diff --git a/ZpcBulletinBoard/Data/ApplicationDbContext.cs b/ZpcBulletinBoard/Data/ApplicationDbContext.cs new file mode 100644 index 0000000..f52c7f3 --- /dev/null +++ b/ZpcBulletinBoard/Data/ApplicationDbContext.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; +using ZpcBulletinBoard.Models; +using ZpcBulletinBoard.Models.Editor; + +namespace ZpcBulletinBoard.Data +{ + public class ApplicationDbContext(DbContextOptions options) + : IdentityDbContext(options) + { + public DbSet Notes { get; set; } + public DbSet BulletinBoards { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + base.OnModelCreating(modelBuilder); + + //Relacije + modelBuilder.Entity() + .HasMany(t => t.Notes) + .WithOne(t => t.BulletinBoard) + .OnDelete(DeleteBehavior.Cascade); + } + } +} diff --git a/ZpcBulletinBoard/Migrations/20240225111417_0.Designer.cs b/ZpcBulletinBoard/Migrations/20240225111417_0.Designer.cs new file mode 100644 index 0000000..291d72d --- /dev/null +++ b/ZpcBulletinBoard/Migrations/20240225111417_0.Designer.cs @@ -0,0 +1,293 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ZpcBulletinBoard.Data; + +#nullable disable + +namespace ZpcBulletinBoard.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240225111417_0")] + partial class _0 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("EveryThing.Models.IdentityApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("EveryThing.Models.IdentityApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("DateCreated") + .HasColumnType("datetime(6)"); + + b.Property("DateValidUntil") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("Surname") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EveryThing.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ZpcBulletinBoard/Migrations/20240225111417_0.cs b/ZpcBulletinBoard/Migrations/20240225111417_0.cs new file mode 100644 index 0000000..23b0c27 --- /dev/null +++ b/ZpcBulletinBoard/Migrations/20240225111417_0.cs @@ -0,0 +1,266 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ZpcBulletinBoard.Migrations +{ + /// + public partial class _0 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterDatabase() + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Description = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Active = table.Column(type: "tinyint(1)", nullable: false), + Name = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + NormalizedName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ConcurrencyStamp = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Surname = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + DateCreated = table.Column(type: "datetime(6)", nullable: false), + DateValidUntil = table.Column(type: "datetime(6)", nullable: false), + Active = table.Column(type: "tinyint(1)", nullable: false), + UserName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + NormalizedUserName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Email = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + NormalizedEmail = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + EmailConfirmed = table.Column(type: "tinyint(1)", nullable: false), + PasswordHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + SecurityStamp = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ConcurrencyStamp = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + PhoneNumber = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + PhoneNumberConfirmed = table.Column(type: "tinyint(1)", nullable: false), + TwoFactorEnabled = table.Column(type: "tinyint(1)", nullable: false), + LockoutEnd = table.Column(type: "datetime(6)", nullable: true), + LockoutEnabled = table.Column(type: "tinyint(1)", nullable: false), + AccessFailedCount = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + RoleId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ClaimValue = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ClaimValue = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ProviderKey = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ProviderDisplayName = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + UserId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + RoleId = table.Column(type: "int", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(type: "int", nullable: false), + LoginProvider = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Name = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Value = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + } + } +} diff --git a/ZpcBulletinBoard/Migrations/20240225160626_1.Designer.cs b/ZpcBulletinBoard/Migrations/20240225160626_1.Designer.cs new file mode 100644 index 0000000..c7583ca --- /dev/null +++ b/ZpcBulletinBoard/Migrations/20240225160626_1.Designer.cs @@ -0,0 +1,359 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ZpcBulletinBoard.Data; + +#nullable disable + +namespace ZpcBulletinBoard.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240225160626_1")] + partial class _1 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("EveryThing.Models.IdentityApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("EveryThing.Models.IdentityApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("DateCreated") + .HasColumnType("datetime(6)"); + + b.Property("DateValidUntil") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("Surname") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.BulletinBoard", b => + { + b.Property("IdBulletinBoard") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Guid") + .HasColumnType("char(36)"); + + b.HasKey("IdBulletinBoard"); + + b.ToTable("BulletinBoards"); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.Note", b => + { + b.Property("IdNote") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("IdBulletinBoard") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Width") + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("int"); + + b.Property("Y") + .HasColumnType("int"); + + b.HasKey("IdNote"); + + b.HasIndex("IdBulletinBoard"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EveryThing.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("EveryThing.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.Note", b => + { + b.HasOne("ZpcBulletinBoard.Models.Editor.BulletinBoard", "BulletinBoard") + .WithMany("Notes") + .HasForeignKey("IdBulletinBoard") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BulletinBoard"); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.BulletinBoard", b => + { + b.Navigation("Notes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ZpcBulletinBoard/Migrations/20240225160626_1.cs b/ZpcBulletinBoard/Migrations/20240225160626_1.cs new file mode 100644 index 0000000..43e97c8 --- /dev/null +++ b/ZpcBulletinBoard/Migrations/20240225160626_1.cs @@ -0,0 +1,73 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ZpcBulletinBoard.Migrations +{ + /// + public partial class _1 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "BulletinBoards", + columns: table => new + { + IdBulletinBoard = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Guid = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci") + }, + constraints: table => + { + table.PrimaryKey("PK_BulletinBoards", x => x.IdBulletinBoard); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateTable( + name: "Notes", + columns: table => new + { + IdNote = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + IdBulletinBoard = table.Column(type: "int", nullable: false), + X = table.Column(type: "int", nullable: false), + Y = table.Column(type: "int", nullable: false), + Width = table.Column(type: "int", nullable: false), + Height = table.Column(type: "int", nullable: false), + Title = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Content = table.Column(type: "longtext", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_Notes", x => x.IdNote); + table.ForeignKey( + name: "FK_Notes_BulletinBoards_IdBulletinBoard", + column: x => x.IdBulletinBoard, + principalTable: "BulletinBoards", + principalColumn: "IdBulletinBoard", + onDelete: ReferentialAction.Cascade); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.CreateIndex( + name: "IX_Notes_IdBulletinBoard", + table: "Notes", + column: "IdBulletinBoard"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Notes"); + + migrationBuilder.DropTable( + name: "BulletinBoards"); + } + } +} diff --git a/ZpcBulletinBoard/Migrations/20240225172529_2.Designer.cs b/ZpcBulletinBoard/Migrations/20240225172529_2.Designer.cs new file mode 100644 index 0000000..0aaf206 --- /dev/null +++ b/ZpcBulletinBoard/Migrations/20240225172529_2.Designer.cs @@ -0,0 +1,366 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ZpcBulletinBoard.Data; + +#nullable disable + +namespace ZpcBulletinBoard.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240225172529_2")] + partial class _2 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.BulletinBoard", b => + { + b.Property("IdBulletinBoard") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Guid") + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Ratio") + .HasColumnType("int"); + + b.HasKey("IdBulletinBoard"); + + b.ToTable("BulletinBoards"); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.Note", b => + { + b.Property("IdNote") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("IdBulletinBoard") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Width") + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("int"); + + b.Property("Y") + .HasColumnType("int"); + + b.HasKey("IdNote"); + + b.HasIndex("IdBulletinBoard"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.IdentityApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.IdentityApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("DateCreated") + .HasColumnType("datetime(6)"); + + b.Property("DateValidUntil") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("Surname") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.Note", b => + { + b.HasOne("ZpcBulletinBoard.Models.Editor.BulletinBoard", "BulletinBoard") + .WithMany("Notes") + .HasForeignKey("IdBulletinBoard") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BulletinBoard"); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.BulletinBoard", b => + { + b.Navigation("Notes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ZpcBulletinBoard/Migrations/20240225172529_2.cs b/ZpcBulletinBoard/Migrations/20240225172529_2.cs new file mode 100644 index 0000000..4131920 --- /dev/null +++ b/ZpcBulletinBoard/Migrations/20240225172529_2.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace ZpcBulletinBoard.Migrations +{ + /// + public partial class _2 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Name", + table: "BulletinBoards", + type: "longtext", + nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "Ratio", + table: "BulletinBoards", + type: "int", + nullable: false, + defaultValue: 0); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Name", + table: "BulletinBoards"); + + migrationBuilder.DropColumn( + name: "Ratio", + table: "BulletinBoards"); + } + } +} diff --git a/ZpcBulletinBoard/Migrations/ApplicationDbContextModelSnapshot.cs b/ZpcBulletinBoard/Migrations/ApplicationDbContextModelSnapshot.cs new file mode 100644 index 0000000..c9536bf --- /dev/null +++ b/ZpcBulletinBoard/Migrations/ApplicationDbContextModelSnapshot.cs @@ -0,0 +1,363 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using ZpcBulletinBoard.Data; + +#nullable disable + +namespace ZpcBulletinBoard.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + partial class ApplicationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.BulletinBoard", b => + { + b.Property("IdBulletinBoard") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Guid") + .HasColumnType("char(36)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Ratio") + .HasColumnType("int"); + + b.HasKey("IdBulletinBoard"); + + b.ToTable("BulletinBoards"); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.Note", b => + { + b.Property("IdNote") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Content") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("IdBulletinBoard") + .HasColumnType("int"); + + b.Property("Title") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Width") + .HasColumnType("int"); + + b.Property("X") + .HasColumnType("int"); + + b.Property("Y") + .HasColumnType("int"); + + b.HasKey("IdNote"); + + b.HasIndex("IdBulletinBoard"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.IdentityApplicationRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Description") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.IdentityApplicationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Active") + .HasColumnType("tinyint(1)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("DateCreated") + .HasColumnType("datetime(6)"); + + b.Property("DateValidUntil") + .HasColumnType("datetime(6)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("Name") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("Surname") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("ZpcBulletinBoard.Models.IdentityApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.Note", b => + { + b.HasOne("ZpcBulletinBoard.Models.Editor.BulletinBoard", "BulletinBoard") + .WithMany("Notes") + .HasForeignKey("IdBulletinBoard") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("BulletinBoard"); + }); + + modelBuilder.Entity("ZpcBulletinBoard.Models.Editor.BulletinBoard", b => + { + b.Navigation("Notes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ZpcBulletinBoard/Models/Editor/BulletinBoard.cs b/ZpcBulletinBoard/Models/Editor/BulletinBoard.cs new file mode 100644 index 0000000..dd54ed6 --- /dev/null +++ b/ZpcBulletinBoard/Models/Editor/BulletinBoard.cs @@ -0,0 +1,37 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace ZpcBulletinBoard.Models.Editor +{ + public class BulletinBoard + { + public enum RatioEnum + { + [Display(Name = "16:9")] + Ratio16To9 = 1, + [Display(Name = "4:3")] + Ratio4To3 = 2 + } + + [Key] + public int IdBulletinBoard { get; set; } + + [Required] + [Index("IX_BulletinBoardUnique", 1, IsUnique = true)] + public Guid Guid { get; set; } + + [Required] + [Display(Name = "Ime")] + public string Name { get; set; } + + + [Required] + [Display(Name = "Razmerje")] + public RatioEnum Ratio { get; set; } + + + // InvoicePart + [InverseProperty("BulletinBoard")] + public virtual ICollection Notes { get; set; } + } +} diff --git a/ZpcBulletinBoard/Models/Editor/Note.cs b/ZpcBulletinBoard/Models/Editor/Note.cs new file mode 100644 index 0000000..d1500a5 --- /dev/null +++ b/ZpcBulletinBoard/Models/Editor/Note.cs @@ -0,0 +1,36 @@ +using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; + +namespace ZpcBulletinBoard.Models.Editor +{ + public class Note + { + [Key] + public int IdNote { get; set; } + + [Required] + [ForeignKey("BulletinBoard")] + public int IdBulletinBoard { get; set; } + + [Required] + public int X { get; set; } + + [Required] + public int Y { get; set; } + + [Required] + public int Width { get; set; } + + [Required] + public int Height { get; set; } + + [Required] + public string Title { get; set; } + + [Required] + public string Content { get; set; } + + // ForeignKey + public BulletinBoard BulletinBoard{ get; set; } + } +} diff --git a/ZpcBulletinBoard/Models/IdentityApplicationRole.cs b/ZpcBulletinBoard/Models/IdentityApplicationRole.cs new file mode 100644 index 0000000..13e7bd0 --- /dev/null +++ b/ZpcBulletinBoard/Models/IdentityApplicationRole.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; + +namespace ZpcBulletinBoard.Models +{ + public class IdentityApplicationRole : IdentityRole + { + [Required] + public string Description { get; set; } + + [Required] + public bool Active { get; set; } + } +} diff --git a/ZpcBulletinBoard/Models/IdentityApplicationUser.cs b/ZpcBulletinBoard/Models/IdentityApplicationUser.cs new file mode 100644 index 0000000..9c00ed2 --- /dev/null +++ b/ZpcBulletinBoard/Models/IdentityApplicationUser.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; + +namespace ZpcBulletinBoard.Models +{ + public class IdentityApplicationUser : IdentityUser + { + [Required] + public string Name { get; set; } + + [Required] + public string Surname { get; set; } + + [Required] + public DateTime DateCreated { get; set; } + + [Required] + public DateTime DateValidUntil { get; set; } + + [Required] + public bool Active { get; set; } + } +} diff --git a/ZpcBulletinBoard/Pages/Boards/AddEdit.cshtml b/ZpcBulletinBoard/Pages/Boards/AddEdit.cshtml new file mode 100644 index 0000000..4692e64 --- /dev/null +++ b/ZpcBulletinBoard/Pages/Boards/AddEdit.cshtml @@ -0,0 +1,62 @@ +@page "{handler?}" +@model ZpcBulletinBoard.Pages.Boards.AddEditModel + +@{ + ViewData["Title"] = "Edit board"; + Layout = "~/Pages/Shared/_Layout.cshtml"; +} + + + +

+ + Nalog / + @if (Model.Board.IdBulletinBoard > 0) + { + Urejanje + } + else + { + Vnos + } + +

+ +
+
+
+
+
+
+ + +
+ + + +
+
+ + + +
+
+ +
+
+
+
+
+
+
+ + +@section Scripts { + @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} + + + + +} \ No newline at end of file diff --git a/ZpcBulletinBoard/Pages/Boards/AddEdit.cshtml.cs b/ZpcBulletinBoard/Pages/Boards/AddEdit.cshtml.cs new file mode 100644 index 0000000..5c0e628 --- /dev/null +++ b/ZpcBulletinBoard/Pages/Boards/AddEdit.cshtml.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.EntityFrameworkCore; +using ZpcBulletinBoard.Data; +using ZpcBulletinBoard.Models; +using ZpcBulletinBoard.Models.Editor; + +namespace ZpcBulletinBoard.Pages.Boards + +{ + //[Authorize(Roles = "Administrator,TransportThingUser,InvoicingUser")] + public class AddEditModel(ApplicationDbContext context) + //public class AddEditModel(ApplicationDbContext context, UserManager userManager) + : PageModel + { + [BindProperty] + public BulletinBoard Board { get; set; } + + public async Task OnGetAsync(Guid? guid) + { + //var user = userManager.GetUserAsync(User).Result; + + if (guid == null) + { + Board = new BulletinBoard + { + Ratio = BulletinBoard.RatioEnum.Ratio16To9, + Guid = Guid.NewGuid(), + Notes = new List() + }; + + return Page(); + } + + var tmpBoard = await context.BulletinBoards.Include(x => x.Notes) + .FirstOrDefaultAsync(m => m.Guid == guid); + + + if (tmpBoard == null) + { + return NotFound(); + } + + Board = tmpBoard; + + return Page(); + } + + public async Task OnPostAsync() + { + System.Diagnostics.Debug.WriteLine("OnPost"); + + //var user = userManager.GetUserAsync(User).Result; + //Board.Notes = new List(); + //if (!ModelState.IsValid) + //{ + // System.Diagnostics.Debug.WriteLine(string.Join(",", ModelState.Where(a => a.Value.Errors.Count > 0) + // .Select(b => $"{b.Key} {b.Value.Errors}"))); + // return Page(); + //} + + if (Board.IdBulletinBoard > 0) + { + context.Attach(Board).State = EntityState.Modified; + + try + { + await context.SaveChangesAsync(); + } + catch (DbUpdateConcurrencyException) + { + if (!BoardExists(Board.IdBulletinBoard)) + { + return NotFound(); + } + else + { + throw; + } + } + + return RedirectToPage("./Index"); + } + + // OrderNumber and OrderYear + + context.BulletinBoards.Add(Board); + await context.SaveChangesAsync(); + + + return RedirectToPage("./Index"); + } + + + private bool BoardExists(int id) + { + return context.BulletinBoards.Any(e => e.IdBulletinBoard == id); + } + } +} diff --git a/ZpcBulletinBoard/Pages/Boards/Index.cshtml b/ZpcBulletinBoard/Pages/Boards/Index.cshtml new file mode 100644 index 0000000..bf3725a --- /dev/null +++ b/ZpcBulletinBoard/Pages/Boards/Index.cshtml @@ -0,0 +1,69 @@ +@page +@model ZpcBulletinBoard.Pages.Boards.IndexModel + +@{ + ViewData["Title"] = "Oglasne deske - Pregled"; + Layout = "~/Pages/Shared/_Layout.cshtml"; +} + +@section Styles { + + + +} + +

+ + + Oglasne deske + / Pregled + +

+ +
+
+ Seznam oglasnih desk +
+ + + + + + + + + + @foreach (var item in Model.Boards) + { + + + + + + } + +
+ @Html.DisplayNameFor(model => model.Boards[0].Name) + + @Html.DisplayNameFor(model => model.Boards[0].Ratio) +
+ @Html.DisplayFor(modelItem => item.Name) + + @Html.DisplayFor(modelItem => item.Ratio) + + +
+ +
+ +@section Scripts { +} \ No newline at end of file diff --git a/ZpcBulletinBoard/Pages/Boards/Index.cshtml.cs b/ZpcBulletinBoard/Pages/Boards/Index.cshtml.cs new file mode 100644 index 0000000..e47449d --- /dev/null +++ b/ZpcBulletinBoard/Pages/Boards/Index.cshtml.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Authorization; +using ZpcBulletinBoard.Data; +using ZpcBulletinBoard.Models.Editor; + +namespace ZpcBulletinBoard.Pages.Boards +{ + //[Authorize] + public class IndexModel(ApplicationDbContext context) : PageModel + { + public IList Boards { get;set; } + + public async Task OnGetAsync() + { + Boards = await context.BulletinBoards.ToListAsync(); + } + } +} diff --git a/ZpcBulletinBoard/Pages/Editor/EditMain.cshtml b/ZpcBulletinBoard/Pages/Editor/EditMain.cshtml new file mode 100644 index 0000000..9797105 --- /dev/null +++ b/ZpcBulletinBoard/Pages/Editor/EditMain.cshtml @@ -0,0 +1,73 @@ +@page +@model EditMainModel +@{ + ViewData["Title"] = "Urejanje"; +} + +@section Styles +{ + + +} + +
+
+
+
+
+ +
+ + +
+ +
+ +
+ +
+ +
+
+
+ +
+
+ + + + +@section Scripts +{ + + + + +} diff --git a/ZpcBulletinBoard/Pages/Editor/EditMain.cshtml.cs b/ZpcBulletinBoard/Pages/Editor/EditMain.cshtml.cs new file mode 100644 index 0000000..f71ed83 --- /dev/null +++ b/ZpcBulletinBoard/Pages/Editor/EditMain.cshtml.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; + +namespace ZpcBulletinBoard.Pages.Editor +{ + public class EditMainModel(ILogger logger) : PageModel + { + private readonly ILogger _logger = logger; + + public void OnGet() + { + + } + } +} diff --git a/ZpcBulletinBoard/Pages/Index.cshtml.cs b/ZpcBulletinBoard/Pages/Index.cshtml.cs index c826ad8..73c8616 100644 --- a/ZpcBulletinBoard/Pages/Index.cshtml.cs +++ b/ZpcBulletinBoard/Pages/Index.cshtml.cs @@ -12,9 +12,9 @@ namespace ZpcBulletinBoard.Pages _logger = logger; } - public void OnGet() + public IActionResult OnGet() { - + return Redirect("~/Editor/EditMain"); } } } diff --git a/ZpcBulletinBoard/Pages/Layouts/Partials/_LayoutSidenav.cshtml b/ZpcBulletinBoard/Pages/Layouts/Partials/_LayoutSidenav.cshtml index c72823b..89d1bba 100644 --- a/ZpcBulletinBoard/Pages/Layouts/Partials/_LayoutSidenav.cshtml +++ b/ZpcBulletinBoard/Pages/Layouts/Partials/_LayoutSidenav.cshtml @@ -15,8 +15,11 @@
\ No newline at end of file diff --git a/ZpcBulletinBoard/Pages/Shared/_Application.cshtml b/ZpcBulletinBoard/Pages/Shared/_Application.cshtml index a4f73ca..ce74525 100644 --- a/ZpcBulletinBoard/Pages/Shared/_Application.cshtml +++ b/ZpcBulletinBoard/Pages/Shared/_Application.cshtml @@ -14,6 +14,8 @@ + + @* *@ @@ -51,7 +53,7 @@ @await Html.PartialAsync("Shared/_ValidationScriptsPartial") - @* *@ + @@ -64,7 +66,7 @@ - + @* *@ diff --git a/ZpcBulletinBoard/Pages/User/Login.cshtml b/ZpcBulletinBoard/Pages/User/Login.cshtml new file mode 100644 index 0000000..bc2a80a --- /dev/null +++ b/ZpcBulletinBoard/Pages/User/Login.cshtml @@ -0,0 +1,76 @@ +@page "{handler?}" +@using Microsoft.AspNetCore.Http.Extensions +@using Microsoft.AspNetCore.Http +@model ZpcBulletinBoard.Pages.User.LoginModel +@{ + ViewData["Title"] = "Prijava"; + Layout = "~/Pages/Shared/_Layout.cshtml"; +} + +@section Styles { + + + +} + +
+
+ +
+
+
+

+ EveryThing +

+
+ Oblačna aplikacija +
+
+
+ +
+
+
+ +
+ +
+ +

Prijava uporabnika

+ +
+
+ + + +
+
+ + + +
+ +
+ +
+ + +
+
+ +
+ Ste pozabili geslo? Kliknite tukaj za ponastavitev +
+
+
+
+ +
+
\ No newline at end of file diff --git a/ZpcBulletinBoard/Pages/User/Login.cshtml.cs b/ZpcBulletinBoard/Pages/User/Login.cshtml.cs new file mode 100644 index 0000000..c8c9602 --- /dev/null +++ b/ZpcBulletinBoard/Pages/User/Login.cshtml.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.Logging; +using ZpcBulletinBoard.Models; + +namespace ZpcBulletinBoard.Pages.User +{ + [IgnoreAntiforgeryToken(Order = 1005)] + [AllowAnonymous] + public class LoginModel : PageModel + { + private readonly UserManager _userManager; + private readonly SignInManager _loginManager; + private readonly RoleManager _roleManager; + //private readonly ILogger _logger; + + public LoginModel(UserManager userManager, SignInManager loginManager, RoleManager roleManager) + { + _userManager = userManager; + _loginManager = loginManager; + _roleManager = roleManager; + //_logger = logger; + } + + [BindProperty] + public InputModel Input { get; set; } + + public IActionResult OnGetToken() + { + return new ObjectResult(new {id = 0}); + } + + public IActionResult OnGet() + { + //IdentityApplicationUser identityApplicationUser = new IdentityApplicationUser + //{ + // Name = "Master", + // Surname = "Admin", + // UserName = "admin", + // NormalizedUserName = "admin", + // Email = "admin@domain.com", + // NormalizedEmail = "admin@domain.com", + // EmailConfirmed = true, + // DateCreated = DateTime.Now, + // DateValidUntil = DateTime.MaxValue, + // PhoneNumber = "123456789", + // PhoneNumberConfirmed = true, + // Active = true, + // IdCompanyFk = 1 + //}; + + //IdentityResult identityResult = _userManager.CreateAsync(identityApplicationUser, "Master#Admin22!").Result; + + //if (identityResult.Succeeded) + //{ + // if (!_roleManager.RoleExistsAsync("TransportThingUser").Result) + // { + // IdentityApplicationRole normalUserRole = new IdentityApplicationRole + // { + // Name = "TransportThingUser", + // Description = "TransporThing uporabniki" + // }; + + // _roleManager.CreateAsync(normalUserRole).Wait(); + // } + + // if (!_roleManager.RoleExistsAsync("ProjecThingUser").Result) + // { + // IdentityApplicationRole normalUserRole = new IdentityApplicationRole + // { + // Name = "ProjecThingUser", + // Description = "ProjecThing uporabniki" + // }; + + // _roleManager.CreateAsync(normalUserRole).Wait(); + // } + + // if (!_roleManager.RoleExistsAsync("Administrator").Result) + // { + // IdentityApplicationRole normalUserRole = new IdentityApplicationRole + // { + // Name = "Administrator", + // Description = "Administratorji" + // }; + + // _roleManager.CreateAsync(normalUserRole).Wait(); + // } + + // _userManager.AddToRoleAsync(identityApplicationUser, "Administrator").Wait(); + + // //return RedirectToPage("/Administration/Users/Index"); + //} + //else + //{ + // ModelState.AddModelError("", string.Join(",", identityResult.Errors.Select(x => x.Description))); + //} + + return Page(); + } + + public async Task OnPostAsync(string returnUrl) + { + returnUrl ??= Url.Content("~/"); + + if (!ModelState.IsValid) + { + return Page(); + } + + if (ModelState.IsValid) + { + var result = await _loginManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberLogin, false); + + if (result.Succeeded) + { + // to get current user info + //var user = await _userManager.FindByNameAsync(Input.UserName); + + //var user = await _userManager.GetUserAsync(User); + //_logger.LogInformation($"Login: {user.Name} {user.Surname} - {user.Company.Title}"); + + return RedirectToPage("/Index"); + } + + if (result.IsLockedOut) + { + //var user = await _userManager.GetUserAsync(User); //TODO: ?? verjetno ne bo delalo + //_logger.LogInformation($"LoginLocked: {user.Name} {user.Surname} - {user.Company.Title}"); + + ModelState.AddModelError("", "Uporabnik je zaklenjen!"); + } + else + { + //_logger.LogInformation($"LoginFail: {Input.UserName}"); + + ModelState.AddModelError("", "Nepravilna prijava!"); + } + } + + return Page(); + } + + //public async Task Login([FromBody] UserLoginRequest user) + //{ + // if (ModelState.IsValid) + // { + // // check if the user with the same email exist + // var existingUser = await _userManager.FindByEmailAsync(user.Email); + + // if (existingUser == null) + // { + // // We dont want to give to much information on why the request has failed for security reasons + // return BadRequest(new RegistrationResponse() + // { + // Result = false, + // Errors = new List(){ + // "Invalid authentication request" + // } + // }); + // } + + // // Now we need to check if the user has inputed the right password + // var isCorrect = await _userManager.CheckPasswordAsync(existingUser, user.Password); + + // if (isCorrect) + // { + // var jwtToken = GenerateJwtToken(existingUser); + + // return Ok(new RegistrationResponse() + // { + // Result = true, + // Token = jwtToken + // }); + // } + // else + // { + // // We dont want to give to much information on why the request has failed for security reasons + // return BadRequest(new RegistrationResponse() + // { + // Result = false, + // Errors = new List(){ + // "Invalid authentication request" + // } + // }); + // } + // } + + // return BadRequest(new RegistrationResponse() + // { + // Result = false, + // Errors = new List(){ + // "Invalid payload" + // } + // }); + //} + + //private string GenerateJwtToken(IdentityUser user) + //{ + // // Now its ime to define the jwt token which will be responsible of creating our tokens + // var jwtTokenHandler = new JwtSecurityTokenHandler(); + + // // We get our secret from the appsettings + // var key = Encoding.ASCII.GetBytes(_jwtConfig.Secret); + + // // we define our token descriptor + // // We need to utilise claims which are properties in our token which gives information about the token + // // which belong to the specific user who it belongs to + // // so it could contain their id, name, email the good part is that these information + // // are generated by our server and identity framework which is valid and trusted + // var tokenDescriptor = new SecurityTokenDescriptor + // { + // Subject = new ClaimsIdentity(new[] + // { + // new Claim("Id", user.Id), + // new Claim(JwtRegisteredClaimNames.Sub, user.Email), + // new Claim(JwtRegisteredClaimNames.Email, user.Email), + // // the JTI is used for our refresh token which we will be convering in the next video + // new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()) + // }), + // // the life span of the token needs to be shorter and utilise refresh token to keep the user signedin + // // but since this is a demo app we can extend it to fit our current need + // Expires = DateTime.UtcNow.AddHours(6), + // // here we are adding the encryption alogorithim information which will be used to decrypt our token + // SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature) + // }; + + // var token = jwtTokenHandler.CreateToken(tokenDescriptor); + + // var jwtToken = jwtTokenHandler.WriteToken(token); + + // return jwtToken; + //} + + //public async Task OnPostTokenAsync(string userName, string password) + //{ + // var user = await _userManager.FindByNameAsync(userName); + + // if (user != null) + // { + // var result = await _loginManager.UserManager.CheckPasswordAsync(user, password); + + // if (result) + // { + // var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("!Appli$cation#2021#!")); + + // var claims = new [] + // { + // new Claim(JwtRegisteredClaimNames.Name, user.Name), + // new Claim(JwtRegisteredClaimNames.Email, user.Email), + // new Claim(JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddDays(1)).ToUnixTimeSeconds()}"), //TODO skrajšaj + // new Claim(JwtRegisteredClaimNames.Iss, "EveryThing"), + // new Claim(JwtRegisteredClaimNames.Aud, "Android"), + // new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), + // new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"), + // new Claim(JwtRegisteredClaimNames.Jti, $"{Guid.NewGuid()}") + // }; + + // var token = new JwtSecurityToken(new JwtHeader(new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256)), new JwtPayload(claims)); + // string jwtToken = new JwtSecurityTokenHandler().WriteToken(token); + + // return new ObjectResult(jwtToken); + // } + // } + + // return BadRequest(); + //} + + public class InputModel + { + [Required(ErrorMessage = "Polje uporabniško ime je obvezno")] + [Display(Name = "Uporabniško ime")] + public string UserName { get; set; } + + [Required(ErrorMessage = "Polje geslo je obvezno")] + [DataType(DataType.Password)] + [Display(Name = "Geslo")] + public string Password { get; set; } + + public bool RememberLogin { get; set; } + } + } +} \ No newline at end of file diff --git a/ZpcBulletinBoard/Pages/User/Logout.cshtml b/ZpcBulletinBoard/Pages/User/Logout.cshtml new file mode 100644 index 0000000..b54e739 --- /dev/null +++ b/ZpcBulletinBoard/Pages/User/Logout.cshtml @@ -0,0 +1,6 @@ +@page +@model ZpcBulletinBoard.Pages.User.LogoutModel +@{ + ViewData["Title"] = "Odjava"; + Layout = "~/Pages/Shared/_Layout.cshtml"; +} diff --git a/ZpcBulletinBoard/Pages/User/Logout.cshtml.cs b/ZpcBulletinBoard/Pages/User/Logout.cshtml.cs new file mode 100644 index 0000000..f7cd3f4 --- /dev/null +++ b/ZpcBulletinBoard/Pages/User/Logout.cshtml.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.Logging; +using ZpcBulletinBoard.Models; + +namespace ZpcBulletinBoard.Pages.User +{ + [Authorize] + public class LogoutModel : PageModel + { + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; + private readonly ILogger _logger; + + public LogoutModel(UserManager userManager, SignInManager signInManager, ILogger logger) + { + _userManager = userManager; + _signInManager = signInManager; + _logger = logger; + } + + public async Task OnGetAsync() + { + var user = await _userManager.GetUserAsync(User); + + await _signInManager.SignOutAsync(); + + //_logger.LogInformation($"Logout: {user.Name} {user.Surname} - {user.Company.Title}"); + + //if (returnUrl != null) + //{ + // return LocalRedirect(returnUrl); + //} + + return RedirectToPage(); + } + + public async Task OnPostAsync(string returnUrl = null) + { + var user = await _userManager.GetUserAsync(User); + + await _signInManager.SignOutAsync(); + + _logger.LogInformation($"Logout: {user.Name} {user.Surname}"); + + if (returnUrl != null) + { + return LocalRedirect(returnUrl); + } + + return RedirectToPage(); + } + } +} diff --git a/ZpcBulletinBoard/Program.cs b/ZpcBulletinBoard/Program.cs index 055f0ae..4e9ade3 100644 --- a/ZpcBulletinBoard/Program.cs +++ b/ZpcBulletinBoard/Program.cs @@ -1,10 +1,44 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.FileProviders; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; +//using Microsoft.AspNetCore.Authentication.JwtBearer; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Connections; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Localization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; +//using Microsoft.IdentityModel.Tokens; +//using EveryThing.Data; +//using Microsoft.AspNetCore.Authentication.Negotiate; +using Microsoft.AspNetCore.HttpOverrides; +using ZpcBulletinBoard.Data; + + var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); +var connectionString = builder.Configuration.GetConnectionString("DataConnection"); +builder.Services.AddDbContext(options => options.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))); + var app = builder.Build(); //app.UseStaticFiles(new StaticFileOptions diff --git a/ZpcBulletinBoard/ZpcBulletinBoard.csproj b/ZpcBulletinBoard/ZpcBulletinBoard.csproj index 43935ff..7bde14d 100644 --- a/ZpcBulletinBoard/ZpcBulletinBoard.csproj +++ b/ZpcBulletinBoard/ZpcBulletinBoard.csproj @@ -16,11 +16,25 @@ + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/ZpcBulletinBoard/appsettings.json b/ZpcBulletinBoard/appsettings.json index 10f68b8..8415bbc 100644 --- a/ZpcBulletinBoard/appsettings.json +++ b/ZpcBulletinBoard/appsettings.json @@ -5,5 +5,8 @@ "Microsoft.AspNetCore": "Warning" } }, - "AllowedHosts": "*" + "AllowedHosts": "*", + "ConnectionStrings": { + "DataConnection": "server=192.168.1.12;user=david;password=*staleker*;database=ZpcBulletinBoard" + } } diff --git a/ZpcBulletinBoard/wwwroot/css/editor/editor-main.css b/ZpcBulletinBoard/wwwroot/css/editor/editor-main.css new file mode 100644 index 0000000..9153b49 --- /dev/null +++ b/ZpcBulletinBoard/wwwroot/css/editor/editor-main.css @@ -0,0 +1,53 @@ +#divCanvas { + padding: 0; + position: relative; + /* border: 2px solid #cccccc; */ +} + +.div-main-body { + padding:0; +} + +.div-main-body > hr { + margin-bottom: 0; +} + +.div-tools { + margin: 5px; + width: 100%; +} + +.div-tools > select { + width: 200px !important; + margin-right: 5px; +} + +.div-tools > button { + margin-left: 5px; +} + +.input-xs, select.input-xs { + height: 27px; + line-height: 30px; + font-size: 0.75rem; + padding-top: 0; + padding-bottom: 0; +} + +.ui-resizable-handle { + width: 20px; + height: 20px; + line-height: 16px; + margin-left: auto; + margin-right: 0; + cursor: nwse-resize; +} + +.div-note { + position: absolute !important; + float: left; +} + +.input-hidden { + display: none; +} diff --git a/ZpcBulletinBoard/wwwroot/js/editor/edit-main.js b/ZpcBulletinBoard/wwwroot/js/editor/edit-main.js new file mode 100644 index 0000000..c1a6caf --- /dev/null +++ b/ZpcBulletinBoard/wwwroot/js/editor/edit-main.js @@ -0,0 +1,91 @@ +$(function () { + loadBoard(); + loadNotes(); +}); + + +const ratio = '16:9' +let divCanvas; +let canWidth; +let canHeight; +let notes = []; + +function loadBoard(){ + let placeholder = $('#divPlaceholder'); + placeholder.empty(); + + let tmpSplit = ratio.split(':'); + canWidth = placeholder.width(); + canHeight = canWidth / (parseFloat(tmpSplit[0]) / parseFloat(tmpSplit[1])); + divCanvas = $(`
`); + placeholder.append(divCanvas); + divCanvas.css({ + 'width': '100%', + 'height': canHeight + 'px', + 'background-color': 'white', + 'padding': '5px' + }); +} + +function loadNotes(){ + let note = new Note(1, divCanvas, 200, 0, 400, 240, '

Naslov


Test

' ); + + notes.push(note); + + let note2 = new Note(2, divCanvas, 0, 0, 400, 240); + notes.push(note2); + + notes.forEach(note => { + note.refresh(); + }); +} + +function openModalEditNote(id){ + $('#inpModalEditNoteIdNote').val(id); + note = getNote(id); + + $('#divModalEditNote').modal('show'); + $('#divModalEditNoteSummernote').summernote('destroy'); + $('#divModalEditNoteSummernote').html(note.content); + $('#divModalEditNoteSummernote').summernote({}); +} + +function saveModalEditNote(){ + let idNote = parseInt($('#inpModalEditNoteIdNote').val()); + note = getNote(idNote); + note.content = $('#divModalEditNoteSummernote').summernote('code'); + note.refresh(); + $('#divModalEditNote').modal('hide'); +} + +function getNote(id){ + let note; + notes.forEach(e => { + if (e.id === id){ + note = e; + } + }); + return note; +} + +function svgTest(){ + var node = document.getElementById('divCanvas'); + + htmlToImage.toSvg(node) + .then(function (dataUrl) { + var link = document.createElement('a'); + link.href = dataUrl; + link.download = 'Download.jpg'; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + return; + var img = new Image(); + img.src = dataUrl; + document.body.appendChild(img); + }) + .catch(function (error) { + console.error('oops, something went wrong!', error); + }); +} + diff --git a/ZpcBulletinBoard/wwwroot/js/editor/note.js b/ZpcBulletinBoard/wwwroot/js/editor/note.js new file mode 100644 index 0000000..01b169d --- /dev/null +++ b/ZpcBulletinBoard/wwwroot/js/editor/note.js @@ -0,0 +1,60 @@ +class Note{ + constructor(id, divCanvas, x, y, width, height, content) { + this.id = id; + this.divCanvas = divCanvas; + this.x = x; + this.y = y; + this.width = width; + this.height = height; + this.element = null; + this.content = content; + } + + refresh(){ + if (this.element !== null){ + this.element.remove(); + } + + this.element = $(` +
+
+ ${this.content} +
+
`); + this.element.draggable({ + containment: "parent", + stop: function( event, ui ) { + let id = parseInt($(this).attr('data-id')); + let note = getNote(id); + note.x = ui.position.left; + note.y = ui.position.top; + console.log(ui.position); + } + }); + this.element.resizable({ + handles: 'se', + autoHide: true, + minHeight: 240, + minWidth: 300, + }); + this.element.css({ + 'width': this.width + 'px', + 'height': this.height + 'px', + 'position': 'relative' + }); + this.element.on( "dblclick", function() { + openModalEditNote(parseInt($(this).attr('data-id'))); + }); + + this.divCanvas.append(this.element); + this.setPosition(); + } + + setPosition(){ + this.element.css({ + 'left': this.x + 'px', + 'top': this.y + 'px' + }); + } +} + diff --git a/ZpcBulletinBoard/wwwroot/lib/html-to-image/dist/html-to-image.js b/ZpcBulletinBoard/wwwroot/lib/html-to-image/dist/html-to-image.js new file mode 100644 index 0000000..59db326 --- /dev/null +++ b/ZpcBulletinBoard/wwwroot/lib/html-to-image/dist/html-to-image.js @@ -0,0 +1,2 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).htmlToImage={})}(this,(function(t){"use strict";function e(t,e,n,r){return new(n||(n=Promise))((function(i,o){function u(t){try{a(r.next(t))}catch(t){o(t)}}function c(t){try{a(r.throw(t))}catch(t){o(t)}}function a(t){var e;t.done?i(t.value):(e=t.value,e instanceof n?e:new n((function(t){t(e)}))).then(u,c)}a((r=r.apply(t,e||[])).next())}))}function n(t,e){var n,r,i,o,u={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function c(c){return function(a){return function(c){if(n)throw new TypeError("Generator is already executing.");for(;o&&(o=0,c[0]&&(u=0)),u;)try{if(n=1,r&&(i=2&c[0]?r.return:c[0]?r.throw||((i=r.return)&&i.call(r),0):r.next)&&!(i=i.call(r,c[1])).done)return i;switch(r=0,i&&(c=[2&c[0],i.value]),c[0]){case 0:case 1:i=c;break;case 4:return u.label++,{value:c[1],done:!1};case 5:u.label++,r=c[1],c=[0];continue;case 7:c=u.ops.pop(),u.trys.pop();continue;default:if(!(i=u.trys,(i=i.length>0&&i[i.length-1])||6!==c[0]&&2!==c[0])){u=0;continue}if(3===c[0]&&(!i||c[1]>i[0]&&c[1]a||t.height>a)&&(t.width>a&&t.height>a?t.width>t.height?(t.height*=a/t.width,t.width=a):(t.width*=a/t.height,t.height=a):t.width>a?(t.height*=a/t.width,t.width=a):(t.width*=a/t.height,t.height=a))}(s),s.style.width="".concat(d),s.style.height="".concat(v),r.backgroundColor&&(f.fillStyle=r.backgroundColor,f.fillRect(0,0,s.width,s.height)),f.drawImage(u,0,0,s.width,s.height),[2,s]}}))}))}t.getFontEmbedCSS=function(t,r){return void 0===r&&(r={}),e(this,void 0,void 0,(function(){return n(this,(function(e){return[2,J(t,r)]}))}))},t.toBlob=function(t,r){return void 0===r&&(r={}),e(this,void 0,void 0,(function(){return n(this,(function(e){switch(e.label){case 0:return[4,K(t,r)];case 1:return[4,s(e.sent())];case 2:return[2,e.sent()]}}))}))},t.toCanvas=K,t.toJpeg=function(t,r){return void 0===r&&(r={}),e(this,void 0,void 0,(function(){return n(this,(function(e){switch(e.label){case 0:return[4,K(t,r)];case 1:return[2,e.sent().toDataURL("image/jpeg",r.quality||1)]}}))}))},t.toPixelData=function(t,r){return void 0===r&&(r={}),e(this,void 0,void 0,(function(){var e,i,o,u;return n(this,(function(n){switch(n.label){case 0:return e=c(t,r),i=e.width,o=e.height,[4,K(t,r)];case 1:return u=n.sent(),[2,u.getContext("2d").getImageData(0,0,i,o).data]}}))}))},t.toPng=function(t,r){return void 0===r&&(r={}),e(this,void 0,void 0,(function(){return n(this,(function(e){switch(e.label){case 0:return[4,K(t,r)];case 1:return[2,e.sent().toDataURL()]}}))}))},t.toSvg=X})); +//# sourceMappingURL=html-to-image.js.map diff --git a/ZpcBulletinBoard/wwwroot/lib/html-to-image/dist/html-to-image.js.map b/ZpcBulletinBoard/wwwroot/lib/html-to-image/dist/html-to-image.js.map new file mode 100644 index 0000000..8632e21 --- /dev/null +++ b/ZpcBulletinBoard/wwwroot/lib/html-to-image/dist/html-to-image.js.map @@ -0,0 +1 @@ +{"version":3,"file":"html-to-image.js","sources":["../node_modules/.pnpm/@rollup+plugin-typescript@11.0.0_rhlcksimi4ycfgwevqw3afkobq/node_modules/tslib/tslib.es6.js","../src/util.ts","../src/clone-pseudos.ts","../src/mimes.ts","../src/dataurl.ts","../src/clone-node.ts","../src/embed-resources.ts","../src/embed-images.ts","../src/embed-webfonts.ts","../src/index.ts","../src/apply-style.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {\r\n function accept(f) { if (f !== void 0 && typeof f !== \"function\") throw new TypeError(\"Function expected\"); return f; }\r\n var kind = contextIn.kind, key = kind === \"getter\" ? \"get\" : kind === \"setter\" ? \"set\" : \"value\";\r\n var target = !descriptorIn && ctor ? contextIn[\"static\"] ? ctor : ctor.prototype : null;\r\n var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});\r\n var _, done = false;\r\n for (var i = decorators.length - 1; i >= 0; i--) {\r\n var context = {};\r\n for (var p in contextIn) context[p] = p === \"access\" ? {} : contextIn[p];\r\n for (var p in contextIn.access) context.access[p] = contextIn.access[p];\r\n context.addInitializer = function (f) { if (done) throw new TypeError(\"Cannot add initializers after decoration has completed\"); extraInitializers.push(accept(f || null)); };\r\n var result = (0, decorators[i])(kind === \"accessor\" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);\r\n if (kind === \"accessor\") {\r\n if (result === void 0) continue;\r\n if (result === null || typeof result !== \"object\") throw new TypeError(\"Object expected\");\r\n if (_ = accept(result.get)) descriptor.get = _;\r\n if (_ = accept(result.set)) descriptor.set = _;\r\n if (_ = accept(result.init)) initializers.push(_);\r\n }\r\n else if (_ = accept(result)) {\r\n if (kind === \"field\") initializers.push(_);\r\n else descriptor[key] = _;\r\n }\r\n }\r\n if (target) Object.defineProperty(target, contextIn.name, descriptor);\r\n done = true;\r\n};\r\n\r\nexport function __runInitializers(thisArg, initializers, value) {\r\n var useValue = arguments.length > 2;\r\n for (var i = 0; i < initializers.length; i++) {\r\n value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);\r\n }\r\n return useValue ? value : void 0;\r\n};\r\n\r\nexport function __propKey(x) {\r\n return typeof x === \"symbol\" ? x : \"\".concat(x);\r\n};\r\n\r\nexport function __setFunctionName(f, name, prefix) {\r\n if (typeof name === \"symbol\") name = name.description ? \"[\".concat(name.description, \"]\") : \"\";\r\n return Object.defineProperty(f, \"name\", { configurable: true, value: prefix ? \"\".concat(prefix, \" \", name) : name });\r\n};\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (g && (g = 0, op[0] && (_ = 0)), _) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n",null,null,null,null,null,null,null,null,null,null],"names":["__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","__generator","body","f","y","t","g","_","label","sent","trys","ops","verb","throw","return","Symbol","iterator","this","n","v","op","TypeError","call","pop","length","push","counter","uuid","concat","Math","random","pow","toString","slice","toArray","arrayLike","arr","i","l","px","node","styleProperty","val","ownerDocument","defaultView","window","getComputedStyle","getPropertyValue","parseFloat","replace","getImageSize","targetNode","options","leftBorder","rightBorder","width","clientWidth","height","topBorder","bottomBorder","clientHeight","getNodeHeight","canvasDimensionLimit","canvasToBlob","canvas","toBlob","type","quality","binaryString","atob","toDataURL","undefined","split","len","binaryArray","Uint8Array","charCodeAt","Blob","createImage","url","img","Image","decode","onload","onerror","crossOrigin","decoding","src","svgToDataURL","svg","XMLSerializer","serializeToString","encodeURIComponent","html","nodeToDataURL","xmlns","document","createElementNS","foreignObject","setAttribute","appendChild","isInstanceOfElement","instance","nodePrototype","Object","getPrototypeOf","constructor","name","getPseudoElementStyle","className","pseudo","style","selector","cssText","content","formatCSSText","map","priority","getPropertyPriority","join","formatCSSProperties","createTextNode","clonePseudoElement","nativeNode","clonedNode","err","styleElement","createElement","WOFF","JPEG","mimes","woff","woff2","ttf","eot","png","jpg","jpeg","gif","tiff","webp","getMimeType","extension","match","exec","getExtension","toLowerCase","isDataUrl","search","makeDataUrl","mimeType","fetchAsDataURL","init","process","fetch","res","_a","status","Error","blob","reader","FileReader","onloadend","error","readAsDataURL","cache","resourceToDataURL","resourceUrl","contentType","cacheKey","includeQueryParams","key","test","getCacheKey","cacheBust","Date","getTime","fetchRequestInit","headers","get","dataURL","getContentFromDataUrl","imagePlaceholder","msg","error_1","message","console","warn","cloneCanvasElement","cloneNode","cloneVideoElement","video","currentSrc","ctx","getContext","drawImage","poster","cloneIFrameElement","iframe","contentDocument","_c","decorate","Element","targetStyle","sourceStyle","transformOrigin","forEach","endsWith","reducedFont","floor","substring","HTMLIFrameElement","getAttribute","setProperty","cloneCSSStyle","clonePseudoElements","HTMLTextAreaElement","innerHTML","HTMLInputElement","cloneInputValue","HTMLSelectElement","clonedSelect","selectedOption","Array","from","children","find","child","cloneSelectValue","isRoot","filter","HTMLCanvasElement","HTMLVideoElement","cloneSingleNode","tagName","toUpperCase","assignedNodes","childNodes","shadowRoot","_b","reduce","deferred","clonedChild","cloneChildren","clone","uses","querySelectorAll","processedDefs","use","id","exist","querySelector","definition","nodes","values","ns","position","overflow","display","defs","ensureSVGSymbols","URL_REGEX","URL_WITH_FORMAT_REGEX","FONT_SRC_REGEX","embed","resourceURL","baseURL","getContentFromUrl","resolvedURL","baseUrl","location","protocol","doc","implementation","createHTMLDocument","base","a","head","href","resolveUrl","escaped","RegExp","shouldEmbed","embedResources","filteredCSSText","str","preferredFontFormat","format","filterPreferredFontFormat","urls","raw","quotation","parseURLs","css","embedProp","propName","propValue","cssString","embedBackground","embedImageNode","isImageElement","HTMLImageElement","SVGImageElement","baseVal","image","loading","srcset","embedChildren","deferreds","embedImages","all","cssFetchCache","fetchCSS","text","embedFonts","data","regexUrl","fontLocs","loadFonts","loc","_this","startsWith","URL","parseCSS","source","keyframesRegex","matches","importRegex","unifiedRegex","lastIndex","getCSSRules","styleSheets","ret","sheet","cssRules","item","index","CSSRule","IMPORT_RULE","importIndex_1","metadata","rule","insertRule","catch","inline_1","getWebFontRules","FONT_FACE_RULE","parseWebFontRules","getWebFontCSS","rules","parentStyleSheet","embedWebFonts","fontEmbedCSS","skipFonts","styleNode","sytleContent","firstChild","insertBefore","toSvg","backgroundColor","manual","keys","applyStyle","toCanvas","context","ratio","pixelRatio","FINAL_PROCESS","env","devicePixelRatio","parseInt","Number","isNaN","getPixelRatio","canvasWidth","canvasHeight","skipAutoScale","checkCanvasDimensions","fillStyle","fillRect","getImageData"],"mappings":"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"} \ No newline at end of file diff --git a/ZpcBulletinBoard/wwwroot/lib/jquery-ui/dist/jquery-ui.js b/ZpcBulletinBoard/wwwroot/lib/jquery-ui/dist/jquery-ui.js new file mode 100644 index 0000000..1a613bf --- /dev/null +++ b/ZpcBulletinBoard/wwwroot/lib/jquery-ui/dist/jquery-ui.js @@ -0,0 +1,19062 @@ +/*! jQuery UI - v1.13.2 - 2022-07-14 +* http://jqueryui.com +* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-patch.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +( function( factory ) { + "use strict"; + + if ( typeof define === "function" && define.amd ) { + + // AMD. Register as an anonymous module. + define( [ "jquery" ], factory ); + } else { + + // Browser globals + factory( jQuery ); + } +} )( function( $ ) { +"use strict"; + +$.ui = $.ui || {}; + +var version = $.ui.version = "1.13.2"; + + +/*! + * jQuery UI Widget 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Widget +//>>group: Core +//>>description: Provides a factory for creating stateful widgets with a common API. +//>>docs: http://api.jqueryui.com/jQuery.widget/ +//>>demos: http://jqueryui.com/widget/ + + +var widgetUuid = 0; +var widgetHasOwnProperty = Array.prototype.hasOwnProperty; +var widgetSlice = Array.prototype.slice; + +$.cleanData = ( function( orig ) { + return function( elems ) { + var events, elem, i; + for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) { + + // Only trigger remove when necessary to save time + events = $._data( elem, "events" ); + if ( events && events.remove ) { + $( elem ).triggerHandler( "remove" ); + } + } + orig( elems ); + }; +} )( $.cleanData ); + +$.widget = function( name, base, prototype ) { + var existingConstructor, constructor, basePrototype; + + // ProxiedPrototype allows the provided prototype to remain unmodified + // so that it can be used as a mixin for multiple widgets (#8876) + var proxiedPrototype = {}; + + var namespace = name.split( "." )[ 0 ]; + name = name.split( "." )[ 1 ]; + var fullName = namespace + "-" + name; + + if ( !prototype ) { + prototype = base; + base = $.Widget; + } + + if ( Array.isArray( prototype ) ) { + prototype = $.extend.apply( null, [ {} ].concat( prototype ) ); + } + + // Create selector for plugin + $.expr.pseudos[ fullName.toLowerCase() ] = function( elem ) { + return !!$.data( elem, fullName ); + }; + + $[ namespace ] = $[ namespace ] || {}; + existingConstructor = $[ namespace ][ name ]; + constructor = $[ namespace ][ name ] = function( options, element ) { + + // Allow instantiation without "new" keyword + if ( !this || !this._createWidget ) { + return new constructor( options, element ); + } + + // Allow instantiation without initializing for simple inheritance + // must use "new" keyword (the code above always passes args) + if ( arguments.length ) { + this._createWidget( options, element ); + } + }; + + // Extend with the existing constructor to carry over any static properties + $.extend( constructor, existingConstructor, { + version: prototype.version, + + // Copy the object used to create the prototype in case we need to + // redefine the widget later + _proto: $.extend( {}, prototype ), + + // Track widgets that inherit from this widget in case this widget is + // redefined after a widget inherits from it + _childConstructors: [] + } ); + + basePrototype = new base(); + + // We need to make the options hash a property directly on the new instance + // otherwise we'll modify the options hash on the prototype that we're + // inheriting from + basePrototype.options = $.widget.extend( {}, basePrototype.options ); + $.each( prototype, function( prop, value ) { + if ( typeof value !== "function" ) { + proxiedPrototype[ prop ] = value; + return; + } + proxiedPrototype[ prop ] = ( function() { + function _super() { + return base.prototype[ prop ].apply( this, arguments ); + } + + function _superApply( args ) { + return base.prototype[ prop ].apply( this, args ); + } + + return function() { + var __super = this._super; + var __superApply = this._superApply; + var returnValue; + + this._super = _super; + this._superApply = _superApply; + + returnValue = value.apply( this, arguments ); + + this._super = __super; + this._superApply = __superApply; + + return returnValue; + }; + } )(); + } ); + constructor.prototype = $.widget.extend( basePrototype, { + + // TODO: remove support for widgetEventPrefix + // always use the name + a colon as the prefix, e.g., draggable:start + // don't prefix for widgets that aren't DOM-based + widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name + }, proxiedPrototype, { + constructor: constructor, + namespace: namespace, + widgetName: name, + widgetFullName: fullName + } ); + + // If this widget is being redefined then we need to find all widgets that + // are inheriting from it and redefine all of them so that they inherit from + // the new version of this widget. We're essentially trying to replace one + // level in the prototype chain. + if ( existingConstructor ) { + $.each( existingConstructor._childConstructors, function( i, child ) { + var childPrototype = child.prototype; + + // Redefine the child widget using the same prototype that was + // originally used, but inherit from the new version of the base + $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, + child._proto ); + } ); + + // Remove the list of existing child constructors from the old constructor + // so the old child constructors can be garbage collected + delete existingConstructor._childConstructors; + } else { + base._childConstructors.push( constructor ); + } + + $.widget.bridge( name, constructor ); + + return constructor; +}; + +$.widget.extend = function( target ) { + var input = widgetSlice.call( arguments, 1 ); + var inputIndex = 0; + var inputLength = input.length; + var key; + var value; + + for ( ; inputIndex < inputLength; inputIndex++ ) { + for ( key in input[ inputIndex ] ) { + value = input[ inputIndex ][ key ]; + if ( widgetHasOwnProperty.call( input[ inputIndex ], key ) && value !== undefined ) { + + // Clone objects + if ( $.isPlainObject( value ) ) { + target[ key ] = $.isPlainObject( target[ key ] ) ? + $.widget.extend( {}, target[ key ], value ) : + + // Don't extend strings, arrays, etc. with objects + $.widget.extend( {}, value ); + + // Copy everything else by reference + } else { + target[ key ] = value; + } + } + } + } + return target; +}; + +$.widget.bridge = function( name, object ) { + var fullName = object.prototype.widgetFullName || name; + $.fn[ name ] = function( options ) { + var isMethodCall = typeof options === "string"; + var args = widgetSlice.call( arguments, 1 ); + var returnValue = this; + + if ( isMethodCall ) { + + // If this is an empty collection, we need to have the instance method + // return undefined instead of the jQuery instance + if ( !this.length && options === "instance" ) { + returnValue = undefined; + } else { + this.each( function() { + var methodValue; + var instance = $.data( this, fullName ); + + if ( options === "instance" ) { + returnValue = instance; + return false; + } + + if ( !instance ) { + return $.error( "cannot call methods on " + name + + " prior to initialization; " + + "attempted to call method '" + options + "'" ); + } + + if ( typeof instance[ options ] !== "function" || + options.charAt( 0 ) === "_" ) { + return $.error( "no such method '" + options + "' for " + name + + " widget instance" ); + } + + methodValue = instance[ options ].apply( instance, args ); + + if ( methodValue !== instance && methodValue !== undefined ) { + returnValue = methodValue && methodValue.jquery ? + returnValue.pushStack( methodValue.get() ) : + methodValue; + return false; + } + } ); + } + } else { + + // Allow multiple hashes to be passed on init + if ( args.length ) { + options = $.widget.extend.apply( null, [ options ].concat( args ) ); + } + + this.each( function() { + var instance = $.data( this, fullName ); + if ( instance ) { + instance.option( options || {} ); + if ( instance._init ) { + instance._init(); + } + } else { + $.data( this, fullName, new object( options, this ) ); + } + } ); + } + + return returnValue; + }; +}; + +$.Widget = function( /* options, element */ ) {}; +$.Widget._childConstructors = []; + +$.Widget.prototype = { + widgetName: "widget", + widgetEventPrefix: "", + defaultElement: "
", + + options: { + classes: {}, + disabled: false, + + // Callbacks + create: null + }, + + _createWidget: function( options, element ) { + element = $( element || this.defaultElement || this )[ 0 ]; + this.element = $( element ); + this.uuid = widgetUuid++; + this.eventNamespace = "." + this.widgetName + this.uuid; + + this.bindings = $(); + this.hoverable = $(); + this.focusable = $(); + this.classesElementLookup = {}; + + if ( element !== this ) { + $.data( element, this.widgetFullName, this ); + this._on( true, this.element, { + remove: function( event ) { + if ( event.target === element ) { + this.destroy(); + } + } + } ); + this.document = $( element.style ? + + // Element within the document + element.ownerDocument : + + // Element is window or document + element.document || element ); + this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow ); + } + + this.options = $.widget.extend( {}, + this.options, + this._getCreateOptions(), + options ); + + this._create(); + + if ( this.options.disabled ) { + this._setOptionDisabled( this.options.disabled ); + } + + this._trigger( "create", null, this._getCreateEventData() ); + this._init(); + }, + + _getCreateOptions: function() { + return {}; + }, + + _getCreateEventData: $.noop, + + _create: $.noop, + + _init: $.noop, + + destroy: function() { + var that = this; + + this._destroy(); + $.each( this.classesElementLookup, function( key, value ) { + that._removeClass( value, key ); + } ); + + // We can probably remove the unbind calls in 2.0 + // all event bindings should go through this._on() + this.element + .off( this.eventNamespace ) + .removeData( this.widgetFullName ); + this.widget() + .off( this.eventNamespace ) + .removeAttr( "aria-disabled" ); + + // Clean up events and states + this.bindings.off( this.eventNamespace ); + }, + + _destroy: $.noop, + + widget: function() { + return this.element; + }, + + option: function( key, value ) { + var options = key; + var parts; + var curOption; + var i; + + if ( arguments.length === 0 ) { + + // Don't return a reference to the internal hash + return $.widget.extend( {}, this.options ); + } + + if ( typeof key === "string" ) { + + // Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } + options = {}; + parts = key.split( "." ); + key = parts.shift(); + if ( parts.length ) { + curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); + for ( i = 0; i < parts.length - 1; i++ ) { + curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; + curOption = curOption[ parts[ i ] ]; + } + key = parts.pop(); + if ( arguments.length === 1 ) { + return curOption[ key ] === undefined ? null : curOption[ key ]; + } + curOption[ key ] = value; + } else { + if ( arguments.length === 1 ) { + return this.options[ key ] === undefined ? null : this.options[ key ]; + } + options[ key ] = value; + } + } + + this._setOptions( options ); + + return this; + }, + + _setOptions: function( options ) { + var key; + + for ( key in options ) { + this._setOption( key, options[ key ] ); + } + + return this; + }, + + _setOption: function( key, value ) { + if ( key === "classes" ) { + this._setOptionClasses( value ); + } + + this.options[ key ] = value; + + if ( key === "disabled" ) { + this._setOptionDisabled( value ); + } + + return this; + }, + + _setOptionClasses: function( value ) { + var classKey, elements, currentElements; + + for ( classKey in value ) { + currentElements = this.classesElementLookup[ classKey ]; + if ( value[ classKey ] === this.options.classes[ classKey ] || + !currentElements || + !currentElements.length ) { + continue; + } + + // We are doing this to create a new jQuery object because the _removeClass() call + // on the next line is going to destroy the reference to the current elements being + // tracked. We need to save a copy of this collection so that we can add the new classes + // below. + elements = $( currentElements.get() ); + this._removeClass( currentElements, classKey ); + + // We don't use _addClass() here, because that uses this.options.classes + // for generating the string of classes. We want to use the value passed in from + // _setOption(), this is the new value of the classes option which was passed to + // _setOption(). We pass this value directly to _classes(). + elements.addClass( this._classes( { + element: elements, + keys: classKey, + classes: value, + add: true + } ) ); + } + }, + + _setOptionDisabled: function( value ) { + this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value ); + + // If the widget is becoming disabled, then nothing is interactive + if ( value ) { + this._removeClass( this.hoverable, null, "ui-state-hover" ); + this._removeClass( this.focusable, null, "ui-state-focus" ); + } + }, + + enable: function() { + return this._setOptions( { disabled: false } ); + }, + + disable: function() { + return this._setOptions( { disabled: true } ); + }, + + _classes: function( options ) { + var full = []; + var that = this; + + options = $.extend( { + element: this.element, + classes: this.options.classes || {} + }, options ); + + function bindRemoveEvent() { + var nodesToBind = []; + + options.element.each( function( _, element ) { + var isTracked = $.map( that.classesElementLookup, function( elements ) { + return elements; + } ) + .some( function( elements ) { + return elements.is( element ); + } ); + + if ( !isTracked ) { + nodesToBind.push( element ); + } + } ); + + that._on( $( nodesToBind ), { + remove: "_untrackClassesElement" + } ); + } + + function processClassString( classes, checkOption ) { + var current, i; + for ( i = 0; i < classes.length; i++ ) { + current = that.classesElementLookup[ classes[ i ] ] || $(); + if ( options.add ) { + bindRemoveEvent(); + current = $( $.uniqueSort( current.get().concat( options.element.get() ) ) ); + } else { + current = $( current.not( options.element ).get() ); + } + that.classesElementLookup[ classes[ i ] ] = current; + full.push( classes[ i ] ); + if ( checkOption && options.classes[ classes[ i ] ] ) { + full.push( options.classes[ classes[ i ] ] ); + } + } + } + + if ( options.keys ) { + processClassString( options.keys.match( /\S+/g ) || [], true ); + } + if ( options.extra ) { + processClassString( options.extra.match( /\S+/g ) || [] ); + } + + return full.join( " " ); + }, + + _untrackClassesElement: function( event ) { + var that = this; + $.each( that.classesElementLookup, function( key, value ) { + if ( $.inArray( event.target, value ) !== -1 ) { + that.classesElementLookup[ key ] = $( value.not( event.target ).get() ); + } + } ); + + this._off( $( event.target ) ); + }, + + _removeClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, false ); + }, + + _addClass: function( element, keys, extra ) { + return this._toggleClass( element, keys, extra, true ); + }, + + _toggleClass: function( element, keys, extra, add ) { + add = ( typeof add === "boolean" ) ? add : extra; + var shift = ( typeof element === "string" || element === null ), + options = { + extra: shift ? keys : extra, + keys: shift ? element : keys, + element: shift ? this.element : element, + add: add + }; + options.element.toggleClass( this._classes( options ), add ); + return this; + }, + + _on: function( suppressDisabledCheck, element, handlers ) { + var delegateElement; + var instance = this; + + // No suppressDisabledCheck flag, shuffle arguments + if ( typeof suppressDisabledCheck !== "boolean" ) { + handlers = element; + element = suppressDisabledCheck; + suppressDisabledCheck = false; + } + + // No element argument, shuffle and use this.element + if ( !handlers ) { + handlers = element; + element = this.element; + delegateElement = this.widget(); + } else { + element = delegateElement = $( element ); + this.bindings = this.bindings.add( element ); + } + + $.each( handlers, function( event, handler ) { + function handlerProxy() { + + // Allow widgets to customize the disabled handling + // - disabled as an array instead of boolean + // - disabled class as method for disabling individual parts + if ( !suppressDisabledCheck && + ( instance.options.disabled === true || + $( this ).hasClass( "ui-state-disabled" ) ) ) { + return; + } + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + + // Copy the guid so direct unbinding works + if ( typeof handler !== "string" ) { + handlerProxy.guid = handler.guid = + handler.guid || handlerProxy.guid || $.guid++; + } + + var match = event.match( /^([\w:-]*)\s*(.*)$/ ); + var eventName = match[ 1 ] + instance.eventNamespace; + var selector = match[ 2 ]; + + if ( selector ) { + delegateElement.on( eventName, selector, handlerProxy ); + } else { + element.on( eventName, handlerProxy ); + } + } ); + }, + + _off: function( element, eventName ) { + eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) + + this.eventNamespace; + element.off( eventName ); + + // Clear the stack to avoid memory leaks (#10056) + this.bindings = $( this.bindings.not( element ).get() ); + this.focusable = $( this.focusable.not( element ).get() ); + this.hoverable = $( this.hoverable.not( element ).get() ); + }, + + _delay: function( handler, delay ) { + function handlerProxy() { + return ( typeof handler === "string" ? instance[ handler ] : handler ) + .apply( instance, arguments ); + } + var instance = this; + return setTimeout( handlerProxy, delay || 0 ); + }, + + _hoverable: function( element ) { + this.hoverable = this.hoverable.add( element ); + this._on( element, { + mouseenter: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-hover" ); + }, + mouseleave: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-hover" ); + } + } ); + }, + + _focusable: function( element ) { + this.focusable = this.focusable.add( element ); + this._on( element, { + focusin: function( event ) { + this._addClass( $( event.currentTarget ), null, "ui-state-focus" ); + }, + focusout: function( event ) { + this._removeClass( $( event.currentTarget ), null, "ui-state-focus" ); + } + } ); + }, + + _trigger: function( type, event, data ) { + var prop, orig; + var callback = this.options[ type ]; + + data = data || {}; + event = $.Event( event ); + event.type = ( type === this.widgetEventPrefix ? + type : + this.widgetEventPrefix + type ).toLowerCase(); + + // The original event may come from any element + // so we need to reset the target on the new event + event.target = this.element[ 0 ]; + + // Copy original event properties over to the new event + orig = event.originalEvent; + if ( orig ) { + for ( prop in orig ) { + if ( !( prop in event ) ) { + event[ prop ] = orig[ prop ]; + } + } + } + + this.element.trigger( event, data ); + return !( typeof callback === "function" && + callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false || + event.isDefaultPrevented() ); + } +}; + +$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { + $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { + if ( typeof options === "string" ) { + options = { effect: options }; + } + + var hasOptions; + var effectName = !options ? + method : + options === true || typeof options === "number" ? + defaultEffect : + options.effect || defaultEffect; + + options = options || {}; + if ( typeof options === "number" ) { + options = { duration: options }; + } else if ( options === true ) { + options = {}; + } + + hasOptions = !$.isEmptyObject( options ); + options.complete = callback; + + if ( options.delay ) { + element.delay( options.delay ); + } + + if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { + element[ method ]( options ); + } else if ( effectName !== method && element[ effectName ] ) { + element[ effectName ]( options.duration, options.easing, callback ); + } else { + element.queue( function( next ) { + $( this )[ method ](); + if ( callback ) { + callback.call( element[ 0 ] ); + } + next(); + } ); + } + }; +} ); + +var widget = $.widget; + + +/*! + * jQuery UI Position 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/position/ + */ + +//>>label: Position +//>>group: Core +//>>description: Positions elements relative to other elements. +//>>docs: http://api.jqueryui.com/position/ +//>>demos: http://jqueryui.com/position/ + + +( function() { +var cachedScrollbarWidth, + max = Math.max, + abs = Math.abs, + rhorizontal = /left|center|right/, + rvertical = /top|center|bottom/, + roffset = /[\+\-]\d+(\.[\d]+)?%?/, + rposition = /^\w+/, + rpercent = /%$/, + _position = $.fn.position; + +function getOffsets( offsets, width, height ) { + return [ + parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), + parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) + ]; +} + +function parseCss( element, property ) { + return parseInt( $.css( element, property ), 10 ) || 0; +} + +function isWindow( obj ) { + return obj != null && obj === obj.window; +} + +function getDimensions( elem ) { + var raw = elem[ 0 ]; + if ( raw.nodeType === 9 ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: 0, left: 0 } + }; + } + if ( isWindow( raw ) ) { + return { + width: elem.width(), + height: elem.height(), + offset: { top: elem.scrollTop(), left: elem.scrollLeft() } + }; + } + if ( raw.preventDefault ) { + return { + width: 0, + height: 0, + offset: { top: raw.pageY, left: raw.pageX } + }; + } + return { + width: elem.outerWidth(), + height: elem.outerHeight(), + offset: elem.offset() + }; +} + +$.position = { + scrollbarWidth: function() { + if ( cachedScrollbarWidth !== undefined ) { + return cachedScrollbarWidth; + } + var w1, w2, + div = $( "
" + + "
" ), + innerDiv = div.children()[ 0 ]; + + $( "body" ).append( div ); + w1 = innerDiv.offsetWidth; + div.css( "overflow", "scroll" ); + + w2 = innerDiv.offsetWidth; + + if ( w1 === w2 ) { + w2 = div[ 0 ].clientWidth; + } + + div.remove(); + + return ( cachedScrollbarWidth = w1 - w2 ); + }, + getScrollInfo: function( within ) { + var overflowX = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-x" ), + overflowY = within.isWindow || within.isDocument ? "" : + within.element.css( "overflow-y" ), + hasOverflowX = overflowX === "scroll" || + ( overflowX === "auto" && within.width < within.element[ 0 ].scrollWidth ), + hasOverflowY = overflowY === "scroll" || + ( overflowY === "auto" && within.height < within.element[ 0 ].scrollHeight ); + return { + width: hasOverflowY ? $.position.scrollbarWidth() : 0, + height: hasOverflowX ? $.position.scrollbarWidth() : 0 + }; + }, + getWithinInfo: function( element ) { + var withinElement = $( element || window ), + isElemWindow = isWindow( withinElement[ 0 ] ), + isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9, + hasOffset = !isElemWindow && !isDocument; + return { + element: withinElement, + isWindow: isElemWindow, + isDocument: isDocument, + offset: hasOffset ? $( element ).offset() : { left: 0, top: 0 }, + scrollLeft: withinElement.scrollLeft(), + scrollTop: withinElement.scrollTop(), + width: withinElement.outerWidth(), + height: withinElement.outerHeight() + }; + } +}; + +$.fn.position = function( options ) { + if ( !options || !options.of ) { + return _position.apply( this, arguments ); + } + + // Make a copy, we don't want to modify arguments + options = $.extend( {}, options ); + + var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, + + // Make sure string options are treated as CSS selectors + target = typeof options.of === "string" ? + $( document ).find( options.of ) : + $( options.of ), + + within = $.position.getWithinInfo( options.within ), + scrollInfo = $.position.getScrollInfo( within ), + collision = ( options.collision || "flip" ).split( " " ), + offsets = {}; + + dimensions = getDimensions( target ); + if ( target[ 0 ].preventDefault ) { + + // Force left top to allow flipping + options.at = "left top"; + } + targetWidth = dimensions.width; + targetHeight = dimensions.height; + targetOffset = dimensions.offset; + + // Clone to reuse original targetOffset later + basePosition = $.extend( {}, targetOffset ); + + // Force my and at to have valid horizontal and vertical positions + // if a value is missing or invalid, it will be converted to center + $.each( [ "my", "at" ], function() { + var pos = ( options[ this ] || "" ).split( " " ), + horizontalOffset, + verticalOffset; + + if ( pos.length === 1 ) { + pos = rhorizontal.test( pos[ 0 ] ) ? + pos.concat( [ "center" ] ) : + rvertical.test( pos[ 0 ] ) ? + [ "center" ].concat( pos ) : + [ "center", "center" ]; + } + pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; + pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; + + // Calculate offsets + horizontalOffset = roffset.exec( pos[ 0 ] ); + verticalOffset = roffset.exec( pos[ 1 ] ); + offsets[ this ] = [ + horizontalOffset ? horizontalOffset[ 0 ] : 0, + verticalOffset ? verticalOffset[ 0 ] : 0 + ]; + + // Reduce to just the positions without the offsets + options[ this ] = [ + rposition.exec( pos[ 0 ] )[ 0 ], + rposition.exec( pos[ 1 ] )[ 0 ] + ]; + } ); + + // Normalize collision option + if ( collision.length === 1 ) { + collision[ 1 ] = collision[ 0 ]; + } + + if ( options.at[ 0 ] === "right" ) { + basePosition.left += targetWidth; + } else if ( options.at[ 0 ] === "center" ) { + basePosition.left += targetWidth / 2; + } + + if ( options.at[ 1 ] === "bottom" ) { + basePosition.top += targetHeight; + } else if ( options.at[ 1 ] === "center" ) { + basePosition.top += targetHeight / 2; + } + + atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); + basePosition.left += atOffset[ 0 ]; + basePosition.top += atOffset[ 1 ]; + + return this.each( function() { + var collisionPosition, using, + elem = $( this ), + elemWidth = elem.outerWidth(), + elemHeight = elem.outerHeight(), + marginLeft = parseCss( this, "marginLeft" ), + marginTop = parseCss( this, "marginTop" ), + collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + + scrollInfo.width, + collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + + scrollInfo.height, + position = $.extend( {}, basePosition ), + myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); + + if ( options.my[ 0 ] === "right" ) { + position.left -= elemWidth; + } else if ( options.my[ 0 ] === "center" ) { + position.left -= elemWidth / 2; + } + + if ( options.my[ 1 ] === "bottom" ) { + position.top -= elemHeight; + } else if ( options.my[ 1 ] === "center" ) { + position.top -= elemHeight / 2; + } + + position.left += myOffset[ 0 ]; + position.top += myOffset[ 1 ]; + + collisionPosition = { + marginLeft: marginLeft, + marginTop: marginTop + }; + + $.each( [ "left", "top" ], function( i, dir ) { + if ( $.ui.position[ collision[ i ] ] ) { + $.ui.position[ collision[ i ] ][ dir ]( position, { + targetWidth: targetWidth, + targetHeight: targetHeight, + elemWidth: elemWidth, + elemHeight: elemHeight, + collisionPosition: collisionPosition, + collisionWidth: collisionWidth, + collisionHeight: collisionHeight, + offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], + my: options.my, + at: options.at, + within: within, + elem: elem + } ); + } + } ); + + if ( options.using ) { + + // Adds feedback as second argument to using callback, if present + using = function( props ) { + var left = targetOffset.left - position.left, + right = left + targetWidth - elemWidth, + top = targetOffset.top - position.top, + bottom = top + targetHeight - elemHeight, + feedback = { + target: { + element: target, + left: targetOffset.left, + top: targetOffset.top, + width: targetWidth, + height: targetHeight + }, + element: { + element: elem, + left: position.left, + top: position.top, + width: elemWidth, + height: elemHeight + }, + horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", + vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" + }; + if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { + feedback.horizontal = "center"; + } + if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { + feedback.vertical = "middle"; + } + if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { + feedback.important = "horizontal"; + } else { + feedback.important = "vertical"; + } + options.using.call( this, props, feedback ); + }; + } + + elem.offset( $.extend( position, { using: using } ) ); + } ); +}; + +$.ui.position = { + fit: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, + outerWidth = within.width, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = withinOffset - collisionPosLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, + newOverRight; + + // Element is wider than within + if ( data.collisionWidth > outerWidth ) { + + // Element is initially over the left side of within + if ( overLeft > 0 && overRight <= 0 ) { + newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - + withinOffset; + position.left += overLeft - newOverRight; + + // Element is initially over right side of within + } else if ( overRight > 0 && overLeft <= 0 ) { + position.left = withinOffset; + + // Element is initially over both left and right sides of within + } else { + if ( overLeft > overRight ) { + position.left = withinOffset + outerWidth - data.collisionWidth; + } else { + position.left = withinOffset; + } + } + + // Too far left -> align with left edge + } else if ( overLeft > 0 ) { + position.left += overLeft; + + // Too far right -> align with right edge + } else if ( overRight > 0 ) { + position.left -= overRight; + + // Adjust based on position and margin + } else { + position.left = max( position.left - collisionPosLeft, position.left ); + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.isWindow ? within.scrollTop : within.offset.top, + outerHeight = data.within.height, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = withinOffset - collisionPosTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, + newOverBottom; + + // Element is taller than within + if ( data.collisionHeight > outerHeight ) { + + // Element is initially over the top of within + if ( overTop > 0 && overBottom <= 0 ) { + newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - + withinOffset; + position.top += overTop - newOverBottom; + + // Element is initially over bottom of within + } else if ( overBottom > 0 && overTop <= 0 ) { + position.top = withinOffset; + + // Element is initially over both top and bottom of within + } else { + if ( overTop > overBottom ) { + position.top = withinOffset + outerHeight - data.collisionHeight; + } else { + position.top = withinOffset; + } + } + + // Too far up -> align with top + } else if ( overTop > 0 ) { + position.top += overTop; + + // Too far down -> align with bottom edge + } else if ( overBottom > 0 ) { + position.top -= overBottom; + + // Adjust based on position and margin + } else { + position.top = max( position.top - collisionPosTop, position.top ); + } + } + }, + flip: { + left: function( position, data ) { + var within = data.within, + withinOffset = within.offset.left + within.scrollLeft, + outerWidth = within.width, + offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, + collisionPosLeft = position.left - data.collisionPosition.marginLeft, + overLeft = collisionPosLeft - offsetLeft, + overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, + myOffset = data.my[ 0 ] === "left" ? + -data.elemWidth : + data.my[ 0 ] === "right" ? + data.elemWidth : + 0, + atOffset = data.at[ 0 ] === "left" ? + data.targetWidth : + data.at[ 0 ] === "right" ? + -data.targetWidth : + 0, + offset = -2 * data.offset[ 0 ], + newOverRight, + newOverLeft; + + if ( overLeft < 0 ) { + newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - + outerWidth - withinOffset; + if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { + position.left += myOffset + atOffset + offset; + } + } else if ( overRight > 0 ) { + newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + + atOffset + offset - offsetLeft; + if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { + position.left += myOffset + atOffset + offset; + } + } + }, + top: function( position, data ) { + var within = data.within, + withinOffset = within.offset.top + within.scrollTop, + outerHeight = within.height, + offsetTop = within.isWindow ? within.scrollTop : within.offset.top, + collisionPosTop = position.top - data.collisionPosition.marginTop, + overTop = collisionPosTop - offsetTop, + overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, + top = data.my[ 1 ] === "top", + myOffset = top ? + -data.elemHeight : + data.my[ 1 ] === "bottom" ? + data.elemHeight : + 0, + atOffset = data.at[ 1 ] === "top" ? + data.targetHeight : + data.at[ 1 ] === "bottom" ? + -data.targetHeight : + 0, + offset = -2 * data.offset[ 1 ], + newOverTop, + newOverBottom; + if ( overTop < 0 ) { + newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - + outerHeight - withinOffset; + if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) { + position.top += myOffset + atOffset + offset; + } + } else if ( overBottom > 0 ) { + newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + + offset - offsetTop; + if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) { + position.top += myOffset + atOffset + offset; + } + } + } + }, + flipfit: { + left: function() { + $.ui.position.flip.left.apply( this, arguments ); + $.ui.position.fit.left.apply( this, arguments ); + }, + top: function() { + $.ui.position.flip.top.apply( this, arguments ); + $.ui.position.fit.top.apply( this, arguments ); + } + } +}; + +} )(); + +var position = $.ui.position; + + +/*! + * jQuery UI :data 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: :data Selector +//>>group: Core +//>>description: Selects elements which have data stored under the specified key. +//>>docs: http://api.jqueryui.com/data-selector/ + + +var data = $.extend( $.expr.pseudos, { + data: $.expr.createPseudo ? + $.expr.createPseudo( function( dataName ) { + return function( elem ) { + return !!$.data( elem, dataName ); + }; + } ) : + + // Support: jQuery <1.8 + function( elem, i, match ) { + return !!$.data( elem, match[ 3 ] ); + } +} ); + +/*! + * jQuery UI Disable Selection 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: disableSelection +//>>group: Core +//>>description: Disable selection of text content within the set of matched elements. +//>>docs: http://api.jqueryui.com/disableSelection/ + +// This file is deprecated + +var disableSelection = $.fn.extend( { + disableSelection: ( function() { + var eventType = "onselectstart" in document.createElement( "div" ) ? + "selectstart" : + "mousedown"; + + return function() { + return this.on( eventType + ".ui-disableSelection", function( event ) { + event.preventDefault(); + } ); + }; + } )(), + + enableSelection: function() { + return this.off( ".ui-disableSelection" ); + } +} ); + + + +// Create a local jQuery because jQuery Color relies on it and the +// global may not exist with AMD and a custom build (#10199). +// This module is a noop if used as a regular AMD module. +// eslint-disable-next-line no-unused-vars +var jQuery = $; + + +/*! + * jQuery Color Animations v2.2.0 + * https://github.com/jquery/jquery-color + * + * Copyright OpenJS Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * Date: Sun May 10 09:02:36 2020 +0200 + */ + + + + var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " + + "borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor", + + class2type = {}, + toString = class2type.toString, + + // plusequals test for += 100 -= 100 + rplusequals = /^([\-+])=\s*(\d+\.?\d*)/, + + // a set of RE's that can match strings and generate color tuples. + stringParsers = [ { + re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ], + execResult[ 3 ], + execResult[ 4 ] + ]; + } + }, { + re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + parse: function( execResult ) { + return [ + execResult[ 1 ] * 2.55, + execResult[ 2 ] * 2.55, + execResult[ 3 ] * 2.55, + execResult[ 4 ] + ]; + } + }, { + + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})?/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ], 16 ), + execResult[ 4 ] ? + ( parseInt( execResult[ 4 ], 16 ) / 255 ).toFixed( 2 ) : + 1 + ]; + } + }, { + + // this regex ignores A-F because it's compared against an already lowercased string + re: /#([a-f0-9])([a-f0-9])([a-f0-9])([a-f0-9])?/, + parse: function( execResult ) { + return [ + parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ), + parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ), + parseInt( execResult[ 3 ] + execResult[ 3 ], 16 ), + execResult[ 4 ] ? + ( parseInt( execResult[ 4 ] + execResult[ 4 ], 16 ) / 255 ) + .toFixed( 2 ) : + 1 + ]; + } + }, { + re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/, + space: "hsla", + parse: function( execResult ) { + return [ + execResult[ 1 ], + execResult[ 2 ] / 100, + execResult[ 3 ] / 100, + execResult[ 4 ] + ]; + } + } ], + + // jQuery.Color( ) + color = jQuery.Color = function( color, green, blue, alpha ) { + return new jQuery.Color.fn.parse( color, green, blue, alpha ); + }, + spaces = { + rgba: { + props: { + red: { + idx: 0, + type: "byte" + }, + green: { + idx: 1, + type: "byte" + }, + blue: { + idx: 2, + type: "byte" + } + } + }, + + hsla: { + props: { + hue: { + idx: 0, + type: "degrees" + }, + saturation: { + idx: 1, + type: "percent" + }, + lightness: { + idx: 2, + type: "percent" + } + } + } + }, + propTypes = { + "byte": { + floor: true, + max: 255 + }, + "percent": { + max: 1 + }, + "degrees": { + mod: 360, + floor: true + } + }, + support = color.support = {}, + + // element for support tests + supportElem = jQuery( "

" )[ 0 ], + + // colors = jQuery.Color.names + colors, + + // local aliases of functions called often + each = jQuery.each; + +// determine rgba support immediately +supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; +support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; + +// define cache name and alpha properties +// for rgba and hsla spaces +each( spaces, function( spaceName, space ) { + space.cache = "_" + spaceName; + space.props.alpha = { + idx: 3, + type: "percent", + def: 1 + }; +} ); + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), + function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); + } ); + +function getType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + return typeof obj === "object" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} + +function clamp( value, prop, allowEmpty ) { + var type = propTypes[ prop.type ] || {}; + + if ( value == null ) { + return ( allowEmpty || !prop.def ) ? null : prop.def; + } + + // ~~ is an short way of doing floor for positive numbers + value = type.floor ? ~~value : parseFloat( value ); + + // IE will pass in empty strings as value for alpha, + // which will hit this case + if ( isNaN( value ) ) { + return prop.def; + } + + if ( type.mod ) { + + // we add mod before modding to make sure that negatives values + // get converted properly: -10 -> 350 + return ( value + type.mod ) % type.mod; + } + + // for now all property types without mod have min and max + return Math.min( type.max, Math.max( 0, value ) ); +} + +function stringParse( string ) { + var inst = color(), + rgba = inst._rgba = []; + + string = string.toLowerCase(); + + each( stringParsers, function( _i, parser ) { + var parsed, + match = parser.re.exec( string ), + values = match && parser.parse( match ), + spaceName = parser.space || "rgba"; + + if ( values ) { + parsed = inst[ spaceName ]( values ); + + // if this was an rgba parse the assignment might happen twice + // oh well.... + inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; + rgba = inst._rgba = parsed._rgba; + + // exit each( stringParsers ) here because we matched + return false; + } + } ); + + // Found a stringParser that handled it + if ( rgba.length ) { + + // if this came from a parsed string, force "transparent" when alpha is 0 + // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) + if ( rgba.join() === "0,0,0,0" ) { + jQuery.extend( rgba, colors.transparent ); + } + return inst; + } + + // named colors + return colors[ string ]; +} + +color.fn = jQuery.extend( color.prototype, { + parse: function( red, green, blue, alpha ) { + if ( red === undefined ) { + this._rgba = [ null, null, null, null ]; + return this; + } + if ( red.jquery || red.nodeType ) { + red = jQuery( red ).css( green ); + green = undefined; + } + + var inst = this, + type = getType( red ), + rgba = this._rgba = []; + + // more than 1 argument specified - assume ( red, green, blue, alpha ) + if ( green !== undefined ) { + red = [ red, green, blue, alpha ]; + type = "array"; + } + + if ( type === "string" ) { + return this.parse( stringParse( red ) || colors._default ); + } + + if ( type === "array" ) { + each( spaces.rgba.props, function( _key, prop ) { + rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); + } ); + return this; + } + + if ( type === "object" ) { + if ( red instanceof color ) { + each( spaces, function( _spaceName, space ) { + if ( red[ space.cache ] ) { + inst[ space.cache ] = red[ space.cache ].slice(); + } + } ); + } else { + each( spaces, function( _spaceName, space ) { + var cache = space.cache; + each( space.props, function( key, prop ) { + + // if the cache doesn't exist, and we know how to convert + if ( !inst[ cache ] && space.to ) { + + // if the value was null, we don't need to copy it + // if the key was alpha, we don't need to copy it either + if ( key === "alpha" || red[ key ] == null ) { + return; + } + inst[ cache ] = space.to( inst._rgba ); + } + + // this is the only case where we allow nulls for ALL properties. + // call clamp with alwaysAllowEmpty + inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); + } ); + + // everything defined but alpha? + if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { + + // use the default of 1 + if ( inst[ cache ][ 3 ] == null ) { + inst[ cache ][ 3 ] = 1; + } + + if ( space.from ) { + inst._rgba = space.from( inst[ cache ] ); + } + } + } ); + } + return this; + } + }, + is: function( compare ) { + var is = color( compare ), + same = true, + inst = this; + + each( spaces, function( _, space ) { + var localCache, + isCache = is[ space.cache ]; + if ( isCache ) { + localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; + each( space.props, function( _, prop ) { + if ( isCache[ prop.idx ] != null ) { + same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); + return same; + } + } ); + } + return same; + } ); + return same; + }, + _space: function() { + var used = [], + inst = this; + each( spaces, function( spaceName, space ) { + if ( inst[ space.cache ] ) { + used.push( spaceName ); + } + } ); + return used.pop(); + }, + transition: function( other, distance ) { + var end = color( other ), + spaceName = end._space(), + space = spaces[ spaceName ], + startColor = this.alpha() === 0 ? color( "transparent" ) : this, + start = startColor[ space.cache ] || space.to( startColor._rgba ), + result = start.slice(); + + end = end[ space.cache ]; + each( space.props, function( _key, prop ) { + var index = prop.idx, + startValue = start[ index ], + endValue = end[ index ], + type = propTypes[ prop.type ] || {}; + + // if null, don't override start value + if ( endValue === null ) { + return; + } + + // if null - use end + if ( startValue === null ) { + result[ index ] = endValue; + } else { + if ( type.mod ) { + if ( endValue - startValue > type.mod / 2 ) { + startValue += type.mod; + } else if ( startValue - endValue > type.mod / 2 ) { + startValue -= type.mod; + } + } + result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); + } + } ); + return this[ spaceName ]( result ); + }, + blend: function( opaque ) { + + // if we are already opaque - return ourself + if ( this._rgba[ 3 ] === 1 ) { + return this; + } + + var rgb = this._rgba.slice(), + a = rgb.pop(), + blend = color( opaque )._rgba; + + return color( jQuery.map( rgb, function( v, i ) { + return ( 1 - a ) * blend[ i ] + a * v; + } ) ); + }, + toRgbaString: function() { + var prefix = "rgba(", + rgba = jQuery.map( this._rgba, function( v, i ) { + if ( v != null ) { + return v; + } + return i > 2 ? 1 : 0; + } ); + + if ( rgba[ 3 ] === 1 ) { + rgba.pop(); + prefix = "rgb("; + } + + return prefix + rgba.join() + ")"; + }, + toHslaString: function() { + var prefix = "hsla(", + hsla = jQuery.map( this.hsla(), function( v, i ) { + if ( v == null ) { + v = i > 2 ? 1 : 0; + } + + // catch 1 and 2 + if ( i && i < 3 ) { + v = Math.round( v * 100 ) + "%"; + } + return v; + } ); + + if ( hsla[ 3 ] === 1 ) { + hsla.pop(); + prefix = "hsl("; + } + return prefix + hsla.join() + ")"; + }, + toHexString: function( includeAlpha ) { + var rgba = this._rgba.slice(), + alpha = rgba.pop(); + + if ( includeAlpha ) { + rgba.push( ~~( alpha * 255 ) ); + } + + return "#" + jQuery.map( rgba, function( v ) { + + // default to 0 when nulls exist + v = ( v || 0 ).toString( 16 ); + return v.length === 1 ? "0" + v : v; + } ).join( "" ); + }, + toString: function() { + return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); + } +} ); +color.fn.parse.prototype = color.fn; + +// hsla conversions adapted from: +// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 + +function hue2rgb( p, q, h ) { + h = ( h + 1 ) % 1; + if ( h * 6 < 1 ) { + return p + ( q - p ) * h * 6; + } + if ( h * 2 < 1 ) { + return q; + } + if ( h * 3 < 2 ) { + return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; + } + return p; +} + +spaces.hsla.to = function( rgba ) { + if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { + return [ null, null, null, rgba[ 3 ] ]; + } + var r = rgba[ 0 ] / 255, + g = rgba[ 1 ] / 255, + b = rgba[ 2 ] / 255, + a = rgba[ 3 ], + max = Math.max( r, g, b ), + min = Math.min( r, g, b ), + diff = max - min, + add = max + min, + l = add * 0.5, + h, s; + + if ( min === max ) { + h = 0; + } else if ( r === max ) { + h = ( 60 * ( g - b ) / diff ) + 360; + } else if ( g === max ) { + h = ( 60 * ( b - r ) / diff ) + 120; + } else { + h = ( 60 * ( r - g ) / diff ) + 240; + } + + // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% + // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) + if ( diff === 0 ) { + s = 0; + } else if ( l <= 0.5 ) { + s = diff / add; + } else { + s = diff / ( 2 - add ); + } + return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; +}; + +spaces.hsla.from = function( hsla ) { + if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { + return [ null, null, null, hsla[ 3 ] ]; + } + var h = hsla[ 0 ] / 360, + s = hsla[ 1 ], + l = hsla[ 2 ], + a = hsla[ 3 ], + q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, + p = 2 * l - q; + + return [ + Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), + Math.round( hue2rgb( p, q, h ) * 255 ), + Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), + a + ]; +}; + + +each( spaces, function( spaceName, space ) { + var props = space.props, + cache = space.cache, + to = space.to, + from = space.from; + + // makes rgba() and hsla() + color.fn[ spaceName ] = function( value ) { + + // generate a cache for this space if it doesn't exist + if ( to && !this[ cache ] ) { + this[ cache ] = to( this._rgba ); + } + if ( value === undefined ) { + return this[ cache ].slice(); + } + + var ret, + type = getType( value ), + arr = ( type === "array" || type === "object" ) ? value : arguments, + local = this[ cache ].slice(); + + each( props, function( key, prop ) { + var val = arr[ type === "object" ? key : prop.idx ]; + if ( val == null ) { + val = local[ prop.idx ]; + } + local[ prop.idx ] = clamp( val, prop ); + } ); + + if ( from ) { + ret = color( from( local ) ); + ret[ cache ] = local; + return ret; + } else { + return color( local ); + } + }; + + // makes red() green() blue() alpha() hue() saturation() lightness() + each( props, function( key, prop ) { + + // alpha is included in more than one space + if ( color.fn[ key ] ) { + return; + } + color.fn[ key ] = function( value ) { + var local, cur, match, fn, + vtype = getType( value ); + + if ( key === "alpha" ) { + fn = this._hsla ? "hsla" : "rgba"; + } else { + fn = spaceName; + } + local = this[ fn ](); + cur = local[ prop.idx ]; + + if ( vtype === "undefined" ) { + return cur; + } + + if ( vtype === "function" ) { + value = value.call( this, cur ); + vtype = getType( value ); + } + if ( value == null && prop.empty ) { + return this; + } + if ( vtype === "string" ) { + match = rplusequals.exec( value ); + if ( match ) { + value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); + } + } + local[ prop.idx ] = value; + return this[ fn ]( local ); + }; + } ); +} ); + +// add cssHook and .fx.step function for each named hook. +// accept a space separated string of properties +color.hook = function( hook ) { + var hooks = hook.split( " " ); + each( hooks, function( _i, hook ) { + jQuery.cssHooks[ hook ] = { + set: function( elem, value ) { + var parsed, curElem, + backgroundColor = ""; + + if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { + value = color( parsed || value ); + if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { + curElem = hook === "backgroundColor" ? elem.parentNode : elem; + while ( + ( backgroundColor === "" || backgroundColor === "transparent" ) && + curElem && curElem.style + ) { + try { + backgroundColor = jQuery.css( curElem, "backgroundColor" ); + curElem = curElem.parentNode; + } catch ( e ) { + } + } + + value = value.blend( backgroundColor && backgroundColor !== "transparent" ? + backgroundColor : + "_default" ); + } + + value = value.toRgbaString(); + } + try { + elem.style[ hook ] = value; + } catch ( e ) { + + // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' + } + } + }; + jQuery.fx.step[ hook ] = function( fx ) { + if ( !fx.colorInit ) { + fx.start = color( fx.elem, hook ); + fx.end = color( fx.end ); + fx.colorInit = true; + } + jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); + }; + } ); + +}; + +color.hook( stepHooks ); + +jQuery.cssHooks.borderColor = { + expand: function( value ) { + var expanded = {}; + + each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { + expanded[ "border" + part + "Color" ] = value; + } ); + return expanded; + } +}; + +// Basic color names only. +// Usage of any of the other color names requires adding yourself or including +// jquery.color.svg-names.js. +colors = jQuery.Color.names = { + + // 4.1. Basic color keywords + aqua: "#00ffff", + black: "#000000", + blue: "#0000ff", + fuchsia: "#ff00ff", + gray: "#808080", + green: "#008000", + lime: "#00ff00", + maroon: "#800000", + navy: "#000080", + olive: "#808000", + purple: "#800080", + red: "#ff0000", + silver: "#c0c0c0", + teal: "#008080", + white: "#ffffff", + yellow: "#ffff00", + + // 4.2.3. "transparent" color keyword + transparent: [ null, null, null, 0 ], + + _default: "#ffffff" +}; + + +/*! + * jQuery UI Effects 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Effects Core +//>>group: Effects +/* eslint-disable max-len */ +//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects. +/* eslint-enable max-len */ +//>>docs: http://api.jqueryui.com/category/effects-core/ +//>>demos: http://jqueryui.com/effect/ + + +var dataSpace = "ui-effects-", + dataSpaceStyle = "ui-effects-style", + dataSpaceAnimated = "ui-effects-animated"; + +$.effects = { + effect: {} +}; + +/******************************************************************************/ +/****************************** CLASS ANIMATIONS ******************************/ +/******************************************************************************/ +( function() { + +var classAnimationActions = [ "add", "remove", "toggle" ], + shorthandStyles = { + border: 1, + borderBottom: 1, + borderColor: 1, + borderLeft: 1, + borderRight: 1, + borderTop: 1, + borderWidth: 1, + margin: 1, + padding: 1 + }; + +$.each( + [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], + function( _, prop ) { + $.fx.step[ prop ] = function( fx ) { + if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { + jQuery.style( fx.elem, prop, fx.end ); + fx.setAttr = true; + } + }; + } +); + +function camelCase( string ) { + return string.replace( /-([\da-z])/gi, function( all, letter ) { + return letter.toUpperCase(); + } ); +} + +function getElementStyles( elem ) { + var key, len, + style = elem.ownerDocument.defaultView ? + elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : + elem.currentStyle, + styles = {}; + + if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { + len = style.length; + while ( len-- ) { + key = style[ len ]; + if ( typeof style[ key ] === "string" ) { + styles[ camelCase( key ) ] = style[ key ]; + } + } + + // Support: Opera, IE <9 + } else { + for ( key in style ) { + if ( typeof style[ key ] === "string" ) { + styles[ key ] = style[ key ]; + } + } + } + + return styles; +} + +function styleDifference( oldStyle, newStyle ) { + var diff = {}, + name, value; + + for ( name in newStyle ) { + value = newStyle[ name ]; + if ( oldStyle[ name ] !== value ) { + if ( !shorthandStyles[ name ] ) { + if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { + diff[ name ] = value; + } + } + } + } + + return diff; +} + +// Support: jQuery <1.8 +if ( !$.fn.addBack ) { + $.fn.addBack = function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + }; +} + +$.effects.animateClass = function( value, duration, easing, callback ) { + var o = $.speed( duration, easing, callback ); + + return this.queue( function() { + var animated = $( this ), + baseClass = animated.attr( "class" ) || "", + applyClassChange, + allAnimations = o.children ? animated.find( "*" ).addBack() : animated; + + // Map the animated objects to store the original styles. + allAnimations = allAnimations.map( function() { + var el = $( this ); + return { + el: el, + start: getElementStyles( this ) + }; + } ); + + // Apply class change + applyClassChange = function() { + $.each( classAnimationActions, function( i, action ) { + if ( value[ action ] ) { + animated[ action + "Class" ]( value[ action ] ); + } + } ); + }; + applyClassChange(); + + // Map all animated objects again - calculate new styles and diff + allAnimations = allAnimations.map( function() { + this.end = getElementStyles( this.el[ 0 ] ); + this.diff = styleDifference( this.start, this.end ); + return this; + } ); + + // Apply original class + animated.attr( "class", baseClass ); + + // Map all animated objects again - this time collecting a promise + allAnimations = allAnimations.map( function() { + var styleInfo = this, + dfd = $.Deferred(), + opts = $.extend( {}, o, { + queue: false, + complete: function() { + dfd.resolve( styleInfo ); + } + } ); + + this.el.animate( this.diff, opts ); + return dfd.promise(); + } ); + + // Once all animations have completed: + $.when.apply( $, allAnimations.get() ).done( function() { + + // Set the final class + applyClassChange(); + + // For each animated element, + // clear all css properties that were animated + $.each( arguments, function() { + var el = this.el; + $.each( this.diff, function( key ) { + el.css( key, "" ); + } ); + } ); + + // This is guarnteed to be there if you use jQuery.speed() + // it also handles dequeuing the next anim... + o.complete.call( animated[ 0 ] ); + } ); + } ); +}; + +$.fn.extend( { + addClass: ( function( orig ) { + return function( classNames, speed, easing, callback ) { + return speed ? + $.effects.animateClass.call( this, + { add: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + } )( $.fn.addClass ), + + removeClass: ( function( orig ) { + return function( classNames, speed, easing, callback ) { + return arguments.length > 1 ? + $.effects.animateClass.call( this, + { remove: classNames }, speed, easing, callback ) : + orig.apply( this, arguments ); + }; + } )( $.fn.removeClass ), + + toggleClass: ( function( orig ) { + return function( classNames, force, speed, easing, callback ) { + if ( typeof force === "boolean" || force === undefined ) { + if ( !speed ) { + + // Without speed parameter + return orig.apply( this, arguments ); + } else { + return $.effects.animateClass.call( this, + ( force ? { add: classNames } : { remove: classNames } ), + speed, easing, callback ); + } + } else { + + // Without force parameter + return $.effects.animateClass.call( this, + { toggle: classNames }, force, speed, easing ); + } + }; + } )( $.fn.toggleClass ), + + switchClass: function( remove, add, speed, easing, callback ) { + return $.effects.animateClass.call( this, { + add: add, + remove: remove + }, speed, easing, callback ); + } +} ); + +} )(); + +/******************************************************************************/ +/*********************************** EFFECTS **********************************/ +/******************************************************************************/ + +( function() { + +if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) { + $.expr.pseudos.animated = ( function( orig ) { + return function( elem ) { + return !!$( elem ).data( dataSpaceAnimated ) || orig( elem ); + }; + } )( $.expr.pseudos.animated ); +} + +if ( $.uiBackCompat !== false ) { + $.extend( $.effects, { + + // Saves a set of properties in a data storage + save: function( element, set ) { + var i = 0, length = set.length; + for ( ; i < length; i++ ) { + if ( set[ i ] !== null ) { + element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] ); + } + } + }, + + // Restores a set of previously saved properties from a data storage + restore: function( element, set ) { + var val, i = 0, length = set.length; + for ( ; i < length; i++ ) { + if ( set[ i ] !== null ) { + val = element.data( dataSpace + set[ i ] ); + element.css( set[ i ], val ); + } + } + }, + + setMode: function( el, mode ) { + if ( mode === "toggle" ) { + mode = el.is( ":hidden" ) ? "show" : "hide"; + } + return mode; + }, + + // Wraps the element around a wrapper that copies position properties + createWrapper: function( element ) { + + // If the element is already wrapped, return it + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + return element.parent(); + } + + // Wrap the element + var props = { + width: element.outerWidth( true ), + height: element.outerHeight( true ), + "float": element.css( "float" ) + }, + wrapper = $( "

" ) + .addClass( "ui-effects-wrapper" ) + .css( { + fontSize: "100%", + background: "transparent", + border: "none", + margin: 0, + padding: 0 + } ), + + // Store the size in case width/height are defined in % - Fixes #5245 + size = { + width: element.width(), + height: element.height() + }, + active = document.activeElement; + + // Support: Firefox + // Firefox incorrectly exposes anonymous content + // https://bugzilla.mozilla.org/show_bug.cgi?id=561664 + try { + // eslint-disable-next-line no-unused-expressions + active.id; + } catch ( e ) { + active = document.body; + } + + element.wrap( wrapper ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).trigger( "focus" ); + } + + // Hotfix for jQuery 1.4 since some change in wrap() seems to actually + // lose the reference to the wrapped element + wrapper = element.parent(); + + // Transfer positioning properties to the wrapper + if ( element.css( "position" ) === "static" ) { + wrapper.css( { position: "relative" } ); + element.css( { position: "relative" } ); + } else { + $.extend( props, { + position: element.css( "position" ), + zIndex: element.css( "z-index" ) + } ); + $.each( [ "top", "left", "bottom", "right" ], function( i, pos ) { + props[ pos ] = element.css( pos ); + if ( isNaN( parseInt( props[ pos ], 10 ) ) ) { + props[ pos ] = "auto"; + } + } ); + element.css( { + position: "relative", + top: 0, + left: 0, + right: "auto", + bottom: "auto" + } ); + } + element.css( size ); + + return wrapper.css( props ).show(); + }, + + removeWrapper: function( element ) { + var active = document.activeElement; + + if ( element.parent().is( ".ui-effects-wrapper" ) ) { + element.parent().replaceWith( element ); + + // Fixes #7595 - Elements lose focus when wrapped. + if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) { + $( active ).trigger( "focus" ); + } + } + + return element; + } + } ); +} + +$.extend( $.effects, { + version: "1.13.2", + + define: function( name, mode, effect ) { + if ( !effect ) { + effect = mode; + mode = "effect"; + } + + $.effects.effect[ name ] = effect; + $.effects.effect[ name ].mode = mode; + + return effect; + }, + + scaledDimensions: function( element, percent, direction ) { + if ( percent === 0 ) { + return { + height: 0, + width: 0, + outerHeight: 0, + outerWidth: 0 + }; + } + + var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1, + y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1; + + return { + height: element.height() * y, + width: element.width() * x, + outerHeight: element.outerHeight() * y, + outerWidth: element.outerWidth() * x + }; + + }, + + clipToBox: function( animation ) { + return { + width: animation.clip.right - animation.clip.left, + height: animation.clip.bottom - animation.clip.top, + left: animation.clip.left, + top: animation.clip.top + }; + }, + + // Injects recently queued functions to be first in line (after "inprogress") + unshift: function( element, queueLength, count ) { + var queue = element.queue(); + + if ( queueLength > 1 ) { + queue.splice.apply( queue, + [ 1, 0 ].concat( queue.splice( queueLength, count ) ) ); + } + element.dequeue(); + }, + + saveStyle: function( element ) { + element.data( dataSpaceStyle, element[ 0 ].style.cssText ); + }, + + restoreStyle: function( element ) { + element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || ""; + element.removeData( dataSpaceStyle ); + }, + + mode: function( element, mode ) { + var hidden = element.is( ":hidden" ); + + if ( mode === "toggle" ) { + mode = hidden ? "show" : "hide"; + } + if ( hidden ? mode === "hide" : mode === "show" ) { + mode = "none"; + } + return mode; + }, + + // Translates a [top,left] array into a baseline value + getBaseline: function( origin, original ) { + var y, x; + + switch ( origin[ 0 ] ) { + case "top": + y = 0; + break; + case "middle": + y = 0.5; + break; + case "bottom": + y = 1; + break; + default: + y = origin[ 0 ] / original.height; + } + + switch ( origin[ 1 ] ) { + case "left": + x = 0; + break; + case "center": + x = 0.5; + break; + case "right": + x = 1; + break; + default: + x = origin[ 1 ] / original.width; + } + + return { + x: x, + y: y + }; + }, + + // Creates a placeholder element so that the original element can be made absolute + createPlaceholder: function( element ) { + var placeholder, + cssPosition = element.css( "position" ), + position = element.position(); + + // Lock in margins first to account for form elements, which + // will change margin if you explicitly set height + // see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380 + // Support: Safari + element.css( { + marginTop: element.css( "marginTop" ), + marginBottom: element.css( "marginBottom" ), + marginLeft: element.css( "marginLeft" ), + marginRight: element.css( "marginRight" ) + } ) + .outerWidth( element.outerWidth() ) + .outerHeight( element.outerHeight() ); + + if ( /^(static|relative)/.test( cssPosition ) ) { + cssPosition = "absolute"; + + placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( { + + // Convert inline to inline block to account for inline elements + // that turn to inline block based on content (like img) + display: /^(inline|ruby)/.test( element.css( "display" ) ) ? + "inline-block" : + "block", + visibility: "hidden", + + // Margins need to be set to account for margin collapse + marginTop: element.css( "marginTop" ), + marginBottom: element.css( "marginBottom" ), + marginLeft: element.css( "marginLeft" ), + marginRight: element.css( "marginRight" ), + "float": element.css( "float" ) + } ) + .outerWidth( element.outerWidth() ) + .outerHeight( element.outerHeight() ) + .addClass( "ui-effects-placeholder" ); + + element.data( dataSpace + "placeholder", placeholder ); + } + + element.css( { + position: cssPosition, + left: position.left, + top: position.top + } ); + + return placeholder; + }, + + removePlaceholder: function( element ) { + var dataKey = dataSpace + "placeholder", + placeholder = element.data( dataKey ); + + if ( placeholder ) { + placeholder.remove(); + element.removeData( dataKey ); + } + }, + + // Removes a placeholder if it exists and restores + // properties that were modified during placeholder creation + cleanUp: function( element ) { + $.effects.restoreStyle( element ); + $.effects.removePlaceholder( element ); + }, + + setTransition: function( element, list, factor, value ) { + value = value || {}; + $.each( list, function( i, x ) { + var unit = element.cssUnit( x ); + if ( unit[ 0 ] > 0 ) { + value[ x ] = unit[ 0 ] * factor + unit[ 1 ]; + } + } ); + return value; + } +} ); + +// Return an effect options object for the given parameters: +function _normalizeArguments( effect, options, speed, callback ) { + + // Allow passing all options as the first parameter + if ( $.isPlainObject( effect ) ) { + options = effect; + effect = effect.effect; + } + + // Convert to an object + effect = { effect: effect }; + + // Catch (effect, null, ...) + if ( options == null ) { + options = {}; + } + + // Catch (effect, callback) + if ( typeof options === "function" ) { + callback = options; + speed = null; + options = {}; + } + + // Catch (effect, speed, ?) + if ( typeof options === "number" || $.fx.speeds[ options ] ) { + callback = speed; + speed = options; + options = {}; + } + + // Catch (effect, options, callback) + if ( typeof speed === "function" ) { + callback = speed; + speed = null; + } + + // Add options to effect + if ( options ) { + $.extend( effect, options ); + } + + speed = speed || options.duration; + effect.duration = $.fx.off ? 0 : + typeof speed === "number" ? speed : + speed in $.fx.speeds ? $.fx.speeds[ speed ] : + $.fx.speeds._default; + + effect.complete = callback || options.complete; + + return effect; +} + +function standardAnimationOption( option ) { + + // Valid standard speeds (nothing, number, named speed) + if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) { + return true; + } + + // Invalid strings - treat as "normal" speed + if ( typeof option === "string" && !$.effects.effect[ option ] ) { + return true; + } + + // Complete callback + if ( typeof option === "function" ) { + return true; + } + + // Options hash (but not naming an effect) + if ( typeof option === "object" && !option.effect ) { + return true; + } + + // Didn't match any standard API + return false; +} + +$.fn.extend( { + effect: function( /* effect, options, speed, callback */ ) { + var args = _normalizeArguments.apply( this, arguments ), + effectMethod = $.effects.effect[ args.effect ], + defaultMode = effectMethod.mode, + queue = args.queue, + queueName = queue || "fx", + complete = args.complete, + mode = args.mode, + modes = [], + prefilter = function( next ) { + var el = $( this ), + normalizedMode = $.effects.mode( el, mode ) || defaultMode; + + // Sentinel for duck-punching the :animated pseudo-selector + el.data( dataSpaceAnimated, true ); + + // Save effect mode for later use, + // we can't just call $.effects.mode again later, + // as the .show() below destroys the initial state + modes.push( normalizedMode ); + + // See $.uiBackCompat inside of run() for removal of defaultMode in 1.14 + if ( defaultMode && ( normalizedMode === "show" || + ( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) { + el.show(); + } + + if ( !defaultMode || normalizedMode !== "none" ) { + $.effects.saveStyle( el ); + } + + if ( typeof next === "function" ) { + next(); + } + }; + + if ( $.fx.off || !effectMethod ) { + + // Delegate to the original method (e.g., .show()) if possible + if ( mode ) { + return this[ mode ]( args.duration, complete ); + } else { + return this.each( function() { + if ( complete ) { + complete.call( this ); + } + } ); + } + } + + function run( next ) { + var elem = $( this ); + + function cleanup() { + elem.removeData( dataSpaceAnimated ); + + $.effects.cleanUp( elem ); + + if ( args.mode === "hide" ) { + elem.hide(); + } + + done(); + } + + function done() { + if ( typeof complete === "function" ) { + complete.call( elem[ 0 ] ); + } + + if ( typeof next === "function" ) { + next(); + } + } + + // Override mode option on a per element basis, + // as toggle can be either show or hide depending on element state + args.mode = modes.shift(); + + if ( $.uiBackCompat !== false && !defaultMode ) { + if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) { + + // Call the core method to track "olddisplay" properly + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[ 0 ], args, done ); + } + } else { + if ( args.mode === "none" ) { + + // Call the core method to track "olddisplay" properly + elem[ mode ](); + done(); + } else { + effectMethod.call( elem[ 0 ], args, cleanup ); + } + } + } + + // Run prefilter on all elements first to ensure that + // any showing or hiding happens before placeholder creation, + // which ensures that any layout changes are correctly captured. + return queue === false ? + this.each( prefilter ).each( run ) : + this.queue( queueName, prefilter ).queue( queueName, run ); + }, + + show: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "show"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.show ), + + hide: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "hide"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.hide ), + + toggle: ( function( orig ) { + return function( option ) { + if ( standardAnimationOption( option ) || typeof option === "boolean" ) { + return orig.apply( this, arguments ); + } else { + var args = _normalizeArguments.apply( this, arguments ); + args.mode = "toggle"; + return this.effect.call( this, args ); + } + }; + } )( $.fn.toggle ), + + cssUnit: function( key ) { + var style = this.css( key ), + val = []; + + $.each( [ "em", "px", "%", "pt" ], function( i, unit ) { + if ( style.indexOf( unit ) > 0 ) { + val = [ parseFloat( style ), unit ]; + } + } ); + return val; + }, + + cssClip: function( clipObj ) { + if ( clipObj ) { + return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " + + clipObj.bottom + "px " + clipObj.left + "px)" ); + } + return parseClip( this.css( "clip" ), this ); + }, + + transfer: function( options, done ) { + var element = $( this ), + target = $( options.to ), + targetFixed = target.css( "position" ) === "fixed", + body = $( "body" ), + fixTop = targetFixed ? body.scrollTop() : 0, + fixLeft = targetFixed ? body.scrollLeft() : 0, + endPosition = target.offset(), + animation = { + top: endPosition.top - fixTop, + left: endPosition.left - fixLeft, + height: target.innerHeight(), + width: target.innerWidth() + }, + startPosition = element.offset(), + transfer = $( "
" ); + + transfer + .appendTo( "body" ) + .addClass( options.className ) + .css( { + top: startPosition.top - fixTop, + left: startPosition.left - fixLeft, + height: element.innerHeight(), + width: element.innerWidth(), + position: targetFixed ? "fixed" : "absolute" + } ) + .animate( animation, options.duration, options.easing, function() { + transfer.remove(); + if ( typeof done === "function" ) { + done(); + } + } ); + } +} ); + +function parseClip( str, element ) { + var outerWidth = element.outerWidth(), + outerHeight = element.outerHeight(), + clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/, + values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ]; + + return { + top: parseFloat( values[ 1 ] ) || 0, + right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ), + bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ), + left: parseFloat( values[ 4 ] ) || 0 + }; +} + +$.fx.step.clip = function( fx ) { + if ( !fx.clipInit ) { + fx.start = $( fx.elem ).cssClip(); + if ( typeof fx.end === "string" ) { + fx.end = parseClip( fx.end, fx.elem ); + } + fx.clipInit = true; + } + + $( fx.elem ).cssClip( { + top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top, + right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right, + bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom, + left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left + } ); +}; + +} )(); + +/******************************************************************************/ +/*********************************** EASING ***********************************/ +/******************************************************************************/ + +( function() { + +// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing) + +var baseEasings = {}; + +$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) { + baseEasings[ name ] = function( p ) { + return Math.pow( p, i + 2 ); + }; +} ); + +$.extend( baseEasings, { + Sine: function( p ) { + return 1 - Math.cos( p * Math.PI / 2 ); + }, + Circ: function( p ) { + return 1 - Math.sqrt( 1 - p * p ); + }, + Elastic: function( p ) { + return p === 0 || p === 1 ? p : + -Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 ); + }, + Back: function( p ) { + return p * p * ( 3 * p - 2 ); + }, + Bounce: function( p ) { + var pow2, + bounce = 4; + + while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {} + return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 ); + } +} ); + +$.each( baseEasings, function( name, easeIn ) { + $.easing[ "easeIn" + name ] = easeIn; + $.easing[ "easeOut" + name ] = function( p ) { + return 1 - easeIn( 1 - p ); + }; + $.easing[ "easeInOut" + name ] = function( p ) { + return p < 0.5 ? + easeIn( p * 2 ) / 2 : + 1 - easeIn( p * -2 + 2 ) / 2; + }; +} ); + +} )(); + +var effect = $.effects; + + +/*! + * jQuery UI Effects Blind 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Blind Effect +//>>group: Effects +//>>description: Blinds the element. +//>>docs: http://api.jqueryui.com/blind-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) { + var map = { + up: [ "bottom", "top" ], + vertical: [ "bottom", "top" ], + down: [ "top", "bottom" ], + left: [ "right", "left" ], + horizontal: [ "right", "left" ], + right: [ "left", "right" ] + }, + element = $( this ), + direction = options.direction || "up", + start = element.cssClip(), + animate = { clip: $.extend( {}, start ) }, + placeholder = $.effects.createPlaceholder( element ); + + animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ]; + + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + if ( placeholder ) { + placeholder.css( $.effects.clipToBox( animate ) ); + } + + animate.clip = start; + } + + if ( placeholder ) { + placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing ); + } + + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Bounce 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Bounce Effect +//>>group: Effects +//>>description: Bounces an element horizontally or vertically n times. +//>>docs: http://api.jqueryui.com/bounce-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) { + var upAnim, downAnim, refValue, + element = $( this ), + + // Defaults: + mode = options.mode, + hide = mode === "hide", + show = mode === "show", + direction = options.direction || "up", + distance = options.distance, + times = options.times || 5, + + // Number of internal animations + anims = times * 2 + ( show || hide ? 1 : 0 ), + speed = options.duration / anims, + easing = options.easing, + + // Utility: + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ), + i = 0, + + queuelen = element.queue().length; + + $.effects.createPlaceholder( element ); + + refValue = element.css( ref ); + + // Default distance for the BIGGEST bounce is the outer Distance / 3 + if ( !distance ) { + distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3; + } + + if ( show ) { + downAnim = { opacity: 1 }; + downAnim[ ref ] = refValue; + + // If we are showing, force opacity 0 and set the initial position + // then do the "first" animation + element + .css( "opacity", 0 ) + .css( ref, motion ? -distance * 2 : distance * 2 ) + .animate( downAnim, speed, easing ); + } + + // Start at the smallest distance if we are hiding + if ( hide ) { + distance = distance / Math.pow( 2, times - 1 ); + } + + downAnim = {}; + downAnim[ ref ] = refValue; + + // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here + for ( ; i < times; i++ ) { + upAnim = {}; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + element + .animate( upAnim, speed, easing ) + .animate( downAnim, speed, easing ); + + distance = hide ? distance * 2 : distance / 2; + } + + // Last Bounce when Hiding + if ( hide ) { + upAnim = { opacity: 0 }; + upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance; + + element.animate( upAnim, speed, easing ); + } + + element.queue( done ); + + $.effects.unshift( element, queuelen, anims + 1 ); +} ); + + +/*! + * jQuery UI Effects Clip 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Clip Effect +//>>group: Effects +//>>description: Clips the element on and off like an old TV. +//>>docs: http://api.jqueryui.com/clip-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) { + var start, + animate = {}, + element = $( this ), + direction = options.direction || "vertical", + both = direction === "both", + horizontal = both || direction === "horizontal", + vertical = both || direction === "vertical"; + + start = element.cssClip(); + animate.clip = { + top: vertical ? ( start.bottom - start.top ) / 2 : start.top, + right: horizontal ? ( start.right - start.left ) / 2 : start.right, + bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom, + left: horizontal ? ( start.right - start.left ) / 2 : start.left + }; + + $.effects.createPlaceholder( element ); + + if ( options.mode === "show" ) { + element.cssClip( animate.clip ); + animate.clip = start; + } + + element.animate( animate, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); + +} ); + + +/*! + * jQuery UI Effects Drop 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Drop Effect +//>>group: Effects +//>>description: Moves an element in one direction and hides it at the same time. +//>>docs: http://api.jqueryui.com/drop-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) { + + var distance, + element = $( this ), + mode = options.mode, + show = mode === "show", + direction = options.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=", + oppositeMotion = ( motion === "+=" ) ? "-=" : "+=", + animation = { + opacity: 0 + }; + + $.effects.createPlaceholder( element ); + + distance = options.distance || + element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2; + + animation[ ref ] = motion + distance; + + if ( show ) { + element.css( animation ); + + animation[ ref ] = oppositeMotion + distance; + animation.opacity = 1; + } + + // Animate + element.animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Explode 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Explode Effect +//>>group: Effects +/* eslint-disable max-len */ +//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness. +/* eslint-enable max-len */ +//>>docs: http://api.jqueryui.com/explode-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) { + + var i, j, left, top, mx, my, + rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3, + cells = rows, + element = $( this ), + mode = options.mode, + show = mode === "show", + + // Show and then visibility:hidden the element before calculating offset + offset = element.show().css( "visibility", "hidden" ).offset(), + + // Width and height of a piece + width = Math.ceil( element.outerWidth() / cells ), + height = Math.ceil( element.outerHeight() / rows ), + pieces = []; + + // Children animate complete: + function childComplete() { + pieces.push( this ); + if ( pieces.length === rows * cells ) { + animComplete(); + } + } + + // Clone the element for each row and cell. + for ( i = 0; i < rows; i++ ) { // ===> + top = offset.top + i * height; + my = i - ( rows - 1 ) / 2; + + for ( j = 0; j < cells; j++ ) { // ||| + left = offset.left + j * width; + mx = j - ( cells - 1 ) / 2; + + // Create a clone of the now hidden main element that will be absolute positioned + // within a wrapper div off the -left and -top equal to size of our pieces + element + .clone() + .appendTo( "body" ) + .wrap( "
" ) + .css( { + position: "absolute", + visibility: "visible", + left: -j * width, + top: -i * height + } ) + + // Select the wrapper - make it overflow: hidden and absolute positioned based on + // where the original was located +left and +top equal to the size of pieces + .parent() + .addClass( "ui-effects-explode" ) + .css( { + position: "absolute", + overflow: "hidden", + width: width, + height: height, + left: left + ( show ? mx * width : 0 ), + top: top + ( show ? my * height : 0 ), + opacity: show ? 0 : 1 + } ) + .animate( { + left: left + ( show ? 0 : mx * width ), + top: top + ( show ? 0 : my * height ), + opacity: show ? 1 : 0 + }, options.duration || 500, options.easing, childComplete ); + } + } + + function animComplete() { + element.css( { + visibility: "visible" + } ); + $( pieces ).remove(); + done(); + } +} ); + + +/*! + * jQuery UI Effects Fade 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Fade Effect +//>>group: Effects +//>>description: Fades the element. +//>>docs: http://api.jqueryui.com/fade-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) { + var show = options.mode === "show"; + + $( this ) + .css( "opacity", show ? 0 : 1 ) + .animate( { + opacity: show ? 1 : 0 + }, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Fold 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Fold Effect +//>>group: Effects +//>>description: Folds an element first horizontally and then vertically. +//>>docs: http://api.jqueryui.com/fold-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) { + + // Create element + var element = $( this ), + mode = options.mode, + show = mode === "show", + hide = mode === "hide", + size = options.size || 15, + percent = /([0-9]+)%/.exec( size ), + horizFirst = !!options.horizFirst, + ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ], + duration = options.duration / 2, + + placeholder = $.effects.createPlaceholder( element ), + + start = element.cssClip(), + animation1 = { clip: $.extend( {}, start ) }, + animation2 = { clip: $.extend( {}, start ) }, + + distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ], + + queuelen = element.queue().length; + + if ( percent ) { + size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ]; + } + animation1.clip[ ref[ 0 ] ] = size; + animation2.clip[ ref[ 0 ] ] = size; + animation2.clip[ ref[ 1 ] ] = 0; + + if ( show ) { + element.cssClip( animation2.clip ); + if ( placeholder ) { + placeholder.css( $.effects.clipToBox( animation2 ) ); + } + + animation2.clip = start; + } + + // Animate + element + .queue( function( next ) { + if ( placeholder ) { + placeholder + .animate( $.effects.clipToBox( animation1 ), duration, options.easing ) + .animate( $.effects.clipToBox( animation2 ), duration, options.easing ); + } + + next(); + } ) + .animate( animation1, duration, options.easing ) + .animate( animation2, duration, options.easing ) + .queue( done ); + + $.effects.unshift( element, queuelen, 4 ); +} ); + + +/*! + * jQuery UI Effects Highlight 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Highlight Effect +//>>group: Effects +//>>description: Highlights the background of an element in a defined color for a custom duration. +//>>docs: http://api.jqueryui.com/highlight-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) { + var element = $( this ), + animation = { + backgroundColor: element.css( "backgroundColor" ) + }; + + if ( options.mode === "hide" ) { + animation.opacity = 0; + } + + $.effects.saveStyle( element ); + + element + .css( { + backgroundImage: "none", + backgroundColor: options.color || "#ffff99" + } ) + .animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Size 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Size Effect +//>>group: Effects +//>>description: Resize an element to a specified width and height. +//>>docs: http://api.jqueryui.com/size-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectSize = $.effects.define( "size", function( options, done ) { + + // Create element + var baseline, factor, temp, + element = $( this ), + + // Copy for children + cProps = [ "fontSize" ], + vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ], + hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ], + + // Set options + mode = options.mode, + restore = mode !== "effect", + scale = options.scale || "both", + origin = options.origin || [ "middle", "center" ], + position = element.css( "position" ), + pos = element.position(), + original = $.effects.scaledDimensions( element ), + from = options.from || original, + to = options.to || $.effects.scaledDimensions( element, 0 ); + + $.effects.createPlaceholder( element ); + + if ( mode === "show" ) { + temp = from; + from = to; + to = temp; + } + + // Set scaling factor + factor = { + from: { + y: from.height / original.height, + x: from.width / original.width + }, + to: { + y: to.height / original.height, + x: to.width / original.width + } + }; + + // Scale the css box + if ( scale === "box" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + from = $.effects.setTransition( element, vProps, factor.from.y, from ); + to = $.effects.setTransition( element, vProps, factor.to.y, to ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + from = $.effects.setTransition( element, hProps, factor.from.x, from ); + to = $.effects.setTransition( element, hProps, factor.to.x, to ); + } + } + + // Scale the content + if ( scale === "content" || scale === "both" ) { + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + from = $.effects.setTransition( element, cProps, factor.from.y, from ); + to = $.effects.setTransition( element, cProps, factor.to.y, to ); + } + } + + // Adjust the position properties based on the provided origin points + if ( origin ) { + baseline = $.effects.getBaseline( origin, original ); + from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top; + from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left; + to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top; + to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left; + } + delete from.outerHeight; + delete from.outerWidth; + element.css( from ); + + // Animate the children if desired + if ( scale === "content" || scale === "both" ) { + + vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps ); + hProps = hProps.concat( [ "marginLeft", "marginRight" ] ); + + // Only animate children with width attributes specified + // TODO: is this right? should we include anything with css width specified as well + element.find( "*[width]" ).each( function() { + var child = $( this ), + childOriginal = $.effects.scaledDimensions( child ), + childFrom = { + height: childOriginal.height * factor.from.y, + width: childOriginal.width * factor.from.x, + outerHeight: childOriginal.outerHeight * factor.from.y, + outerWidth: childOriginal.outerWidth * factor.from.x + }, + childTo = { + height: childOriginal.height * factor.to.y, + width: childOriginal.width * factor.to.x, + outerHeight: childOriginal.height * factor.to.y, + outerWidth: childOriginal.width * factor.to.x + }; + + // Vertical props scaling + if ( factor.from.y !== factor.to.y ) { + childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom ); + childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo ); + } + + // Horizontal props scaling + if ( factor.from.x !== factor.to.x ) { + childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom ); + childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo ); + } + + if ( restore ) { + $.effects.saveStyle( child ); + } + + // Animate children + child.css( childFrom ); + child.animate( childTo, options.duration, options.easing, function() { + + // Restore children + if ( restore ) { + $.effects.restoreStyle( child ); + } + } ); + } ); + } + + // Animate + element.animate( to, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: function() { + + var offset = element.offset(); + + if ( to.opacity === 0 ) { + element.css( "opacity", from.opacity ); + } + + if ( !restore ) { + element + .css( "position", position === "static" ? "relative" : position ) + .offset( offset ); + + // Need to save style here so that automatic style restoration + // doesn't restore to the original styles from before the animation. + $.effects.saveStyle( element ); + } + + done(); + } + } ); + +} ); + + +/*! + * jQuery UI Effects Scale 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Scale Effect +//>>group: Effects +//>>description: Grows or shrinks an element and its content. +//>>docs: http://api.jqueryui.com/scale-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectScale = $.effects.define( "scale", function( options, done ) { + + // Create element + var el = $( this ), + mode = options.mode, + percent = parseInt( options.percent, 10 ) || + ( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ), + + newOptions = $.extend( true, { + from: $.effects.scaledDimensions( el ), + to: $.effects.scaledDimensions( el, percent, options.direction || "both" ), + origin: options.origin || [ "middle", "center" ] + }, options ); + + // Fade option to support puff + if ( options.fade ) { + newOptions.from.opacity = 1; + newOptions.to.opacity = 0; + } + + $.effects.effect.size.call( this, newOptions, done ); +} ); + + +/*! + * jQuery UI Effects Puff 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Puff Effect +//>>group: Effects +//>>description: Creates a puff effect by scaling the element up and hiding it at the same time. +//>>docs: http://api.jqueryui.com/puff-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) { + var newOptions = $.extend( true, {}, options, { + fade: true, + percent: parseInt( options.percent, 10 ) || 150 + } ); + + $.effects.effect.scale.call( this, newOptions, done ); +} ); + + +/*! + * jQuery UI Effects Pulsate 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Pulsate Effect +//>>group: Effects +//>>description: Pulsates an element n times by changing the opacity to zero and back. +//>>docs: http://api.jqueryui.com/pulsate-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) { + var element = $( this ), + mode = options.mode, + show = mode === "show", + hide = mode === "hide", + showhide = show || hide, + + // Showing or hiding leaves off the "last" animation + anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ), + duration = options.duration / anims, + animateTo = 0, + i = 1, + queuelen = element.queue().length; + + if ( show || !element.is( ":visible" ) ) { + element.css( "opacity", 0 ).show(); + animateTo = 1; + } + + // Anims - 1 opacity "toggles" + for ( ; i < anims; i++ ) { + element.animate( { opacity: animateTo }, duration, options.easing ); + animateTo = 1 - animateTo; + } + + element.animate( { opacity: animateTo }, duration, options.easing ); + + element.queue( done ); + + $.effects.unshift( element, queuelen, anims + 1 ); +} ); + + +/*! + * jQuery UI Effects Shake 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Shake Effect +//>>group: Effects +//>>description: Shakes an element horizontally or vertically n times. +//>>docs: http://api.jqueryui.com/shake-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectShake = $.effects.define( "shake", function( options, done ) { + + var i = 1, + element = $( this ), + direction = options.direction || "left", + distance = options.distance || 20, + times = options.times || 3, + anims = times * 2 + 1, + speed = Math.round( options.duration / anims ), + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + positiveMotion = ( direction === "up" || direction === "left" ), + animation = {}, + animation1 = {}, + animation2 = {}, + + queuelen = element.queue().length; + + $.effects.createPlaceholder( element ); + + // Animation + animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance; + animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2; + animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2; + + // Animate + element.animate( animation, speed, options.easing ); + + // Shakes + for ( ; i < times; i++ ) { + element + .animate( animation1, speed, options.easing ) + .animate( animation2, speed, options.easing ); + } + + element + .animate( animation1, speed, options.easing ) + .animate( animation, speed / 2, options.easing ) + .queue( done ); + + $.effects.unshift( element, queuelen, anims + 1 ); +} ); + + +/*! + * jQuery UI Effects Slide 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Slide Effect +//>>group: Effects +//>>description: Slides an element in and out of the viewport. +//>>docs: http://api.jqueryui.com/slide-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) { + var startClip, startRef, + element = $( this ), + map = { + up: [ "bottom", "top" ], + down: [ "top", "bottom" ], + left: [ "right", "left" ], + right: [ "left", "right" ] + }, + mode = options.mode, + direction = options.direction || "left", + ref = ( direction === "up" || direction === "down" ) ? "top" : "left", + positiveMotion = ( direction === "up" || direction === "left" ), + distance = options.distance || + element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ), + animation = {}; + + $.effects.createPlaceholder( element ); + + startClip = element.cssClip(); + startRef = element.position()[ ref ]; + + // Define hide animation + animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef; + animation.clip = element.cssClip(); + animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ]; + + // Reverse the animation if we're showing + if ( mode === "show" ) { + element.cssClip( animation.clip ); + element.css( ref, animation[ ref ] ); + animation.clip = startClip; + animation[ ref ] = startRef; + } + + // Actually animate + element.animate( animation, { + queue: false, + duration: options.duration, + easing: options.easing, + complete: done + } ); +} ); + + +/*! + * jQuery UI Effects Transfer 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Transfer Effect +//>>group: Effects +//>>description: Displays a transfer effect from one element to another. +//>>docs: http://api.jqueryui.com/transfer-effect/ +//>>demos: http://jqueryui.com/effect/ + + +var effect; +if ( $.uiBackCompat !== false ) { + effect = $.effects.define( "transfer", function( options, done ) { + $( this ).transfer( options, done ); + } ); +} +var effectsEffectTransfer = effect; + + +/*! + * jQuery UI Focusable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: :focusable Selector +//>>group: Core +//>>description: Selects elements which can be focused. +//>>docs: http://api.jqueryui.com/focusable-selector/ + + +// Selectors +$.ui.focusable = function( element, hasTabindex ) { + var map, mapName, img, focusableIfVisible, fieldset, + nodeName = element.nodeName.toLowerCase(); + + if ( "area" === nodeName ) { + map = element.parentNode; + mapName = map.name; + if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { + return false; + } + img = $( "img[usemap='#" + mapName + "']" ); + return img.length > 0 && img.is( ":visible" ); + } + + if ( /^(input|select|textarea|button|object)$/.test( nodeName ) ) { + focusableIfVisible = !element.disabled; + + if ( focusableIfVisible ) { + + // Form controls within a disabled fieldset are disabled. + // However, controls within the fieldset's legend do not get disabled. + // Since controls generally aren't placed inside legends, we skip + // this portion of the check. + fieldset = $( element ).closest( "fieldset" )[ 0 ]; + if ( fieldset ) { + focusableIfVisible = !fieldset.disabled; + } + } + } else if ( "a" === nodeName ) { + focusableIfVisible = element.href || hasTabindex; + } else { + focusableIfVisible = hasTabindex; + } + + return focusableIfVisible && $( element ).is( ":visible" ) && visible( $( element ) ); +}; + +// Support: IE 8 only +// IE 8 doesn't resolve inherit to visible/hidden for computed values +function visible( element ) { + var visibility = element.css( "visibility" ); + while ( visibility === "inherit" ) { + element = element.parent(); + visibility = element.css( "visibility" ); + } + return visibility === "visible"; +} + +$.extend( $.expr.pseudos, { + focusable: function( element ) { + return $.ui.focusable( element, $.attr( element, "tabindex" ) != null ); + } +} ); + +var focusable = $.ui.focusable; + + + +// Support: IE8 Only +// IE8 does not support the form attribute and when it is supplied. It overwrites the form prop +// with a string, so we need to find the proper form. +var form = $.fn._form = function() { + return typeof this[ 0 ].form === "string" ? this.closest( "form" ) : $( this[ 0 ].form ); +}; + + +/*! + * jQuery UI Form Reset Mixin 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Form Reset Mixin +//>>group: Core +//>>description: Refresh input widgets when their form is reset +//>>docs: http://api.jqueryui.com/form-reset-mixin/ + + +var formResetMixin = $.ui.formResetMixin = { + _formResetHandler: function() { + var form = $( this ); + + // Wait for the form reset to actually happen before refreshing + setTimeout( function() { + var instances = form.data( "ui-form-reset-instances" ); + $.each( instances, function() { + this.refresh(); + } ); + } ); + }, + + _bindFormResetHandler: function() { + this.form = this.element._form(); + if ( !this.form.length ) { + return; + } + + var instances = this.form.data( "ui-form-reset-instances" ) || []; + if ( !instances.length ) { + + // We don't use _on() here because we use a single event handler per form + this.form.on( "reset.ui-form-reset", this._formResetHandler ); + } + instances.push( this ); + this.form.data( "ui-form-reset-instances", instances ); + }, + + _unbindFormResetHandler: function() { + if ( !this.form.length ) { + return; + } + + var instances = this.form.data( "ui-form-reset-instances" ); + instances.splice( $.inArray( this, instances ), 1 ); + if ( instances.length ) { + this.form.data( "ui-form-reset-instances", instances ); + } else { + this.form + .removeData( "ui-form-reset-instances" ) + .off( "reset.ui-form-reset" ); + } + } +}; + + +/*! + * jQuery UI Support for jQuery core 1.8.x and newer 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + */ + +//>>label: jQuery 1.8+ Support +//>>group: Core +//>>description: Support version 1.8.x and newer of jQuery core + + +// Support: jQuery 1.9.x or older +// $.expr[ ":" ] is deprecated. +if ( !$.expr.pseudos ) { + $.expr.pseudos = $.expr[ ":" ]; +} + +// Support: jQuery 1.11.x or older +// $.unique has been renamed to $.uniqueSort +if ( !$.uniqueSort ) { + $.uniqueSort = $.unique; +} + +// Support: jQuery 2.2.x or older. +// This method has been defined in jQuery 3.0.0. +// Code from https://github.com/jquery/jquery/blob/e539bac79e666bba95bba86d690b4e609dca2286/src/selector/escapeSelector.js +if ( !$.escapeSelector ) { + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g; + + var fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }; + + $.escapeSelector = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); + }; +} + +// Support: jQuery 3.4.x or older +// These methods have been defined in jQuery 3.5.0. +if ( !$.fn.even || !$.fn.odd ) { + $.fn.extend( { + even: function() { + return this.filter( function( i ) { + return i % 2 === 0; + } ); + }, + odd: function() { + return this.filter( function( i ) { + return i % 2 === 1; + } ); + } + } ); +} + +; +/*! + * jQuery UI Keycode 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Keycode +//>>group: Core +//>>description: Provide keycodes as keynames +//>>docs: http://api.jqueryui.com/jQuery.ui.keyCode/ + + +var keycode = $.ui.keyCode = { + BACKSPACE: 8, + COMMA: 188, + DELETE: 46, + DOWN: 40, + END: 35, + ENTER: 13, + ESCAPE: 27, + HOME: 36, + LEFT: 37, + PAGE_DOWN: 34, + PAGE_UP: 33, + PERIOD: 190, + RIGHT: 39, + SPACE: 32, + TAB: 9, + UP: 38 +}; + + +/*! + * jQuery UI Labels 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: labels +//>>group: Core +//>>description: Find all the labels associated with a given input +//>>docs: http://api.jqueryui.com/labels/ + + +var labels = $.fn.labels = function() { + var ancestor, selector, id, labels, ancestors; + + if ( !this.length ) { + return this.pushStack( [] ); + } + + // Check control.labels first + if ( this[ 0 ].labels && this[ 0 ].labels.length ) { + return this.pushStack( this[ 0 ].labels ); + } + + // Support: IE <= 11, FF <= 37, Android <= 2.3 only + // Above browsers do not support control.labels. Everything below is to support them + // as well as document fragments. control.labels does not work on document fragments + labels = this.eq( 0 ).parents( "label" ); + + // Look for the label based on the id + id = this.attr( "id" ); + if ( id ) { + + // We don't search against the document in case the element + // is disconnected from the DOM + ancestor = this.eq( 0 ).parents().last(); + + // Get a full set of top level ancestors + ancestors = ancestor.add( ancestor.length ? ancestor.siblings() : this.siblings() ); + + // Create a selector for the label based on the id + selector = "label[for='" + $.escapeSelector( id ) + "']"; + + labels = labels.add( ancestors.find( selector ).addBack( selector ) ); + + } + + // Return whatever we have found for labels + return this.pushStack( labels ); +}; + + +/*! + * jQuery UI Scroll Parent 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: scrollParent +//>>group: Core +//>>description: Get the closest ancestor element that is scrollable. +//>>docs: http://api.jqueryui.com/scrollParent/ + + +var scrollParent = $.fn.scrollParent = function( includeHidden ) { + var position = this.css( "position" ), + excludeStaticParent = position === "absolute", + overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, + scrollParent = this.parents().filter( function() { + var parent = $( this ); + if ( excludeStaticParent && parent.css( "position" ) === "static" ) { + return false; + } + return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + + parent.css( "overflow-x" ) ); + } ).eq( 0 ); + + return position === "fixed" || !scrollParent.length ? + $( this[ 0 ].ownerDocument || document ) : + scrollParent; +}; + + +/*! + * jQuery UI Tabbable 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: :tabbable Selector +//>>group: Core +//>>description: Selects elements which can be tabbed to. +//>>docs: http://api.jqueryui.com/tabbable-selector/ + + +var tabbable = $.extend( $.expr.pseudos, { + tabbable: function( element ) { + var tabIndex = $.attr( element, "tabindex" ), + hasTabindex = tabIndex != null; + return ( !hasTabindex || tabIndex >= 0 ) && $.ui.focusable( element, hasTabindex ); + } +} ); + + +/*! + * jQuery UI Unique ID 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: uniqueId +//>>group: Core +//>>description: Functions to generate and remove uniqueId's +//>>docs: http://api.jqueryui.com/uniqueId/ + + +var uniqueId = $.fn.extend( { + uniqueId: ( function() { + var uuid = 0; + + return function() { + return this.each( function() { + if ( !this.id ) { + this.id = "ui-id-" + ( ++uuid ); + } + } ); + }; + } )(), + + removeUniqueId: function() { + return this.each( function() { + if ( /^ui-id-\d+$/.test( this.id ) ) { + $( this ).removeAttr( "id" ); + } + } ); + } +} ); + + +/*! + * jQuery UI Accordion 1.13.2 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ + +//>>label: Accordion +//>>group: Widgets +/* eslint-disable max-len */ +//>>description: Displays collapsible content panels for presenting information in a limited amount of space. +/* eslint-enable max-len */ +//>>docs: http://api.jqueryui.com/accordion/ +//>>demos: http://jqueryui.com/accordion/ +//>>css.structure: ../../themes/base/core.css +//>>css.structure: ../../themes/base/accordion.css +//>>css.theme: ../../themes/base/theme.css + + +var widgetsAccordion = $.widget( "ui.accordion", { + version: "1.13.2", + options: { + active: 0, + animate: {}, + classes: { + "ui-accordion-header": "ui-corner-top", + "ui-accordion-header-collapsed": "ui-corner-all", + "ui-accordion-content": "ui-corner-bottom" + }, + collapsible: false, + event: "click", + header: function( elem ) { + return elem.find( "> li > :first-child" ).add( elem.find( "> :not(li)" ).even() ); + }, + heightStyle: "auto", + icons: { + activeHeader: "ui-icon-triangle-1-s", + header: "ui-icon-triangle-1-e" + }, + + // Callbacks + activate: null, + beforeActivate: null + }, + + hideProps: { + borderTopWidth: "hide", + borderBottomWidth: "hide", + paddingTop: "hide", + paddingBottom: "hide", + height: "hide" + }, + + showProps: { + borderTopWidth: "show", + borderBottomWidth: "show", + paddingTop: "show", + paddingBottom: "show", + height: "show" + }, + + _create: function() { + var options = this.options; + + this.prevShow = this.prevHide = $(); + this._addClass( "ui-accordion", "ui-widget ui-helper-reset" ); + this.element.attr( "role", "tablist" ); + + // Don't allow collapsible: false and active: false / null + if ( !options.collapsible && ( options.active === false || options.active == null ) ) { + options.active = 0; + } + + this._processPanels(); + + // handle negative values + if ( options.active < 0 ) { + options.active += this.headers.length; + } + this._refresh(); + }, + + _getCreateEventData: function() { + return { + header: this.active, + panel: !this.active.length ? $() : this.active.next() + }; + }, + + _createIcons: function() { + var icon, children, + icons = this.options.icons; + + if ( icons ) { + icon = $( "" ); + this._addClass( icon, "ui-accordion-header-icon", "ui-icon " + icons.header ); + icon.prependTo( this.headers ); + children = this.active.children( ".ui-accordion-header-icon" ); + this._removeClass( children, icons.header ) + ._addClass( children, null, icons.activeHeader ) + ._addClass( this.headers, "ui-accordion-icons" ); + } + }, + + _destroyIcons: function() { + this._removeClass( this.headers, "ui-accordion-icons" ); + this.headers.children( ".ui-accordion-header-icon" ).remove(); + }, + + _destroy: function() { + var contents; + + // Clean up main element + this.element.removeAttr( "role" ); + + // Clean up headers + this.headers + .removeAttr( "role aria-expanded aria-selected aria-controls tabIndex" ) + .removeUniqueId(); + + this._destroyIcons(); + + // Clean up content panels + contents = this.headers.next() + .css( "display", "" ) + .removeAttr( "role aria-hidden aria-labelledby" ) + .removeUniqueId(); + + if ( this.options.heightStyle !== "content" ) { + contents.css( "height", "" ); + } + }, + + _setOption: function( key, value ) { + if ( key === "active" ) { + + // _activate() will handle invalid values and update this.options + this._activate( value ); + return; + } + + if ( key === "event" ) { + if ( this.options.event ) { + this._off( this.headers, this.options.event ); + } + this._setupEvents( value ); + } + + this._super( key, value ); + + // Setting collapsible: false while collapsed; open first panel + if ( key === "collapsible" && !value && this.options.active === false ) { + this._activate( 0 ); + } + + if ( key === "icons" ) { + this._destroyIcons(); + if ( value ) { + this._createIcons(); + } + } + }, + + _setOptionDisabled: function( value ) { + this._super( value ); + + this.element.attr( "aria-disabled", value ); + + // Support: IE8 Only + // #5332 / #6059 - opacity doesn't cascade to positioned elements in IE + // so we need to add the disabled class to the headers and panels + this._toggleClass( null, "ui-state-disabled", !!value ); + this._toggleClass( this.headers.add( this.headers.next() ), null, "ui-state-disabled", + !!value ); + }, + + _keydown: function( event ) { + if ( event.altKey || event.ctrlKey ) { + return; + } + + var keyCode = $.ui.keyCode, + length = this.headers.length, + currentIndex = this.headers.index( event.target ), + toFocus = false; + + switch ( event.keyCode ) { + case keyCode.RIGHT: + case keyCode.DOWN: + toFocus = this.headers[ ( currentIndex + 1 ) % length ]; + break; + case keyCode.LEFT: + case keyCode.UP: + toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; + break; + case keyCode.SPACE: + case keyCode.ENTER: + this._eventHandler( event ); + break; + case keyCode.HOME: + toFocus = this.headers[ 0 ]; + break; + case keyCode.END: + toFocus = this.headers[ length - 1 ]; + break; + } + + if ( toFocus ) { + $( event.target ).attr( "tabIndex", -1 ); + $( toFocus ).attr( "tabIndex", 0 ); + $( toFocus ).trigger( "focus" ); + event.preventDefault(); + } + }, + + _panelKeyDown: function( event ) { + if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { + $( event.currentTarget ).prev().trigger( "focus" ); + } + }, + + refresh: function() { + var options = this.options; + this._processPanels(); + + // Was collapsed or no panel + if ( ( options.active === false && options.collapsible === true ) || + !this.headers.length ) { + options.active = false; + this.active = $(); + + // active false only when collapsible is true + } else if ( options.active === false ) { + this._activate( 0 ); + + // was active, but active panel is gone + } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { + + // all remaining panel are disabled + if ( this.headers.length === this.headers.find( ".ui-state-disabled" ).length ) { + options.active = false; + this.active = $(); + + // activate previous panel + } else { + this._activate( Math.max( 0, options.active - 1 ) ); + } + + // was active, active panel still exists + } else { + + // make sure active index is correct + options.active = this.headers.index( this.active ); + } + + this._destroyIcons(); + + this._refresh(); + }, + + _processPanels: function() { + var prevHeaders = this.headers, + prevPanels = this.panels; + + if ( typeof this.options.header === "function" ) { + this.headers = this.options.header( this.element ); + } else { + this.headers = this.element.find( this.options.header ); + } + this._addClass( this.headers, "ui-accordion-header ui-accordion-header-collapsed", + "ui-state-default" ); + + this.panels = this.headers.next().filter( ":not(.ui-accordion-content-active)" ).hide(); + this._addClass( this.panels, "ui-accordion-content", "ui-helper-reset ui-widget-content" ); + + // Avoid memory leaks (#10056) + if ( prevPanels ) { + this._off( prevHeaders.not( this.headers ) ); + this._off( prevPanels.not( this.panels ) ); + } + }, + + _refresh: function() { + var maxHeight, + options = this.options, + heightStyle = options.heightStyle, + parent = this.element.parent(); + + this.active = this._findActive( options.active ); + this._addClass( this.active, "ui-accordion-header-active", "ui-state-active" ) + ._removeClass( this.active, "ui-accordion-header-collapsed" ); + this._addClass( this.active.next(), "ui-accordion-content-active" ); + this.active.next().show(); + + this.headers + .attr( "role", "tab" ) + .each( function() { + var header = $( this ), + headerId = header.uniqueId().attr( "id" ), + panel = header.next(), + panelId = panel.uniqueId().attr( "id" ); + header.attr( "aria-controls", panelId ); + panel.attr( "aria-labelledby", headerId ); + } ) + .next() + .attr( "role", "tabpanel" ); + + this.headers + .not( this.active ) + .attr( { + "aria-selected": "false", + "aria-expanded": "false", + tabIndex: -1 + } ) + .next() + .attr( { + "aria-hidden": "true" + } ) + .hide(); + + // Make sure at least one header is in the tab order + if ( !this.active.length ) { + this.headers.eq( 0 ).attr( "tabIndex", 0 ); + } else { + this.active.attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ) + .next() + .attr( { + "aria-hidden": "false" + } ); + } + + this._createIcons(); + + this._setupEvents( options.event ); + + if ( heightStyle === "fill" ) { + maxHeight = parent.height(); + this.element.siblings( ":visible" ).each( function() { + var elem = $( this ), + position = elem.css( "position" ); + + if ( position === "absolute" || position === "fixed" ) { + return; + } + maxHeight -= elem.outerHeight( true ); + } ); + + this.headers.each( function() { + maxHeight -= $( this ).outerHeight( true ); + } ); + + this.headers.next() + .each( function() { + $( this ).height( Math.max( 0, maxHeight - + $( this ).innerHeight() + $( this ).height() ) ); + } ) + .css( "overflow", "auto" ); + } else if ( heightStyle === "auto" ) { + maxHeight = 0; + this.headers.next() + .each( function() { + var isVisible = $( this ).is( ":visible" ); + if ( !isVisible ) { + $( this ).show(); + } + maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); + if ( !isVisible ) { + $( this ).hide(); + } + } ) + .height( maxHeight ); + } + }, + + _activate: function( index ) { + var active = this._findActive( index )[ 0 ]; + + // Trying to activate the already active panel + if ( active === this.active[ 0 ] ) { + return; + } + + // Trying to collapse, simulate a click on the currently active header + active = active || this.active[ 0 ]; + + this._eventHandler( { + target: active, + currentTarget: active, + preventDefault: $.noop + } ); + }, + + _findActive: function( selector ) { + return typeof selector === "number" ? this.headers.eq( selector ) : $(); + }, + + _setupEvents: function( event ) { + var events = { + keydown: "_keydown" + }; + if ( event ) { + $.each( event.split( " " ), function( index, eventName ) { + events[ eventName ] = "_eventHandler"; + } ); + } + + this._off( this.headers.add( this.headers.next() ) ); + this._on( this.headers, events ); + this._on( this.headers.next(), { keydown: "_panelKeyDown" } ); + this._hoverable( this.headers ); + this._focusable( this.headers ); + }, + + _eventHandler: function( event ) { + var activeChildren, clickedChildren, + options = this.options, + active = this.active, + clicked = $( event.currentTarget ), + clickedIsActive = clicked[ 0 ] === active[ 0 ], + collapsing = clickedIsActive && options.collapsible, + toShow = collapsing ? $() : clicked.next(), + toHide = active.next(), + eventData = { + oldHeader: active, + oldPanel: toHide, + newHeader: collapsing ? $() : clicked, + newPanel: toShow + }; + + event.preventDefault(); + + if ( + + // click on active header, but not collapsible + ( clickedIsActive && !options.collapsible ) || + + // allow canceling activation + ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { + return; + } + + options.active = collapsing ? false : this.headers.index( clicked ); + + // When the call to ._toggle() comes after the class changes + // it causes a very odd bug in IE 8 (see #6720) + this.active = clickedIsActive ? $() : clicked; + this._toggle( eventData ); + + // Switch classes + // corner classes on the previously active header stay after the animation + this._removeClass( active, "ui-accordion-header-active", "ui-state-active" ); + if ( options.icons ) { + activeChildren = active.children( ".ui-accordion-header-icon" ); + this._removeClass( activeChildren, null, options.icons.activeHeader ) + ._addClass( activeChildren, null, options.icons.header ); + } + + if ( !clickedIsActive ) { + this._removeClass( clicked, "ui-accordion-header-collapsed" ) + ._addClass( clicked, "ui-accordion-header-active", "ui-state-active" ); + if ( options.icons ) { + clickedChildren = clicked.children( ".ui-accordion-header-icon" ); + this._removeClass( clickedChildren, null, options.icons.header ) + ._addClass( clickedChildren, null, options.icons.activeHeader ); + } + + this._addClass( clicked.next(), "ui-accordion-content-active" ); + } + }, + + _toggle: function( data ) { + var toShow = data.newPanel, + toHide = this.prevShow.length ? this.prevShow : data.oldPanel; + + // Handle activating a panel during the animation for another activation + this.prevShow.add( this.prevHide ).stop( true, true ); + this.prevShow = toShow; + this.prevHide = toHide; + + if ( this.options.animate ) { + this._animate( toShow, toHide, data ); + } else { + toHide.hide(); + toShow.show(); + this._toggleComplete( data ); + } + + toHide.attr( { + "aria-hidden": "true" + } ); + toHide.prev().attr( { + "aria-selected": "false", + "aria-expanded": "false" + } ); + + // if we're switching panels, remove the old header from the tab order + // if we're opening from collapsed state, remove the previous header from the tab order + // if we're collapsing, then keep the collapsing header in the tab order + if ( toShow.length && toHide.length ) { + toHide.prev().attr( { + "tabIndex": -1, + "aria-expanded": "false" + } ); + } else if ( toShow.length ) { + this.headers.filter( function() { + return parseInt( $( this ).attr( "tabIndex" ), 10 ) === 0; + } ) + .attr( "tabIndex", -1 ); + } + + toShow + .attr( "aria-hidden", "false" ) + .prev() + .attr( { + "aria-selected": "true", + "aria-expanded": "true", + tabIndex: 0 + } ); + }, + + _animate: function( toShow, toHide, data ) { + var total, easing, duration, + that = this, + adjust = 0, + boxSizing = toShow.css( "box-sizing" ), + down = toShow.length && + ( !toHide.length || ( toShow.index() < toHide.index() ) ), + animate = this.options.animate || {}, + options = down && animate.down || animate, + complete = function() { + that._toggleComplete( data ); + }; + + if ( typeof options === "number" ) { + duration = options; + } + if ( typeof options === "string" ) { + easing = options; + } + + // fall back from options to animation in case of partial down settings + easing = easing || options.easing || animate.easing; + duration = duration || options.duration || animate.duration; + + if ( !toHide.length ) { + return toShow.animate( this.showProps, duration, easing, complete ); + } + if ( !toShow.length ) { + return toHide.animate( this.hideProps, duration, easing, complete ); + } + + total = toShow.show().outerHeight(); + toHide.animate( this.hideProps, { + duration: duration, + easing: easing, + step: function( now, fx ) { + fx.now = Math.round( now ); + } + } ); + toShow + .hide() + .animate( this.showProps, { + duration: duration, + easing: easing, + complete: complete, + step: function( now, fx ) { + fx.now = Math.round( now ); + if ( fx.prop !== "height" ) { + if ( boxSizing === "content-box" ) { + adjust += fx.now; + } + } else if ( that.options.heightStyle !== "content" ) { + fx.now = Math.round( total - toHide.outerHeight() - adjust ); + adjust = 0; + } + } + } ); + }, + + _toggleComplete: function( data ) { + var toHide = data.oldPanel, + prev = toHide.prev(); + + this._removeClass( toHide, "ui-accordion-content-active" ); + this._removeClass( prev, "ui-accordion-header-active" ) + ._addClass( prev, "ui-accordion-header-collapsed" ); + + // Work around for rendering bug in IE (#5421) + if ( toHide.length ) { + toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; + } + this._trigger( "activate", null, data ); + } +} ); + + + +var safeActiveElement = $.ui.safeActiveElement = function( document ) { + var activeElement; + + // Support: IE 9 only + // IE9 throws an "Unspecified error" accessing document.activeElement from an