@item.Title
+@item.Description
+ @*Per ea tibique fabellas electram. Ea aliquam corpora vis. Ne quot civibus atomorum quo.
*@ + Read more +diff --git a/StudyDoIT.sln b/StudyDoIT.sln new file mode 100644 index 0000000..0ce54a9 --- /dev/null +++ b/StudyDoIT.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StudyDoIT", "StudyDoIT\StudyDoIT.csproj", "{3498032D-B621-4C2A-ADD1-1219D3ADFE1D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3498032D-B621-4C2A-ADD1-1219D3ADFE1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3498032D-B621-4C2A-ADD1-1219D3ADFE1D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3498032D-B621-4C2A-ADD1-1219D3ADFE1D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3498032D-B621-4C2A-ADD1-1219D3ADFE1D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/StudyDoIT/App_Start/BundleConfig.cs b/StudyDoIT/App_Start/BundleConfig.cs new file mode 100644 index 0000000..4c3bc7f --- /dev/null +++ b/StudyDoIT/App_Start/BundleConfig.cs @@ -0,0 +1,87 @@ +using System.Web; +using System.Web.Optimization; + +namespace StudyDoIT +{ + public class BundleConfig + { + // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 + public static void RegisterBundles(BundleCollection bundles) + { + //bundles.Add(new ScriptBundle("~/bundles/jquery").Include( + // "~/Scripts/jquery-{version}.js")); + bundles.Add(new ScriptBundle("~/bundles/jquery").Include( + "~/Scripts/jquery-{version}.js", + "~/Scripts/js/jquery.min.js")); + + bundles.Add(new ScriptBundle("~/bundles/jquery1").Include( + "~/Scripts/jsadmin/modernizr.js", + "~/Scripts/jsadmin/jquery-2.1.1.min.js", + "~/Scripts/bootstrap.min.js" + )); + + bundles.Add(new ScriptBundle("~/bundles/ajaxform").Include( + "~/Scripts/jquery.unobtrusive-ajax*")); + + bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include( + "~/Scripts/jquery-ui-{version}.js")); + //bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( + // "~/Scripts/jquery.validate*")); + bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( + "~/Scripts/jquery.validate.min.js", + "~/Scripts/jquery.validate.unobtrusive.min.js")); + + // Use the development version of Modernizr to develop with and learn from. Then, when you're + // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. + bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( + "~/Scripts/modernizr-*")); + + //bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( + // "~/Scripts/bootstrap.js", + // "~/Scripts/respond.js")); + + bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( + "~/Scripts/bootstrap.js", + "~/Scripts/respond.js", + "~/Content/bs3/js/bootstrap.min.js", + "~/Scripts/js/bootstrap-datepicker.js", + "~/Scripts/js/jquery.minimalect.min.js", + "~/Scripts/js/jquery.flexslider-min.js", + "~/Scripts/js/rs-plugin/js/jquery.plugins.min.js", + "~/Scripts/js/rs-plugin/js/jquery.revolution.min.js", + "~/Scripts/js/script.js")); + + //bundles.Add(new ScriptBundle("~/bundles/news").Include( + // "~/Scripts/custom.js", + // "~/Scripts/flex-slider-min.js", + // "~/Scripts/plugins.js")); + + bundles.Add(new ScriptBundle("~/bundles/script").Include( + "~/Scripts/jsadmin/jquery.slimscroll.min.js", + "~/Scripts/jsadmin/jquery.placeholder.js", + "~/Scripts/jsadmin/offscreen.js", + "~/Scripts/jsadmin/main.js", + "~/Scripts/jsadmin/jszip.min.js", + "~/Scripts/jsadmin/kendo.all.min.js", + "~/Scripts/jsadmin/jquery.unobtrusive-ajax.min.js", + "~/Scripts/jsadmin/kendo.aspnetmvc.min.js" + )); + + //bundles.Add(new StyleBundle("~/Content/css").Include( + // "~/Content/css/layout.css", + // "~/Content/css/skeleton.css", + // "~/Content/css/style.css")); + + bundles.Add(new StyleBundle("~/Content/css").Include( + + "~/Content/css/bs3/css/bootstrap.css", + "~/Content/bootstrap.css", + "~/Content/css/styles.css", + "~/Content/css/flexslider.css", + "~/Content/css/responsive.css", + "~/Content/css/colors/color1.css", + "~/Content/css/flexslider.css", + "~/Content/css/responsive.css")); + } + } +} diff --git a/StudyDoIT/App_Start/FilterConfig.cs b/StudyDoIT/App_Start/FilterConfig.cs new file mode 100644 index 0000000..94cc475 --- /dev/null +++ b/StudyDoIT/App_Start/FilterConfig.cs @@ -0,0 +1,13 @@ +using System.Web; +using System.Web.Mvc; + +namespace StudyDoIT +{ + public class FilterConfig + { + public static void RegisterGlobalFilters(GlobalFilterCollection filters) + { + filters.Add(new HandleErrorAttribute()); + } + } +} diff --git a/StudyDoIT/App_Start/RouteConfig.cs b/StudyDoIT/App_Start/RouteConfig.cs new file mode 100644 index 0000000..14fe656 --- /dev/null +++ b/StudyDoIT/App_Start/RouteConfig.cs @@ -0,0 +1,192 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; + +namespace StudyDoIT +{ + public class RouteConfig + { + public static void RegisterRoutes(RouteCollection routes) + { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + + routes.MapRoute( + "SearchProduct", + "tim-kiem-san-pham/{p}", + new { controller = "Search", action = "ResulftSearch"}, + new { p = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Product", + "sp/{seoName}-{id}-{p}", + new { controller = "Category", action = "Index", seoName = "" }, + new { id = @"^\d+$", p = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "News", + "tin/{seoName}-{id}-{p}", + new { controller = "Category", action = "News", seoName = "" }, + new { id = @"^\d+$", p = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Page", + "p/{seoName}-{id}", + new { controller = "Category", action = "Page", seoName = "" }, + new { id = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Tag", + "tag-tin/{seoName}-{p}", + new { controller = "Category", action = "Tag", seoName = "" }, + new { p = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "TagProduct", + "tag-sp/{seoName}-{p}", + new { controller = "Category", action = "TagTour", seoName = "" }, + new { p = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "CustomerComment", + "y-kien-khach-hang", + new { controller = "Category", action = "CustomerComment"}, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Comment", + "chi-tiet-y-kien-khach-hang/{id}", + new { controller = "Single", action = "Comment" }, + new { id = @"^\d+$"}, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "DetailProduct", + "chi-tiet-sp/{seoName}-{id}", + new { controller = "Single", action = "Index", seoName = "" }, + new { id = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "DetailNews", + "chi-tiet-tin/{seoName}-{id}", + new { controller = "Single", action = "News", seoName = "" }, + new { id = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Contact", + "lien-he", + new { controller = "Home", action = "Contact" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "RecoverPassword", + "lay-lai-mat-khau", + new { controller = "Customer", action = "RecoverPassword"}, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "UserAuthentication", + "xac-thuc-tai-khoan/{username}", + new { controller = "Customer", action = "UserAuthentication", username = "" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Login", + "dang-nhap", + new { controller = "Customer", action = "Login"}, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Register", + "dang-ky", + new { controller = "Customer", action = "Register" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Logout", + "dang-xuat", + new { controller = "Customer", action = "Logout" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "InfoUser", + "trang-ca-nhan/{user}", + new { controller = "Customer", action = "InfoUser", user = "" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Compare", + "danh-sach-san-pham-so-sanh", + new { controller = "Customer", action = "Compare" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Wishlist", + "danh-sach-yeu-thich-{p}", + new { controller = "Customer", action = "Wishlists", p = 1 }, + new { p = @"^\d+$" }, new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "ShoppingCart", + "gio-hang", + new { controller = "ShoppingCart", action = "ShoppingCart" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "Checkout", + "thuc-hien-mua-hang", + new { controller = "Checkout", action = "Index" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "ComplateOrder", + "hoan-tat-dat-hang", + new { controller = "Checkout", action = "ComplateOrder" }, + new string[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, + namespaces: new[] { "StudyDoIT.Controllers" } + ); + + routes.MapRoute( + "AdminIT", + "AdminIT/{seoName}", + new { controller = "Home", action = "Menu", seoName = "" }, + new string[] { "StudyDoIT.Areas.Admin.Controllers" } + ); + + //routes.MapRoute( + // name: "Admin", + // url: "AdminIT/{controller}/{action}/{id}", + // defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }, + // constraints: new string[] { "StudyDoIT.Areas.Admin.Controllers" } + //); + } + } +} diff --git a/StudyDoIT/App_Start/Startup.Auth.cs b/StudyDoIT/App_Start/Startup.Auth.cs new file mode 100644 index 0000000..d4f3ef5 --- /dev/null +++ b/StudyDoIT/App_Start/Startup.Auth.cs @@ -0,0 +1,38 @@ +using Microsoft.AspNet.Identity; +using Microsoft.Owin; +using Microsoft.Owin.Security.Cookies; +using Owin; + +namespace StudyDoIT +{ + public partial class Startup + { + // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 + public void ConfigureAuth(IAppBuilder app) + { + // Enable the application to use a cookie to store information for the signed in user + app.UseCookieAuthentication(new CookieAuthenticationOptions + { + AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, + LoginPath = new PathString("/Account/Login") + }); + // Use a cookie to temporarily store information about a user logging in with a third party login provider + app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); + + // Uncomment the following lines to enable logging in with third party login providers + //app.UseMicrosoftAccountAuthentication( + // clientId: "", + // clientSecret: ""); + + //app.UseTwitterAuthentication( + // consumerKey: "", + // consumerSecret: ""); + + //app.UseFacebookAuthentication( + // appId: "", + // appSecret: ""); + + //app.UseGoogleAuthentication(); + } + } +} \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/AdminITAreaRegistration.cs b/StudyDoIT/Areas/AdminIT/AdminITAreaRegistration.cs new file mode 100644 index 0000000..a2d2dc6 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/AdminITAreaRegistration.cs @@ -0,0 +1,24 @@ +using System.Web.Mvc; + +namespace StudyDoIT.Areas.AdminIT +{ + public class AdminITAreaRegistration : AreaRegistration + { + public override string AreaName + { + get + { + return "AdminIT"; + } + } + + public override void RegisterArea(AreaRegistrationContext context) + { + context.MapRoute( + "AdminIT_default", + "AdminIT/{controller}/{action}/{id}", + new { action = "Index", id = UrlParameter.Optional } + ); + } + } +} \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/datajson/output.json b/StudyDoIT/Areas/AdminIT/Content/datajson/output.json new file mode 100644 index 0000000..80411ba --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/datajson/output.json @@ -0,0 +1 @@ +["Cleanliness","Room","Room","Service","Value","Room","Room","Value","Service","Service","Cleanliness","Value","Room","Cleanliness","Cleanliness","Location","Cleanliness","Room","Room","Room","Cleanliness","Service","Room","Room","Room","Cleanliness","Room","Cleanliness","Service","Cleanliness","Cleanliness","Room","Value","Value","Cleanliness","Value","Room","Room","Cleanliness","Location","Room","Room","Cleanliness","Room","Cleanliness","Cleanliness","Room","Cleanliness","Room","Service","Cleanliness","Room","Value","Room","Service","Cleanliness","Room","Value","Room","Room","Value","Cleanliness","Cleanliness","Cleanliness","Service","Cleanliness","Room","Cleanliness","Cleanliness","Service","Cleanliness","Room","Value","Business service ","Room","Room","Room","Value","Room","Room","Cleanliness","Cleanliness","Room","Cleanliness","Cleanliness","Room","Cleanliness","Cleanliness","Service","Service","Room","Room","Room","Cleanliness","Value","Room","Cleanliness","Cleanliness","Cleanliness","Room","Room","Cleanliness","Room","Cleanliness","Business service ","Room","Service","Room","Room","Room","Cleanliness","Service","Cleanliness","Business service ","Room","Cleanliness","Room","Cleanliness","Value","Room","Cleanliness","Room","Room","Room","Cleanliness","Cleanliness","Cleanliness","Cleanliness","Room","Room","Room","Room","Cleanliness","Cleanliness","Cleanliness","Room","Room","Cleanliness","Cleanliness","Cleanliness","Cleanliness","Cleanliness","Cleanliness","Business service ","Room","Cleanliness","Room","Room","Cleanliness","Room","Room","Room","Room","Cleanliness","Cleanliness","Room","Room","Cleanliness","Room","Cleanliness","Cleanliness","Cleanliness","Room","Cleanliness","Service","Room","Cleanliness","Room","Value","Room","Service","Room","Cleanliness","Room","Value","Room","Cleanliness","Room","Cleanliness","Service","Cleanliness","Room","Room","Value","Cleanliness","Cleanliness","Value","Cleanliness","Cleanliness","Room","Cleanliness","Service","Room","Cleanliness","Value","Cleanliness","Room","Service","Room","Cleanliness","Room","Room","Room","Room","Cleanliness","Cleanliness","Room","Room","Room","Room","Cleanliness","Cleanliness","Cleanliness","Room","Room","Cleanliness","Room","Cleanliness","Room","Room","Cleanliness","Cleanliness","Cleanliness","Cleanliness","Service","Room","Cleanliness","Room","Room","Value","Room","Cleanliness","Room","Cleanliness","Cleanliness","Cleanliness","Service","Room","Room","Value"] \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/images/!logged-user.jpg b/StudyDoIT/Areas/AdminIT/Content/images/!logged-user.jpg new file mode 100644 index 0000000..1762061 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/!logged-user.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/!sample-user.jpg b/StudyDoIT/Areas/AdminIT/Content/images/!sample-user.jpg new file mode 100644 index 0000000..83a1d14 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/!sample-user.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/arrows.png b/StudyDoIT/Areas/AdminIT/Content/images/arrows.png new file mode 100644 index 0000000..c3d3939 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/arrows.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/blog-image-1.jpg b/StudyDoIT/Areas/AdminIT/Content/images/blog-image-1.jpg new file mode 100644 index 0000000..50e9347 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/blog-image-1.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/blog-image-2.jpg b/StudyDoIT/Areas/AdminIT/Content/images/blog-image-2.jpg new file mode 100644 index 0000000..106bc32 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/blog-image-2.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/blog-image-3.jpg b/StudyDoIT/Areas/AdminIT/Content/images/blog-image-3.jpg new file mode 100644 index 0000000..11ec547 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/blog-image-3.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/device.png b/StudyDoIT/Areas/AdminIT/Content/images/device.png new file mode 100644 index 0000000..ab5d2af Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/device.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/dragonviet.png b/StudyDoIT/Areas/AdminIT/Content/images/dragonviet.png new file mode 100644 index 0000000..93445fb Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/dragonviet.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/emsi.png b/StudyDoIT/Areas/AdminIT/Content/images/emsi.png new file mode 100644 index 0000000..bb29cdc Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/emsi.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/invoice-logo.png b/StudyDoIT/Areas/AdminIT/Content/images/invoice-logo.png new file mode 100644 index 0000000..ab5bfd0 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/invoice-logo.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/jstree-dark.png b/StudyDoIT/Areas/AdminIT/Content/images/jstree-dark.png new file mode 100644 index 0000000..ef42723 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/jstree-dark.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/jstree.png b/StudyDoIT/Areas/AdminIT/Content/images/jstree.png new file mode 100644 index 0000000..8608969 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/jstree.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/logo-epu.png b/StudyDoIT/Areas/AdminIT/Content/images/logo-epu.png new file mode 100644 index 0000000..9d2bf2e Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/logo-epu.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/logo.png b/StudyDoIT/Areas/AdminIT/Content/images/logo.png new file mode 100644 index 0000000..6ca2e38 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/logo.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/patterns/denim.png b/StudyDoIT/Areas/AdminIT/Content/images/patterns/denim.png new file mode 100644 index 0000000..3b0bb7e Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/patterns/denim.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/patterns/noisy_net.png b/StudyDoIT/Areas/AdminIT/Content/images/patterns/noisy_net.png new file mode 100644 index 0000000..e19a7a6 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/patterns/noisy_net.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-1.jpg b/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-1.jpg new file mode 100644 index 0000000..db40deb Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-1.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-2.jpg b/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-2.jpg new file mode 100644 index 0000000..14c182b Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-2.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-3.jpg b/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-3.jpg new file mode 100644 index 0000000..9216af5 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/post-thumb-3.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/projects/project-1.jpg b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-1.jpg new file mode 100644 index 0000000..27982f3 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-1.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/projects/project-2.jpg b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-2.jpg new file mode 100644 index 0000000..b7fa7fa Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-2.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/projects/project-3.jpg b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-3.jpg new file mode 100644 index 0000000..dfbd12e Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-3.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/projects/project-4.jpg b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-4.jpg new file mode 100644 index 0000000..e7e6015 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-4.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/projects/project-5.jpg b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-5.jpg new file mode 100644 index 0000000..f233bc4 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-5.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/projects/project-6.jpg b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-6.jpg new file mode 100644 index 0000000..bce83a3 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-6.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/projects/project-7.jpg b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-7.jpg new file mode 100644 index 0000000..bffc8bf Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/projects/project-7.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/projects/project.jpg b/StudyDoIT/Areas/AdminIT/Content/images/projects/project.jpg new file mode 100644 index 0000000..3f24bcc Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/projects/project.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/images/widget-twitter-profile.jpg b/StudyDoIT/Areas/AdminIT/Content/images/widget-twitter-profile.jpg new file mode 100644 index 0000000..2066e3e Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/images/widget-twitter-profile.jpg differ diff --git a/StudyDoIT/Areas/AdminIT/Content/stylesheets/invoice-print.css b/StudyDoIT/Areas/AdminIT/Content/stylesheets/invoice-print.css new file mode 100644 index 0000000..8090eef --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/stylesheets/invoice-print.css @@ -0,0 +1,841 @@ +/* Headings */ +h1, +h2, +h3, +.h1, +.h2, +.h3 { + letter-spacing: -1px; +} + +h1, +.h1 { + font-size: 36px; + font-size: 3.6rem; +} + +h2, +.h2 { + font-size: 30px; + font-size: 3rem; +} + +h3, +.h3 { + font-size: 24px; + font-size: 2.4rem; +} + +h4, +.h4 { + font-size: 18px; + font-size: 1.8rem; +} + +h5, +.h5 { + font-size: 14px; + font-size: 1.4rem; +} + +h6, +.h6 { + font-size: 12px; + font-size: 1.2rem; + letter-spacing: 0; +} + +/* Alternative Font Style */ +.alternative-font { + color: #cccccc; + font-family: "Shadows Into Light", cursive; + font-size: 1.6em; +} + +/* Drop Caps */ +p.drop-caps:first-child:first-letter { + float: left; + font-size: 75px; + line-height: 60px; + padding: 4px; + margin-right: 5px; + margin-top: 5px; + font-family: Georgia; + color: #171717; +} + +p.drop-caps.secundary:first-child:first-letter { + background-color: #171717; + color: #FFF; + padding: 6px; + margin-right: 5px; + border-radius: 4px; +} + +p.drop-caps.colored:first-child:first-letter { + color: #cccccc; +} + +p.drop-caps.colored.secundary:first-child:first-letter { + background-color: #cccccc; + color: #FFF; +} + +/* Blockquote */ +blockquote { + font-size: 1em; +} + +/* Hightlight */ +.highlight { + background-color: #cccccc; + color: #FFF; + padding: 3px 6px; +} + +/* Divider Line */ +hr { + border: 0; + height: 1px; + background-image: -webkit-linear-gradient(left, transparent, rgba(0, 0, 0, 0.2), transparent); + background-image: -moz-linear-gradient(left, transparent, rgba(0, 0, 0, 0.2), transparent); + background-image: -ms-linear-gradient(left, transparent, rgba(0, 0, 0, 0.2), transparent); + background-image: -o-linear-gradient(left, transparent, rgba(0, 0, 0, 0.2), transparent); + margin: 22px 0 22px 0; +} + +hr.short { + margin: 11px 0 11px 0; +} + +hr.tall { + margin: 44px 0 44px 0; +} + +hr.taller { + margin: 66px 0 66px 0; +} + +hr.light { + background-image: -webkit-linear-gradient(left, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)); + background-image: -moz-linear-gradient(left, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)); + background-image: -ms-linear-gradient(left, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)); + background-image: -o-linear-gradient(left, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)); +} + +hr.dotted { + height: 0; + border-bottom: 1px dotted #ddd; +} + +hr.solid { + height: 0; + border-bottom: 1px solid #ddd; +} + +/* Buttons Icon */ +.btn-icon i { + margin-right: 10px; +} + +.btn-icon-right i { + margin-right: 0; + margin-left: 10px; +} + +/* Form Elements */ +input { + outline: none; +} + +label { + font-weight: normal; +} + +textarea { + resize: vertical; +} + +textarea[data-toggle=autosize] { + -webkit-transition: height 0.15s ease-in; + -moz-transition: height 0.15s ease-in; + transition: height 0.15s ease-in; +} + +select { + border: 1px solid #E5E7E9; + border-radius: 6px; + height: 46px; + padding: 12px; + outline: none; +} + +/* Forms Validations */ +label.valid { + display: inline-block; + text-indent: -9999px; +} + +label.error { + color: #C10000; + font-size: 0.9em; + margin-top: -5px; + padding: 0; +} + +/* Miscellaneous */ +body a, body a:focus, body a:hover, body a:active, body a:visited { + outline: none !important; +} + +.center { + text-align: center; +} + +ul, +ol { + margin-bottom: 0; + padding-left: 27px; +} + +blockquote.primary { + border-color: #cccccc; +} + +blockquote.success { + border-color: #47a447; +} + +blockquote.warning { + border-color: #ed9c28; +} + +blockquote.danger { + border-color: #d2322d; +} + +blockquote.info { + border-color: #5bc0de; +} + +blockquote.dark { + border-color: #171717; +} + +.well.primary { + background: #cccccc; + border-color: #b3b3b3; + color: white; +} + +.well.success { + background: #47a447; + border-color: #388038; + color: white; +} + +.well.warning { + background: #ed9c28; + border-color: #d18211; + color: white; +} + +.well.danger { + background: #d2322d; + border-color: #a82824; + color: white; +} + +.well.info { + background: #5bc0de; + border-color: #31b0d5; + color: white; +} + +.well.dark { + background: #171717; + border-color: black; + color: white; +} + +/* Arrows */ +.arrow { + background: transparent url(../images/arrows.png) no-repeat 0 0; + width: 47px; + height: 120px; + display: inline-block; + position: relative; +} + +.arrow.vtl { + background-position: 0 0; + width: 47px; + height: 96px; +} + +.arrow.vtr { + background-position: -101px 0; + width: 47px; + height: 96px; +} + +.arrow.vbl { + background-position: 0 -144px; + width: 47px; + height: 96px; +} + +.arrow.vbr { + background-position: -101px -144px; + width: 47px; + height: 96px; +} + +.arrow.hlt { + background-position: -209px 0; + width: 120px; + height: 47px; +} + +.arrow.hlb { + background-position: -209px -101px; + width: 120px; + height: 47px; +} + +.arrow.hrt { + background-position: -353px 0; + width: 120px; + height: 47px; +} + +.arrow.hrb { + background-position: -353px -101px; + width: 120px; + height: 47px; +} + +.img-thumbnail { + border-radius: 8px; + position: relative; +} + +.img-thumbnail .zoom { + display: block; + position: absolute; + right: 8px; + bottom: 8px; + height: 30px; + width: 30px; + padding: 6px; + font-size: 14px; + line-height: 18px; + background: #CCC; + border-radius: 100%; + color: #FFF; + text-align: center; +} + +.img-thumbnail .zoom i { + position: relative; + top: -1px; + left: -1px; +} + +/* Thumbnail Gallery */ +.thumbnail-gallery { + list-style: none; + margin: 10px 0; + padding: 0; +} + +.thumbnail-gallery .img-thumbnail, +.thumbnail-gallery .thumbnail { + margin: 10px 10px 0 0; +} + +/* Navs */ +ul.nav-list.primary > li { + margin: 0; + padding: 0; +} + +ul.nav-list.primary > li:last-child a { + border-bottom: transparent !important; +} + +ul.nav-list.primary > li a { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + transition: all 0.3s; + background-position: 9px 16px; + background-repeat: no-repeat; + border-bottom: 1px solid #EDEDDE; + padding: 8px 20px; +} + +.changelog h4 { + display: inline-block; + color: #000; + font-size: 1em; + font-weight: 600; +} + +.changelog .release-date { + color: #999; + font-size: 0.9em; +} + +.changelog .label { + display: inline-block; + min-width: 100px; +} + +.scrollable { + overflow: hidden; + position: relative; + width: 100%; +} + +.scrollable .scrollable-content { + bottom: 0; + left: 0; + overflow: hidden; + position: absolute; + right: 0; + top: 0; + padding: 0 37px 0 0; + overflow-x: hidden; + overflow-y: scroll; +} + +.scrollable .scrollable-content::-webkit-scrollbar { + visibility: hidden; +} + +.scrollable .scrollable-pane { + bottom: 0; + opacity: 0.01; + position: absolute; + right: 5px; + top: 0; + transition: all 0.2s ease 0s; + width: 4px; +} + +.scrollable .scrollable-slider { + border-radius: 5px; + background: none repeat scroll 0 0 #CCC; + margin: 0; + position: relative; + transition: opacity 0.2s ease 0s; + opacity: 0; +} + +.scrollable.scrollable-padding .scrollable-content { + padding: 10px 24px 10px 10px; +} + +.scrollable:hover .scrollable-slider, .scrollable.visible-slider .scrollable-slider { + opacity: 1; +} + +/* Tables - Basic */ +.table { + width: 100%; +} + +.table .table { + background: transparent; +} + +/* Bootstrap uses important, we need to force it here */ +.table.mb-none { + margin-bottom: 0 !important; +} + +/* In case you dont want a border in some row */ +.table .b-top-none td { + border-top: none; +} + +/* Tables - Actions */ +.table .actions, +.table .actions-hover { + vertical-align: middle; +} + +.table .actions a, +.table .actions-hover a { + display: inline-block; + margin-right: 5px; + color: #666; +} + +.table .actions a:last-child, +.table .actions-hover a:last-child { + margin-right: 0; +} + +.table .actions a:hover, +.table .actions-hover a:hover { + color: #333; +} + +.table .actions-hover a { + opacity: 0; +} + +.table tr:hover .actions-hover a { + opacity: 1; +} + +.table .actions-fade a { + -webkit-transition: all 0.2s linear; + -moz-transition: all 0.2s linear; + transition: all 0.2s linear; +} + +/* Tables - No More Tables technique (991px is the bootstrap SM max-width) */ +@media only screen and (max-width: 991px) { + .table.table-no-more, + .table.table-no-more thead, + .table.table-no-more tbody, + .table.table-no-more tr, + .table.table-no-more th, + .table.table-no-more td { + display: block; + } + + .table.table-no-more thead tr { + left: -9999px; + position: absolute; + top: -9999px; + } + + .table.table-no-more tr { + border-bottom: 1px solid #DDD; + } + + .table.table-no-more td { + border: none; + position: relative; + padding-left: 50%; + text-align: left; + white-space: normal; + } + + .table.table-no-more td:before { + content: attr(data-title); + font-weight: bold; + left: 6px; + padding-right: 10px; + position: absolute; + text-align: left; + top: 8px; + white-space: nowrap; + width: 45%; + } + + .table.table-no-more.table-bordered td { + border-bottom: 1px solid #EFEFEF; + } + + .table.table-no-more.table-condensed td:before { + top: 5px; + } +} +/* Dark - Tables */ +html.dark .table > thead > tr > th, +html.dark .table > tbody > tr > th, +html.dark .table > tfoot > tr > th, +html.dark .table > thead > tr > td, +html.dark .table > tbody > tr > td, +html.dark .table > tfoot > tr > td, +html.dark .table-bordered { + border-color: #262b33; +} + +html.dark .table-striped > tbody > tr:nth-child(2n+1) > td, +html.dark .table-striped > tbody > tr:nth-child(2n+1) > th { + background-color: #282d36; +} + +html.dark .table-hover > tbody > tr:hover > td, +html.dark .table-hover > tbody > tr:hover > th { + background-color: #272c34; +} + +html.dark .table .actions a, +html.dark .table .actions-hover a { + color: #808697; +} + +@media screen and (max-width: 991px) { + html.dark .table-responsive { + border-color: #262b33; + } +} + +@media only screen and (max-width: 991px) { + html.dark .table.table-no-more tr, + html.dark .table.table-no-more.table-bordered td { + border-bottom-color: #262b33; + } +} +/* Tables - States */ +.table > thead > tr > td.primary, +.table > tbody > tr > td.primary, +.table > tfoot > tr > td.primary, +.table > thead > tr > th.primary, +.table > tbody > tr > th.primary, +.table > tfoot > tr > th.primary, +.table > thead > tr.primary > td, +.table > tbody > tr.primary > td, +.table > tfoot > tr.primary > td, +.table > thead > tr.primary > th, +.table > tbody > tr.primary > th, +.table > tfoot > tr.primary > th { + color: #FFF; + background-color: #cccccc; +} + +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + color: #FFF; + background-color: #47a447; +} + +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + color: #FFF; + background-color: #ed9c28; +} + +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + color: #FFF; + background-color: #d2322d; +} + +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + color: #FFF; + background-color: #5bc0de; +} + +.table > thead > tr > td.dark, +.table > tbody > tr > td.dark, +.table > tfoot > tr > td.dark, +.table > thead > tr > th.dark, +.table > tbody > tr > th.dark, +.table > tfoot > tr > th.dark, +.table > thead > tr.dark > td, +.table > tbody > tr.dark > td, +.table > tfoot > tr.dark > td, +.table > thead > tr.dark > th, +.table > tbody > tr.dark > th, +.table > tfoot > tr.dark > th { + color: #FFF; + background-color: #171717; +} + +.table > thead > tr > td.dark, +.table > tbody > tr > td.dark, +.table > tfoot > tr > td.dark, +.table > thead > tr > th.dark, +.table > tbody > tr > th.dark, +.table > tfoot > tr > th.dark, +.table > thead > tr.dark > td, +.table > tbody > tr.dark > td, +.table > tfoot > tr.dark > td, +.table > thead > tr.dark > th, +.table > tbody > tr.dark > th, +.table > tfoot > tr.dark > th { + background-color: #4a4a4a; + color: white; +} + +/* Invoice */ +.invoice { + padding: 0 15px 15px; +} + +/* Invoice Address Tag */ +.invoice address { + color: #7F8597; + line-height: 1.5em; +} + +/* Invoice header */ +.invoice header { + border-bottom: 1px solid #DADADA; + margin-bottom: 15px; +} + +.invoice header .h2, +.invoice header .h4 { + letter-spacing: 0; +} + +/* Invoice Billing Information */ +.invoice .bill-to, +.invoice .bill-data { + padding: 15px 0; +} + +.invoice .bill-data .value { + display: inline-block; + margin-left: 10px; + width: 90px; +} + +/* Invoice table */ +.invoice table.table { + table-layout: fixed; +} + +.invoice table.table > thead:first-child > tr > th { + background-color: #F8F8F8; + border-bottom: 1px solid #DADADA; + border-top: 1px solid #DADADA; +} + +.invoice table.table > tbody tr > td { + border-color: #DADADA; +} + +/* Invoice table items */ +.invoice .invoice-items > tbody tr:last-child > td { + border-bottom: 1px solid #DADADA; +} + +.invoice .invoice-items #cell-id { + width: 10%; +} + +.invoice .invoice-items #cell-item { + width: 20%; +} + +.invoice .invoice-items #cell-desc { + width: 20%; +} + +.invoice .invoice-items #cell-price { + width: 10%; +} + +.invoice .invoice-items #cell-qty { + width: 10%; +} + +.invoice .invoice-items #cell-total { + width: 10%; +} + +/* Invoice summary */ +.invoice-summary .col-sm-4 { + padding-left: 0; +} + +/* Invoice Responsiveness */ +@media only screen and (max-width: 991px) { + .invoice .table-responsive > table.table { + table-layout: auto; + } + + .invoice-summary .col-sm-4 { + padding-left: 15px; + } +} +/* Invoice Print */ +@media print { + .invoice .table-responsive { + border: none !important; + overflow: visible !important; + width: auto !important; + } + + .invoice table.table.invoice-items { + table-layout: auto; + } + + .invoice header .col-sm-6:first-child, + .invoice header .col-sm-6:last-child, + .invoice .bill-info .col-md-6 { + float: left !important; + } + + .invoice header .col-sm-6:first-child { + width: 25% !important; + } + + .invoice header .col-sm-6:last-child { + width: 75% !important; + } + + .invoice .bill-info .col-md-6 { + width: 50% !important; + } + + .invoice .invoice-summary .col-sm-4 { + float: right; + padding: 0; + width: 40%; + } +} +/* dark */ +html.dark .invoice header { + border-bottom-color: #282d36; +} + +html.dark .invoice table.table > thead:first-child > tr > th { + background-color: #282d36; + border-bottom-color: #282d36; + border-top-color: #282d36; +} + +html.dark .invoice table.table > tbody tr > td { + border-color: #282d36; +} diff --git a/StudyDoIT/Areas/AdminIT/Content/stylesheets/theme-custom.css b/StudyDoIT/Areas/AdminIT/Content/stylesheets/theme-custom.css new file mode 100644 index 0000000..debd766 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/stylesheets/theme-custom.css @@ -0,0 +1 @@ +/* Add here all your CSS customizations */ diff --git a/StudyDoIT/Areas/AdminIT/Content/stylesheets/theme.css b/StudyDoIT/Areas/AdminIT/Content/stylesheets/theme.css new file mode 100644 index 0000000..c732a66 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/stylesheets/theme.css @@ -0,0 +1,17574 @@ + + +html, +body { + background: #ecedf0; + width: 100%; +} + +html { + font-size: 10px; +} + +body { + color: #777; + font-family: "Open Sans", Arial, sans-serif; + line-height: 22px; + margin: 0; + font-size: 13px; + overflow-x: hidden; + overflow-y: scroll; +} + +a { + color: #cccccc; +} + +a:hover, a:focus { + color: #d9d9d9; +} + +a:active { + color: #bfbfbf; +} + +/* Layout Base - Main Wrapper */ +.body { + min-height: 100vh; + width: 100%; +} + +/* Layout Base - Header */ +.header { + height: 60px; + left: 0; + position: absolute; + right: 0; + top: 0; +} + +/* Layout Base - Inner Wrapper */ +.inner-wrapper { + display: table; + min-height: 100vh; + padding-top: 60px; + table-layout: fixed; + overflow: hidden; + width: 100%; +} + +/* Layout Base - Content Body */ +.content-body { + display: table-cell; + padding: 40px; + position: relative; + vertical-align: top; +} + +.content-body > .row + .row { + padding-top: 10px; +} + +/* Layout Base - Page Header */ +.page-header { + background: #0d4f88; + border-bottom: none; + border-left: 1px solid #428bca; + box-shadow: 1px 3px 0 1px #5bc0de; + height: 50px; + margin: -40px -40px 40px -40px; + padding: 0; +} + +/* Layout Base - Sidebar Left */ +.sidebar-left { + background: #0d4f88; + box-shadow: -5px 0 0 #5bc0de inset; + color: #fff; + display: table-cell; + position: relative; + vertical-align: top; + width: 300px; + z-index: 1010; +} + +/* Layout Base - Sidebar Left Opened ( Larger than mobile ) */ +@media only screen and (min-width: 768px) { + html.sidebar-left-collapsed .sidebar-left { + width: 73px; + } +} +/* Layout Base - Sidebar Right */ +.sidebar-right { + background: #171717; + bottom: 0; + margin-right: -300px; + min-height: 100vh; + position: fixed; + right: 0; + top: 0; + width: 300px; +} + +/* Layout Base - Sidebar Right Opened ( Larger than mobile ) */ +@media only screen and (min-width: 768px) { + html.sidebar-right-opened .header { + margin-left: -300px; + margin-right: 300px; + } + + html.sidebar-right-opened .inner-wrapper { + margin-left: -300px; + } + + html.sidebar-right-opened .sidebar-right { + margin-right: 0; + } +} +/* Layout Base - Flexbox supported */ +@media only screen and (min-width: 768px) { + html.flexbox .inner-wrapper, + html.flexboxlegacy .inner-wrapper { + display: -webkit-box; + display: -moz-box; + display: box; + display: -webkit-flex; + display: -moz-flex; + display: -ms-flexbox; + display: flex; + } + + html.flexbox .sidebar-left, + html.flexbox .content-body, + html.flexboxlegacy .sidebar-left, + html.flexboxlegacy .content-body { + display: block; + -webkit-flex-shrink: 0; + -moz-flex-shrink: 0; + flex-shrink: 0; + -ms-flex-negative: 0; + } + + html.flexbox .content-body, + html.flexboxlegacy .content-body { + -webkit-box-flex: 2; + -moz-box-flex: 2; + box-flex: 2; + -webkit-flex: 2; + -moz-flex: 2; + -ms-flex: 2; + flex: 2; + } +} +/* Layout Fixed */ +@media only screen and (min-width: 768px) { + /* Layout Fixed - Reseting Styles */ + html.fixed .inner-wrapper, + html.fixed .sidebar-left, + html.fixed .content-body { + display: block; + } + + /* Layout Fixed - Header */ + html.fixed .header { + position: fixed; + z-index: 1020; + } + + /* Layout Fixed - Inner Wrapper */ + html.fixed .inner-wrapper { + padding-top: 110px; + } + + /* Layout Fixed - Content Body */ + html.fixed .content-body { + margin-left: 300px; + } + + html.fixed .content-body.has-toolbar { + padding-top: 92px; + } + + /* Layout Fixed - Page header */ + html.fixed .page-header { + left: 300px; + margin: 0; + position: fixed; + right: 0; + top: 60px; + } + + /* Layout Fixed - Sidebar Left */ + html.fixed .sidebar-left { + bottom: 0; + left: 0; + padding-bottom: 50px; + position: fixed; + top: 60px; + } + + html.fixed .sidebar-left .nano-content { + padding-bottom: 50px; + } + + /* Layout Fixed - Sidebar Left Collapsed */ + html.fixed.sidebar-left-collapsed .page-header { + left: 73px; + } + + html.fixed.sidebar-left-collapsed .content-body { + margin-left: 73px; + } + + /* Layout Fixed - Sidebar Right Opened */ + html.fixed.sidebar-right-opened .page-header { + left: 0; + margin-right: 300px; + } + + html.fixed.sidebar-right-opened .sidebar-left { + left: -300px; + } + + /* Layout Fixed - Sidebar Left Collapsed & Sidebar Right Opened */ + html.fixed.sidebar-left-collapsed.sidebar-right-opened .page-header { + left: -300px; + } +} +/* Layout Boxed - small than min-width */ +@media only screen and (max-width: 1199px) { + html.boxed .header { + border-color: #cccccc; + } +} +/* Layout Boxed - larger or equal min width */ +@media only screen and (min-width: 1200px) { + /* Layout Boxed - Body Tag */ + html.boxed body { + background: url(../images/patterns/denim.png) repeat; + } + + /* Layout Boxed - Main Wrapper */ + html.boxed .body { + position: relative; + max-width: 1200px; + margin: 0 auto; + background-color: transparent; + } + + /* Layout Boxed - Header */ + html.boxed .header { + border-top: 3px solid #cccccc; + height: 63px; + position: absolute; + top: 25px; + } + + /* Layout Boxed - Inner Wrapper */ + html.boxed .inner-wrapper { + padding-top: 88px; + padding-bottom: 25px; + } + + /* Layout Boxed - Content Body */ + html.boxed .content-body { + background-color: #ecedf0; + } + + /* Layout Boxed - Border Radius */ + html.boxed .header { + border-radius: 5px 5px 0 0; + } + + html.boxed .sidebar-left { + border-radius: 0 0 0 5px; + } + + html.boxed .content-body { + border-radius: 0 0 5px 0; + } + + html.boxed .sidebar-right { + border-radius: 0 5px 5px 0; + } + + /* Layout Boxed - Sidebar Right */ + html.boxed .sidebar-right { + border-top: 3px solid #cccccc; + min-height: 0; + } + + /* Layout Boxed - Sidebar Right Opened */ + html.boxed.sidebar-right-opened .body { + overflow: hidden; + } + + html.boxed.sidebar-right-opened .header { + border-radius: 5px 0 0 0; + } + + html.boxed.sidebar-right-opened .content-body { + border-radius: 0 0 0 5px; + } + + html.boxed.sidebar-right-opened .sidebar-right { + bottom: 25px; + position: absolute; + top: 25px; + } +} + +@media only screen and (max-width: 767px) { + html, + body { + background: #ecedf0; + } + + html.mobile-device .sidebar-left, + html.mobile-device .sidebar-right { + overflow-y: scroll; + overflow-x: hidden; + -webkit-overflow-scrolling: touch; + } + + body { + min-height: 100vh; + } + + .inner-wrapper, + .sidebar-left, + .content-body { + display: block; + } + + .body { + min-height: 0; + overflow: visible; + } + + .header { + background: none; + border: none; + height: auto; + position: static; + } + + .header .logo-container { + height: 60px; + left: 0; + position: fixed; + right: 0; + top: 0; + z-index: 99; + } + + .header .header-right { + background: #FFF; + float: none !important; + height: 60px; + margin-top: 60px; + width: 100%; + } + + .inner-wrapper { + min-height: 0; + padding-top: 0; + } + + .content-body { + padding: 0 15px 15px; + } + + .page-header { + margin: 0 -15px 20px; + } + + .sidebar-left { + bottom: 0; + left: -100%; + min-height: 0; + min-width: 100%; + min-width: 100vw; + padding-top: 60px; + padding-bottom: 50px; + position: fixed; + overflow: hidden; + top: 0; + z-index: 98 !important; + } + + .sidebar-right { + bottom: 0; + left: auto; + right: -100%; + min-height: 0; + margin-right: 0; + min-width: 100%; + min-width: 100vw; + top: 0; + z-index: 100; + } + + html.csstransforms .sidebar-left, + html.csstransforms .sidebar-right { + /* performs better but native android browser + has problems with translate and percentage + @include transition-property(transform); + */ + -webkit-transition-property: margin; + -moz-transition-property: margin; + transition-property: margin; + -webkit-transition-duration: 0.25s; + -moz-transition-duration: 0.25s; + transition-duration: 0.25s; + -webkit-transition-timing-function: ease-out; + -moz-transition-timing-function: ease-out; + transition-timing-function: ease-out; + -webkit-transition-delay: 0; + -moz-transition-delay: 0; + transition-delay: 0; + } + + html.csstransforms .sidebar-left { + /* performs better but native android browser + has problems with translate and percentage + @include transform( translateX(0) ); + */ + margin-left: -25px; + } + + html.csstransforms .sidebar-right { + /* performs better but native android browser + has problems with translate and percentage + @include transform( translateX(0) ); + */ + margin-right: -25px; + } + + /* If desktop is seeing mobile res, fix scrollbars */ + html.no-mobile-device body { + min-height: 0; + } + + html.no-mobile-device .body { + min-height: 100vh; + overflow: hidden; + } + + html.no-mobile-device .inner-wrapper { + overflow-y: auto; + } + + html.no-mobile-device.sidebar-left-opened, html.no-mobile-device.sidebar-left-opened body, html.no-mobile-device.sidebar-right-opened, html.no-mobile-device.sidebar-right-opened body { + overflow: hidden; + } + + /* Layout Mobile - Sidebar Left Opened */ + html.sidebar-left-opened.no-csstransforms .sidebar-left { + left: 0; + } + + html.sidebar-left-opened.csstransforms .sidebar-left { + /* performs better but native android browser + has problems with translate and percentage + @include transform( translateX(100%) ); + */ + margin-left: 100%; + } + + /* Layout Mobile - Sidebar Right Opened */ + html.sidebar-right-opened.no-csstransforms .sidebar-right { + right: 0; + } + + html.sidebar-right-opened.csstransforms .sidebar-right { + /* performs better but native android browser + has problems with translate and percentage + @include transform( translateX(-100%) ); + */ + margin-right: 100%; + } + + /* Layout Mobile - Sidebar Left Collapsed & Sidebar Right Opened */ + html.sidebar-left-collapsed.sidebar-right-opened .sidebar-left { + margin-left: -300px; + } +} +/* Content With Menu - Boxed Layout Fixing Spacement on Bottom */ +@media only screen and (min-width: 1200px) { + html.boxed .content-with-menu { + margin-bottom: -40px; + } +} +/* Content With Menu - Container */ +@media only screen and (min-width: 768px) { + .content-with-menu-container { + display: table; + table-layout: fixed; + width: 100%; + } +} +/* Content With Menu - Menu Faux Column for Scroll and Boxed Layouts */ +@media only screen and (min-width: 768px) { + html.scroll .content-with-menu:before, + html.boxed .content-with-menu:before { + bottom: -47px; + content: ''; + display: block; + left: 0; + position: absolute; + top: 54px; + width: 300px; + } + + html.scroll .content-with-menu:after, + html.boxed .content-with-menu:after { + bottom: -46px; + content: ''; + display: block; + left: -1px; + position: absolute; + top: 54px; + width: 1px; + z-index: 3; + } + + html.boxed .content-with-menu:before { + bottom: 0; + } + + html.boxed .content-with-menu:after { + bottom: 2px; + } +} + +.content-with-menu { + margin: -20px -15px 0; +} + +/* Content With Menu - Responsive */ +@media only screen and (max-width: 767px) { + .content-with-menu { + clear: both; + } + + .inner-body { + padding: 40px 15px 0; + } +} +/* Content With Menu - Menu and Body */ +@media only screen and (min-width: 768px) { + .content-with-menu { + border-top: 110px solid transparent; + margin: -150px -40px -53px -40px; + min-height: 100vh; + } + + .inner-menu { + display: table-cell; + vertical-align: top; + } + + .inner-body { + display: table-cell; + vertical-align: top; + padding: 40px; + } + + .inner-toolbar { + height: 52px; + overflow: hidden; + } + + .content-with-menu-has-toolbar .inner-menu-toggle { + border-radius: 0; + } + + .content-with-menu-has-toolbar .inner-toolbar { + padding-left: 140px; + } +} +/* Content With Menu - Flexbox supported */ +@media only screen and (min-width: 768px) { + html.flexbox .content-with-menu-container, + html.flexboxlegacy .content-with-menu-container { + display: -webkit-box; + display: -moz-box; + display: box; + display: -webkit-flex; + display: -moz-flex; + display: -ms-flexbox; + display: flex; + } + + html.flexbox .inner-menu, + html.flexbox .inner-body, + html.flexboxlegacy .inner-menu, + html.flexboxlegacy .inner-body { + display: block; + -webkit-flex-shrink: 0; + -moz-flex-shrink: 0; + flex-shrink: 0; + -ms-flex-negative: 0; + } + + html.flexbox .inner-body, + html.flexboxlegacy .inner-body { + -webkit-box-flex: 2; + -moz-box-flex: 2; + box-flex: 2; + -webkit-flex: 2; + -moz-flex: 2; + -ms-flex: 2; + flex: 2; + } +} +/* Content With Menu + Layout Fixed */ +@media only screen and (min-width: 768px) { + html.fixed .content-with-menu-container, + html.fixed .inner-menu, + html.fixed .inner-body { + display: block; + } + + html.fixed .content-with-menu-container { + position: relative; + } + + html.fixed .inner-menu-toggle { + position: absolute; + top: 114px; + border-radius: 0 0 5px 0; + width: 140px; + z-index: 1002; + } + + html.fixed .inner-menu { + bottom: 0; + display: block; + left: 300px; + position: fixed; + margin: 0; + top: 114px; + width: 300px; + padding: 35px; + z-index: 1002; + } + + html.fixed .inner-menu-content { + display: block; + } + + html.fixed .inner-body { + margin-left: 300px; + border-top: 113px solid transparent; + margin-top: -110px; + min-height: 100vh; + position: relative; + } + + html.fixed .content-with-menu-has-toolbar .inner-body { + border-top-width: 165px; + } +} +/* Content With Menu + Layout Scroll & Boxed */ +@media only screen and (min-width: 768px) { + html.scroll .inner-menu, + html.scroll .inner-body, + html.boxed .inner-menu, + html.boxed .inner-body { + display: block; + } + + html.scroll .content-with-menu-container, + html.boxed .content-with-menu-container { + position: relative; + } + + html.scroll .inner-menu-toggle, + html.boxed .inner-menu-toggle { + position: absolute; + top: 0; + border-radius: 0 0 5px 0; + width: 140px; + z-index: 3; + } + + html.scroll .inner-menu, + html.boxed .inner-menu { + display: block; + position: relative; + margin: 0; + width: 300px; + padding: 35px; + } + + html.scroll .inner-menu-content, + html.boxed .inner-menu-content { + display: block; + } + + html.scroll .inner-body, + html.boxed .inner-body { + margin-left: 0; + min-height: 100vh; + position: relative; + } + + html.scroll.flexbox .content-with-menu-container, html.scroll.flexboxlegacy .content-with-menu-container, + html.boxed.flexbox .content-with-menu-container, + html.boxed.flexboxlegacy .content-with-menu-container { + display: -webkit-box; + display: -moz-box; + display: box; + display: -webkit-flex; + display: -moz-flex; + display: -ms-flexbox; + display: flex; + } +} +/* Content With Menu + Layout Fixed + Sidebar Left Collapsed */ +@media only screen and (min-width: 768px) { + html.fixed.sidebar-left-collapsed .inner-menu, + html.fixed.sidebar-left-collapsed .inner-menu-toggle, + html.fixed.sidebar-left-collapsed .inner-toolbar { + left: 73px; + } + + html.fixed.sidebar-left-collapsed.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-collapsed.inner-menu-opened .inner-toolbar { + left: 373px; + } +} +/* Content With Menu + Layout Fixed + Sidebar Right Opened */ +@media only screen and (min-width: 768px) { + html.fixed.sidebar-right-opened .inner-menu, + html.fixed.sidebar-right-opened .inner-menu-toggle, + html.fixed.sidebar-right-opened .inner-toolbar { + left: 0px; + } + + html.fixed.sidebar-right-opened .inner-toolbar { + margin-right: 300px; + } + + html.fixed.sidebar-right-opened.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-right-opened.inner-menu-opened .inner-toolbar { + left: -300px; + } +} +/* Content With Menu + Layout Fixed + Sidebar Left Collapsed + Sidebar Right Opened */ +@media only screen and (min-width: 768px) { + html.fixed.sidebar-left-collapsed.sidebar-right-opened .inner-menu, + html.fixed.sidebar-left-collapsed.sidebar-right-opened .inner-menu-toggle, + html.fixed.sidebar-left-collapsed.sidebar-right-opened .inner-toolbar { + left: -227px; + } + + html.fixed.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .inner-toolbar { + left: -527px; + } +} +/* Resolution gt 767 and lt 1366 - Hide Inner Menu */ +@media only screen and (min-width: 768px) and (max-width: 1365px) { + html.fixed .inner-menu, + html.scroll .inner-menu, + html.boxed .inner-menu { + display: none; + } + + html.fixed .inner-menu-toggle, + html.scroll .inner-menu-toggle, + html.boxed .inner-menu-toggle { + display: block; + } + + html.fixed .inner-body, + html.scroll .inner-body, + html.boxed .inner-body { + margin-left: 0; + } + + html.fixed .content-with-menu-has-toolbar .inner-toolbar, + html.scroll .content-with-menu-has-toolbar .inner-toolbar, + html.boxed .content-with-menu-has-toolbar .inner-toolbar { + padding-left: 140px; + } + + html.fixed.inner-menu-opened .inner-menu, + html.scroll.inner-menu-opened .inner-menu, + html.boxed.inner-menu-opened .inner-menu { + display: block; + } + + html.fixed.inner-menu-opened .inner-menu-toggle, + html.scroll.inner-menu-opened .inner-menu-toggle, + html.boxed.inner-menu-opened .inner-menu-toggle { + display: none; + } + + html.fixed.inner-menu-opened .inner-body, + html.scroll.inner-menu-opened .inner-body, + html.boxed.inner-menu-opened .inner-body { + margin-right: -300px; + } + + html.fixed.inner-menu-opened .content-with-menu-has-toolbar .inner-toolbar, + html.scroll.inner-menu-opened .content-with-menu-has-toolbar .inner-toolbar, + html.boxed.inner-menu-opened .content-with-menu-has-toolbar .inner-toolbar { + padding-left: 0; + } + + html.fixed.inner-menu-opened .inner-body { + margin-left: 300px; + } + + html.scroll .content-with-menu:before, + html.boxed .content-with-menu:before { + display: none; + } + + html.scroll.inner-menu-opened:before, + html.boxed.inner-menu-opened:before { + display: block; + } +} +/* Resolution gt 1366 - Show Inner Menu */ +@media only screen and (min-width: 1366px) { + html.fixed .inner-menu, + html.scroll .inner-menu, + html.boxed .inner-menu { + display: block; + } + + html.fixed .inner-menu-toggle, + html.fixed .inner-menu-toggle-inside, + html.scroll .inner-menu-toggle, + html.scroll .inner-menu-toggle-inside, + html.boxed .inner-menu-toggle, + html.boxed .inner-menu-toggle-inside { + display: none; + } + + html.fixed .inner-body, + html.scroll .inner-body, + html.boxed .inner-body { + margin-right: 0; + } + + html.fixed .content-with-menu-has-toolbar .inner-toolbar, + html.scroll .content-with-menu-has-toolbar .inner-toolbar, + html.boxed .content-with-menu-has-toolbar .inner-toolbar { + padding-left: 0; + } + + html.fixed.inner-menu-opened .inner-body { + margin-left: 300px; + } + + html.fixed .content-with-menu .inner-toolbar, + html.fixed.inner-menu-opened .content-with-menu .inner-toolbar { + left: 600px; + } + + html.fixed .inner-menu-toggle, + html.fixed .inner-menu, + html.fixed.inner-menu-opened .inner-menu-toggle, + html.fixed.inner-menu-opened .inner-menu { + left: 300px; + } + + html.fixed.sidebar-right-opened .content-with-menu .inner-toolbar { + left: 300px; + } + + html.fixed.sidebar-right-opened .inner-menu, + html.fixed.sidebar-right-opened .inner-menu-toggle { + left: 0px; + } + + html.fixed.sidebar-left-collapsed .content-with-menu .inner-toolbar, + html.fixed.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .content-with-menu .inner-toolbar, + html.fixed.sidebar-left-collapsed.inner-menu-opened .content-with-menu .inner-toolbar { + left: 373px; + } + + html.fixed.sidebar-left-collapsed .inner-menu-toggle, + html.fixed.sidebar-left-collapsed .inner-menu, + html.fixed.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .inner-menu, + html.fixed.sidebar-left-collapsed.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-collapsed.inner-menu-opened .inner-menu { + left: 73px; + } + + html.fixed.sidebar-left-collapsed.sidebar-right-opened .content-with-menu .inner-toolbar { + left: 73px; + } + + html.fixed.sidebar-left-collapsed.sidebar-right-opened .inner-menu, + html.fixed.sidebar-left-collapsed.sidebar-right-opened .inner-menu-toggle { + left: -227px; + } +} +/* Fix IE Scrollbar Overlaying content */ +@-ms-viewport { + width: auto !important; +} +/* ------------------------------------------------------------------------------------------------------------------------------------------ +BOOTSTRAP EXTEND +------------------------------------------------------------------------------------------------------------------------------------------ */ +/* Add New Grid Tier FOR NON BOXED LAYOUT */ +html.scroll, +html.fixed { + /* UNDO original bootrap LG helper classes*/ + /* Helper classes for XL */; +} + +@media (min-width: 1600px) { + html.scroll .container, + html.fixed .container { + width: 1570px; + } +} + +html.scroll .col-xl-1, html.scroll .col-xl-2, html.scroll .col-xl-3, html.scroll .col-xl-4, html.scroll .col-xl-5, html.scroll .col-xl-6, html.scroll .col-xl-7, html.scroll .col-xl-8, html.scroll .col-xl-9, html.scroll .col-xl-10, html.scroll .col-xl-11, html.scroll .col-xl-12, +html.fixed .col-xl-1, +html.fixed .col-xl-2, +html.fixed .col-xl-3, +html.fixed .col-xl-4, +html.fixed .col-xl-5, +html.fixed .col-xl-6, +html.fixed .col-xl-7, +html.fixed .col-xl-8, +html.fixed .col-xl-9, +html.fixed .col-xl-10, +html.fixed .col-xl-11, +html.fixed .col-xl-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} + +@media (min-width: 1600px) { + html.scroll .col-xl-1, html.scroll .col-xl-2, html.scroll .col-xl-3, html.scroll .col-xl-4, html.scroll .col-xl-5, html.scroll .col-xl-6, html.scroll .col-xl-7, html.scroll .col-xl-8, html.scroll .col-xl-9, html.scroll .col-xl-10, html.scroll .col-xl-11, html.scroll .col-xl-12, + html.fixed .col-xl-1, + html.fixed .col-xl-2, + html.fixed .col-xl-3, + html.fixed .col-xl-4, + html.fixed .col-xl-5, + html.fixed .col-xl-6, + html.fixed .col-xl-7, + html.fixed .col-xl-8, + html.fixed .col-xl-9, + html.fixed .col-xl-10, + html.fixed .col-xl-11, + html.fixed .col-xl-12 { + float: left; + } + + html.scroll .col-xl-12, + html.fixed .col-xl-12 { + width: 100%; + } + + html.scroll .col-xl-11, + html.fixed .col-xl-11 { + width: 91.66666667%; + } + + html.scroll .col-xl-10, + html.fixed .col-xl-10 { + width: 83.33333333%; + } + + html.scroll .col-xl-9, + html.fixed .col-xl-9 { + width: 75%; + } + + html.scroll .col-xl-8, + html.fixed .col-xl-8 { + width: 66.66666667%; + } + + html.scroll .col-xl-7, + html.fixed .col-xl-7 { + width: 58.33333333%; + } + + html.scroll .col-xl-6, + html.fixed .col-xl-6 { + width: 50%; + } + + html.scroll .col-xl-5, + html.fixed .col-xl-5 { + width: 41.66666667%; + } + + html.scroll .col-xl-4, + html.fixed .col-xl-4 { + width: 33.33333333%; + } + + html.scroll .col-xl-3, + html.fixed .col-xl-3 { + width: 25%; + } + + html.scroll .col-xl-2, + html.fixed .col-xl-2 { + width: 16.66666667%; + } + + html.scroll .col-xl-1, + html.fixed .col-xl-1 { + width: 8.33333333%; + } + + html.scroll .col-xl-pull-12, + html.fixed .col-xl-pull-12 { + right: 100%; + } + + html.scroll .col-xl-pull-11, + html.fixed .col-xl-pull-11 { + right: 91.66666667%; + } + + html.scroll .col-xl-pull-10, + html.fixed .col-xl-pull-10 { + right: 83.33333333%; + } + + html.scroll .col-xl-pull-9, + html.fixed .col-xl-pull-9 { + right: 75%; + } + + html.scroll .col-xl-pull-8, + html.fixed .col-xl-pull-8 { + right: 66.66666667%; + } + + html.scroll .col-xl-pull-7, + html.fixed .col-xl-pull-7 { + right: 58.33333333%; + } + + html.scroll .col-xl-pull-6, + html.fixed .col-xl-pull-6 { + right: 50%; + } + + html.scroll .col-xl-pull-5, + html.fixed .col-xl-pull-5 { + right: 41.66666667%; + } + + html.scroll .col-xl-pull-4, + html.fixed .col-xl-pull-4 { + right: 33.33333333%; + } + + html.scroll .col-xl-pull-3, + html.fixed .col-xl-pull-3 { + right: 25%; + } + + html.scroll .col-xl-pull-2, + html.fixed .col-xl-pull-2 { + right: 16.66666667%; + } + + html.scroll .col-xl-pull-1, + html.fixed .col-xl-pull-1 { + right: 8.33333333%; + } + + html.scroll .col-xl-pull-0, + html.fixed .col-xl-pull-0 { + right: auto; + } + + html.scroll .col-xl-push-12, + html.fixed .col-xl-push-12 { + left: 100%; + } + + html.scroll .col-xl-push-11, + html.fixed .col-xl-push-11 { + left: 91.66666667%; + } + + html.scroll .col-xl-push-10, + html.fixed .col-xl-push-10 { + left: 83.33333333%; + } + + html.scroll .col-xl-push-9, + html.fixed .col-xl-push-9 { + left: 75%; + } + + html.scroll .col-xl-push-8, + html.fixed .col-xl-push-8 { + left: 66.66666667%; + } + + html.scroll .col-xl-push-7, + html.fixed .col-xl-push-7 { + left: 58.33333333%; + } + + html.scroll .col-xl-push-6, + html.fixed .col-xl-push-6 { + left: 50%; + } + + html.scroll .col-xl-push-5, + html.fixed .col-xl-push-5 { + left: 41.66666667%; + } + + html.scroll .col-xl-push-4, + html.fixed .col-xl-push-4 { + left: 33.33333333%; + } + + html.scroll .col-xl-push-3, + html.fixed .col-xl-push-3 { + left: 25%; + } + + html.scroll .col-xl-push-2, + html.fixed .col-xl-push-2 { + left: 16.66666667%; + } + + html.scroll .col-xl-push-1, + html.fixed .col-xl-push-1 { + left: 8.33333333%; + } + + html.scroll .col-xl-push-0, + html.fixed .col-xl-push-0 { + left: auto; + } + + html.scroll .col-xl-offset-12, + html.fixed .col-xl-offset-12 { + margin-left: 100%; + } + + html.scroll .col-xl-offset-11, + html.fixed .col-xl-offset-11 { + margin-left: 91.66666667%; + } + + html.scroll .col-xl-offset-10, + html.fixed .col-xl-offset-10 { + margin-left: 83.33333333%; + } + + html.scroll .col-xl-offset-9, + html.fixed .col-xl-offset-9 { + margin-left: 75%; + } + + html.scroll .col-xl-offset-8, + html.fixed .col-xl-offset-8 { + margin-left: 66.66666667%; + } + + html.scroll .col-xl-offset-7, + html.fixed .col-xl-offset-7 { + margin-left: 58.33333333%; + } + + html.scroll .col-xl-offset-6, + html.fixed .col-xl-offset-6 { + margin-left: 50%; + } + + html.scroll .col-xl-offset-5, + html.fixed .col-xl-offset-5 { + margin-left: 41.66666667%; + } + + html.scroll .col-xl-offset-4, + html.fixed .col-xl-offset-4 { + margin-left: 33.33333333%; + } + + html.scroll .col-xl-offset-3, + html.fixed .col-xl-offset-3 { + margin-left: 25%; + } + + html.scroll .col-xl-offset-2, + html.fixed .col-xl-offset-2 { + margin-left: 16.66666667%; + } + + html.scroll .col-xl-offset-1, + html.fixed .col-xl-offset-1 { + margin-left: 8.33333333%; + } + + html.scroll .col-xl-offset-0, + html.fixed .col-xl-offset-0 { + margin-left: 0; + } +} + +html.scroll .visible-xl, +html.fixed .visible-xl { + display: none !important; +} + +html.scroll .visible-xl-block, +html.scroll .visible-xl-inline, +html.scroll .visible-xl-inline-block, +html.fixed .visible-xl-block, +html.fixed .visible-xl-inline, +html.fixed .visible-xl-inline-block { + display: none !important; +} + +@media (min-width: 1200px) and (max-width: 1599px) { + html.scroll .visible-lg, + html.fixed .visible-lg { + display: block !important; + } + + html.scroll table.visible-lg, + html.fixed table.visible-lg { + display: table; + } + + html.scroll tr.visible-lg, + html.fixed tr.visible-lg { + display: table-row !important; + } + + html.scroll th.visible-lg, + html.scroll td.visible-lg, + html.fixed th.visible-lg, + html.fixed td.visible-lg { + display: table-cell !important; + } + + html.scroll .visible-lg-block, + html.fixed .visible-lg-block { + display: block !important; + } + + html.scroll .visible-lg-inline, + html.fixed .visible-lg-inline { + display: inline !important; + } + + html.scroll .visible-lg-inline-block, + html.fixed .visible-lg-inline-block { + display: inline-block !important; + } + + html.scroll .hidden-lg, + html.fixed .hidden-lg { + display: none !important; + } +} + +@media (min-width: 1600px) { + html.scroll .visible-lg-block, + html.fixed .visible-lg-block { + display: none !important; + } + + html.scroll .visible-lg-inline, + html.fixed .visible-lg-inline { + display: none !important; + } + + html.scroll .visible-lg-inline-block, + html.fixed .visible-lg-inline-block { + display: none !important; + } +} + +@media (min-width: 1600px) { + html.scroll .visible-xl, + html.fixed .visible-xl { + display: block !important; + } + + html.scroll table.visible-xl, + html.fixed table.visible-xl { + display: table; + } + + html.scroll tr.visible-xl, + html.fixed tr.visible-xl { + display: table-row !important; + } + + html.scroll th.visible-xl, + html.scroll td.visible-xl, + html.fixed th.visible-xl, + html.fixed td.visible-xl { + display: table-cell !important; + } + + html.scroll .visible-xl-block, + html.fixed .visible-xl-block { + display: block !important; + } + + html.scroll .visible-xl-inline, + html.fixed .visible-xl-inline { + display: inline !important; + } + + html.scroll .visible-xl-inline-block, + html.fixed .visible-xl-inline-block { + display: inline-block !important; + } + + html.scroll .hidden-xl, + html.fixed .hidden-xl { + display: none !important; + } +} + +@media screen and (max-width: 991px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: auto; + overflow-y: hidden; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + + .table-responsive > .table { + margin-bottom: 0; + } + + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + + .table-responsive > .table-bordered { + border: 0; + } + + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +/* Fix img-thumbnail - IE10 and below */ +.img-thumbnail { + width: auto \9; +} + +/* Header */ +.header { + background-color: #f6f6f6; + background-image: -webkit-linear-gradient(#f6f6f6 0%, white 45%); + background-image: linear-gradient(#f6f6f6 0%, white 45%); + border-bottom: 1px solid #E9E9E6; + border-top: 3px solid #EDEDED; + z-index: 1000; +} + +.header .logo { + float: left; + margin: 10px 0 0 15px; +} + +.header .logo img { + color: transparent; +} + +.header .separator { + background-color: #f6f6f6; + background-image: -webkit-linear-gradient(#f6f6f6 60%, #ededed); + background-image: linear-gradient(#f6f6f6 60%, #ededed); + display: inline-block; + height: 100%; + margin: 0 25px 0; + width: 2px; + vertical-align: middle; +} + +.header .search { + width: 170px; + display: inline-block; + vertical-align: middle; +} + +.header .toggle-sidebar-left { + background: #cccccc; + border-radius: 100px; + color: white; + height: 30px; + line-height: 30px; + position: absolute; + right: 15px; + text-align: center; + top: 14px; + width: 30px; +} + +.header-right { + float: right; + height: 56px; +} + +/* Header Mobile */ +@media only screen and (max-width: 767px) { + .header .logo-container { + background-color: #f6f6f6; + background-image: -webkit-linear-gradient(#f6f6f6 0%, white 45%); + background-image: linear-gradient(#f6f6f6 0%, white 45%); + border-bottom: 1px solid #E9E9E6; + border-top: 3px solid #EDEDED; + } + + .header .logo-container .logo { + float: none; + display: inline-block; + line-height: 57px; + margin-top: 0; + } + + .header .search, + .header .separator { + display: none; + } +} +/* Header Dark */ +html.dark .header, +html.header-dark .header { + background: #1d2127; + border-bottom-color: #161a1e; + border-top-color: #1d2127; +} + +@media only screen and (max-width: 767px) { + html.dark .header .logo-container, + html.header-dark .header .logo-container { + background: #1d2127; + border-bottom-color: #161a1e; + border-top-color: #1d2127; + } + + html.dark .header .header-right, + html.header-dark .header .header-right { + background: #1d2127; + } +} + +html.dark .header .separator, +html.header-dark .header .separator { + background-color: #1d2127; + background-image: -webkit-linear-gradient(#1d2127 10%, #121518); + background-image: linear-gradient(#1d2127 10%, #121518); +} + +html.dark .header .input-search input, html.dark .header .input-search input:focus, +html.header-dark .header .input-search input, +html.header-dark .header .input-search input:focus { + background: #282d36; + border-color: #161a1e; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.4) inset; + color: #FFF; +} + +html.dark .header .input-search .input-group-btn .btn-default, +html.header-dark .header .input-search .input-group-btn .btn-default { + background: transparent; + color: #c3c3c3; +} + +.sidebar-left { + z-index: 1010; +} + +.sidebar-left .sidebar-header { + position: relative; + color: #fff; + height: 50px; +} + +.sidebar-left .sidebar-header .sidebar-title { + color: #fff; + padding: 15px; + font-size: 15px; + font-size: 1.5rem; +} + +.sidebar-left .sidebar-header .sidebar-toggle { + position: absolute; + top: 0; + right: 0; + width: 73px; + height: 50px; + background-color: #07345a; + border-radius: 0 0 0 5px; + text-align: center; + cursor: pointer; +} + +.sidebar-left .sidebar-header .sidebar-toggle i { + color: #fff; + font-size: 17px; + font-size: 1.7rem; + line-height: 50px; + -webkit-transition: all 0.15s ease-in-out; + -moz-transition: all 0.15s ease-in-out; + transition: all 0.15s ease-in-out; +} + +.sidebar-left .sidebar-header .sidebar-toggle:hover i { + color: #cccccc; +} + +.sidebar-left hr.separator { + background: none; + margin: 20px 10px 20px; +} + +/* Unstyle nano for non fixed layouts */ +@media only screen and (min-width: 768px) { + html.scroll .sidebar-left .nano, + html.boxed .sidebar-left .nano { + position: static; + height: auto; + overflow: visible; + width: auto; + } + + html.scroll .sidebar-left .nano .nano-content, + html.boxed .sidebar-left .nano .nano-content { + margin-right: 0 !important; + position: static; + overflow: visible; + } + + html.scroll .sidebar-left .nano .nano-pane, + html.boxed .sidebar-left .nano .nano-pane { + display: none !important; + } + + html.boxed .sidebar-left .nano > .nano-content, + html.scroll .sidebar-left .nano > .nano-content { + overflow: visible !important; + } +} + +@media only screen and (min-width: 768px) { + html.sidebar-left-collapsed .sidebar-left .nano { + background: #0d4f88; + box-shadow: -5px 0 0 #428bca inset; + } + + html.sidebar-left-collapsed .sidebar-left .sidebar-title { + margin-left: -300px; + opacity: 0; + } + + html.sidebar-left-collapsed .sidebar-left .sidebar-toggle { + border-radius: 0; + } + + html.sidebar-left-collapsed .sidebar-left .nav-main > li > a { + overflow: hidden; + text-overflow: clip; + } + + html.sidebar-left-collapsed .sidebar-left .nav-main li.nav-parent a:after { + display: none; + } + + html.sidebar-left-collapsed .sidebar-left .nav-main li.nav-parent > ul.nav-children { + display: none; + } + + html.sidebar-left-collapsed .sidebar-left .nav-main a span { + visibility: hidden; + } + + html.sidebar-left-collapsed .sidebar-left .sidebar-widget, + html.sidebar-left-collapsed .sidebar-left .separator { + display: none; + } + + html.sidebar-left-collapsed .sidebar-left .nano:hover { + width: 300px; + } + + html.sidebar-left-collapsed .sidebar-left .nano:hover .nav-main .nav-expanded > ul.nav-children { + display: block; + } + + html.sidebar-left-collapsed .sidebar-left .nano:hover .nav-main li.nav-parent a:after { + display: inline-block; + } + + html.sidebar-left-collapsed .sidebar-left .nano:hover .nav-main li a span { + visibility: visible; + } + + html.sidebar-left-collapsed .sidebar-left .nano:hover .sidebar-widget, + html.sidebar-left-collapsed .sidebar-left .nano:hover .separator { + display: block; + } + + html.sidebar-left-collapsed.sidebar-left-opened .sidebar-left .nano { + width: 300px; + } + + html.sidebar-left-collapsed.sidebar-left-opened .sidebar-left .nano .nav-main .nav-expanded > ul.nav-children { + display: block; + } + + html.sidebar-left-collapsed.sidebar-left-opened .sidebar-left .nano .nav-main li.nav-parent a:after { + display: inline-block; + } + + html.sidebar-left-collapsed.sidebar-left-opened .sidebar-left .nano .nav-main li a span { + visibility: visible; + } + + html.sidebar-left-collapsed.sidebar-left-opened .sidebar-left .nano .sidebar-widget, + html.sidebar-left-collapsed.sidebar-left-opened .sidebar-left .nano .separator { + display: block; + } +} + +@media only screen and (max-width: 767px) { + /* Layout Mobile - Sidebar Left Collapsed & Sidebar Right Opened */ + html.sidebar-left-sm.sidebar-left-collapsed.sidebar-right-opened .sidebar-left { + margin-left: -250px; + } +} + +@media only screen and (min-width: 768px) { + /* Layout Base - Sidebar Left */ + html.sidebar-left-sm .sidebar-left { + width: 250px; + font-size: 12px; + font-size: 1.2rem; + } + + html.sidebar-left-sm .sidebar-left ul.nav-main li i { + font-size: 16px; + font-size: 1.6rem; + } + + html.sidebar-left-sm .sidebar-left ul.nav-main li a { + font-size: 12px; + font-size: 1.2rem; + } + + html.sidebar-left-sm .sidebar-left .sidebar-widget .widget-header h6 { + font-size: 12px; + font-size: 1.2rem; + } + + html.sidebar-left-sm.sidebar-left-collapsed .sidebar-left .sidebar-title { + margin-left: -250px; + } + + html.sidebar-left-sm.sidebar-left-collapsed.fixed .sidebar-left .nano:hover { + width: 250px; + } + + /* Layout Base - Sidebar Left Opened ( Larger than mobile ) */ + html.sidebar-left-sm.sidebar-left-collapsed .sidebar-left { + width: 73px; + } + + /* Layout Fixed - Content Body */ + html.fixed.sidebar-left-sm .content-body { + margin-left: 250px; + } + + /* Layout Fixed - Page header */ + html.fixed.sidebar-left-sm .page-header { + left: 250px; + } + + /* Layout Fixed - Sidebar Right Opened */ + html.fixed.sidebar-left-sm.sidebar-right-opened .page-header { + left: 0; + } + + html.fixed.sidebar-left-sm.sidebar-right-opened .sidebar-left { + left: -250px; + } + + /* Layout Fixed - Sidebar Left Collapsed */ + html.fixed.sidebar-left-collapsed .page-header { + left: 73px; + } + + html.fixed.sidebar-left-collapsed .content-body { + margin-left: 73px; + } + + /* Layout Fixed - Sidebar Left Collapsed & Sidebar Right Opened */ + html.fixed.sidebar-left-sm.sidebar-left-collapsed.sidebar-right-opened .page-header { + left: -250px; + } + + /* Content With Menu + Layout Fixed */ + html.fixed.sidebar-left-sm .inner-menu { + left: 250px; + } + + /* Content With Menu + Layout Fixed + Sidebar Left Collapsed */ + html.fixed.sidebar-left-sm.sidebar-left-collapsed .inner-menu, + html.fixed.sidebar-left-sm.sidebar-left-collapsed .inner-menu-toggle, + html.fixed.sidebar-left-sm.sidebar-left-collapsed .inner-toolbar { + left: 73px; + } + + html.fixed.sidebar-left-sm.sidebar-left-collapsed.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-sm.sidebar-left-collapsed.inner-menu-opened .inner-toolbar { + left: 373px; + } + + /* Content With Menu + Layout Fixed + Sidebar Right Opened */ + html.fixed.sidebar-left-sm.sidebar-right-opened .inner-menu, + html.fixed.sidebar-left-sm.sidebar-right-opened .inner-menu-toggle, + html.fixed.sidebar-left-sm.sidebar-right-opened .inner-toolbar { + left: -50px; + } + + html.fixed.sidebar-left-sm.sidebar-right-opened.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-sm.sidebar-right-opened.inner-menu-opened .inner-toolbar { + left: -350px; + } + + /* Content With Menu - Toolbar + Layout Fixed */ + html.fixed.sidebar-left-sm.inner-menu-opened { + left: 550px; + } + + html.fixed.sidebar-left-sm .inner-menu-toggle { + left: 250px; + } +} +/* Resolution gt 1366 - Show Inner Menu */ +@media only screen and (min-width: 1366px) { + html.fixed.sidebar-left-sm .content-with-menu .inner-toolbar, + html.fixed.sidebar-left-sm.inner-menu-opened .content-with-menu .inner-toolbar { + left: 550px; + } + + html.fixed.sidebar-left-sm .inner-menu-toggle, + html.fixed.sidebar-left-sm .inner-menu, + html.fixed.sidebar-left-sm.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-sm.inner-menu-opened .inner-menu { + left: 250px; + } + + html.fixed.sidebar-left-sm.sidebar-right-opened .content-with-menu .inner-toolbar { + left: 250px; + } + + html.fixed.sidebar-left-sm.sidebar-right-opened .inner-menu, + html.fixed.sidebar-left-sm.sidebar-right-opened .inner-menu-toggle { + left: -50px; + } + + html.fixed.sidebar-left-sm.sidebar-left-collapsed .content-with-menu .inner-toolbar, + html.fixed.sidebar-left-sm.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .content-with-menu .inner-toolbar, + html.fixed.sidebar-left-sm.sidebar-left-collapsed.inner-menu-opened .content-with-menu .inner-toolbar { + left: 373px; + } + + html.fixed.sidebar-left-sm.sidebar-left-collapsed .inner-menu-toggle, + html.fixed.sidebar-left-sm.sidebar-left-collapsed .inner-menu, + html.fixed.sidebar-left-sm.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-sm.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .inner-menu, + html.fixed.sidebar-left-sm.sidebar-left-collapsed.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-sm.sidebar-left-collapsed.inner-menu-opened .inner-menu { + left: 73px; + } + + html.fixed.sidebar-left-sm.sidebar-left-collapsed.sidebar-right-opened .content-with-menu .inner-toolbar { + left: 73px; + } + + html.fixed.sidebar-left-sm.sidebar-left-collapsed.sidebar-right-opened .inner-menu, + html.fixed.sidebar-left-sm.sidebar-left-collapsed.sidebar-right-opened .inner-menu-toggle { + left: -227px; + } +} + +@media only screen and (max-width: 767px) { + /* Layout Mobile - Sidebar Left Collapsed & Sidebar Right Opened */ + html.sidebar-left-xs.sidebar-left-collapsed.sidebar-right-opened .sidebar-left { + margin-left: -200px; + } +} + +@media only screen and (min-width: 768px) { + /* Layout Base - Sidebar Left */ + html.sidebar-left-xs .sidebar-left { + width: 200px; + font-size: 11px; + font-size: 1.1rem; + } + + html.sidebar-left-xs .sidebar-left ul.nav-main li i { + font-size: 14px; + font-size: 1.4rem; + } + + html.sidebar-left-xs .sidebar-left ul.nav-main li a { + font-size: 11px; + font-size: 1.1rem; + } + + html.sidebar-left-xs .sidebar-left ul.nav-main li .nav-children li a { + padding-left: 52px; + } + + html.sidebar-left-xs .sidebar-left .sidebar-widget .widget-header h6 { + font-size: 11px; + font-size: 1.1rem; + } + + html.sidebar-left-xs.sidebar-left-collapsed .sidebar-left .sidebar-title { + margin-left: -200px; + } + + html.sidebar-left-xs.sidebar-left-collapsed.fixed .sidebar-left .nano:hover { + width: 200px; + } + + /* Layout Base - Sidebar Left Opened ( Larger than mobile ) */ + html.sidebar-left-xs.sidebar-left-collapsed .sidebar-left { + width: 73px; + } + + /* Layout Fixed - Content Body */ + html.fixed.sidebar-left-xs .content-body { + margin-left: 200px; + } + + /* Layout Fixed - Page header */ + html.fixed.sidebar-left-xs .page-header { + left: 200px; + } + + /* Layout Fixed - Sidebar Right Opened */ + html.fixed.sidebar-left-xs.sidebar-right-opened .page-header { + left: 0; + } + + html.fixed.sidebar-left-xs.sidebar-right-opened .sidebar-left { + left: -200px; + } + + /* Layout Fixed - Sidebar Left Collapsed */ + html.fixed.sidebar-left-collapsed .page-header { + left: 73px; + } + + html.fixed.sidebar-left-collapsed .content-body { + margin-left: 73px; + } + + /* Layout Fixed - Sidebar Left Collapsed & Sidebar Right Opened */ + html.fixed.sidebar-left-xs.sidebar-left-collapsed.sidebar-right-opened .page-header { + left: -200px; + } + + /* Content With Menu + Layout Fixed */ + html.fixed.sidebar-left-xs .inner-menu { + left: 200px; + } + + /* Content With Menu + Layout Fixed + Sidebar Left Collapsed */ + html.fixed.sidebar-left-xs.sidebar-left-collapsed .inner-menu, + html.fixed.sidebar-left-xs.sidebar-left-collapsed .inner-menu-toggle, + html.fixed.sidebar-left-xs.sidebar-left-collapsed .inner-toolbar { + left: 73px; + } + + html.fixed.sidebar-left-xs.sidebar-left-collapsed.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-xs.sidebar-left-collapsed.inner-menu-opened .inner-toolbar { + left: 373px; + } + + /* Content With Menu + Layout Fixed + Sidebar Right Opened */ + html.fixed.sidebar-left-xs.sidebar-right-opened .inner-menu, + html.fixed.sidebar-left-xs.sidebar-right-opened .inner-menu-toggle, + html.fixed.sidebar-left-xs.sidebar-right-opened .inner-toolbar { + left: -100px; + } + + html.fixed.sidebar-left-xs.sidebar-right-opened.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-xs.sidebar-right-opened.inner-menu-opened .inner-toolbar { + left: -400px; + } + + /* Content With Menu - Toolbar + Layout Fixed */ + html.fixed.sidebar-left-xs.inner-menu-opened { + left: 500px; + } + + html.fixed.sidebar-left-xs .inner-menu-toggle { + left: 200px; + } +} +/* Resolution gt 1366 - Show Inner Menu */ +@media only screen and (min-width: 1366px) { + html.fixed.sidebar-left-xs .content-with-menu .inner-toolbar, + html.fixed.sidebar-left-xs.inner-menu-opened .content-with-menu .inner-toolbar { + left: 500px; + } + + html.fixed.sidebar-left-xs .inner-menu-toggle, + html.fixed.sidebar-left-xs .inner-menu, + html.fixed.sidebar-left-xs.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-xs.inner-menu-opened .inner-menu { + left: 200px; + } + + html.fixed.sidebar-left-xs.sidebar-right-opened .content-with-menu .inner-toolbar { + left: 200px; + } + + html.fixed.sidebar-left-xs.sidebar-right-opened .inner-menu, + html.fixed.sidebar-left-xs.sidebar-right-opened .inner-menu-toggle { + left: -100px; + } + + html.fixed.sidebar-left-xs.sidebar-left-collapsed .content-with-menu .inner-toolbar, + html.fixed.sidebar-left-xs.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .content-with-menu .inner-toolbar, + html.fixed.sidebar-left-xs.sidebar-left-collapsed.inner-menu-opened .content-with-menu .inner-toolbar { + left: 373px; + } + + html.fixed.sidebar-left-xs.sidebar-left-collapsed .inner-menu-toggle, + html.fixed.sidebar-left-xs.sidebar-left-collapsed .inner-menu, + html.fixed.sidebar-left-xs.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-xs.sidebar-left-collapsed.sidebar-right-opened.inner-menu-opened .inner-menu, + html.fixed.sidebar-left-xs.sidebar-left-collapsed.inner-menu-opened .inner-menu-toggle, + html.fixed.sidebar-left-xs.sidebar-left-collapsed.inner-menu-opened .inner-menu { + left: 73px; + } + + html.fixed.sidebar-left-xs.sidebar-left-collapsed.sidebar-right-opened .content-with-menu .inner-toolbar { + left: 73px; + } + + html.fixed.sidebar-left-xs.sidebar-left-collapsed.sidebar-right-opened .inner-menu, + html.fixed.sidebar-left-xs.sidebar-left-collapsed.sidebar-right-opened .inner-menu-toggle { + left: -227px; + } +} +/* Sidebar Right */ +.sidebar-right { + z-index: 1010; +} + +.sidebar-right .sidebar-right-wrapper { + padding: 20px; +} + +.sidebar-right h6 { + margin: 0; + color: #777777; + text-transform: uppercase; + font-size: 12px; + font-size: 1.2rem; + font-weight: 600; +} + +.sidebar-right .mobile-close { + background: #000; + color: #999; + left: 0; + line-height: 50px; + padding-left: 20px; + position: relative; + overflow: hidden; + width: 100%; + text-align: left; + text-decoration: none; +} + +.sidebar-right .mobile-close i { + margin-left: 5px; + vertical-align: middle; +} + +.sidebar-right .mobile-close:after { + box-shadow: 0 0px 3px 0 rgba(255, 255, 255, 0.7); + bottom: -1px; + content: ''; + display: block; + height: 1px; + left: 0; + position: absolute; + right: 0; +} + +/* If desktop is seeing mobile res, fix scrollbars */ +@media only screen and (max-width: 767px) { + html.no-mobile-device.custom-scroll .sidebar-right .nano > .nano-content { + overflow: scroll; + overflow-x: hidden; + } +} +/* Content With Menu - Menu Faux Column for Scroll and Boxed Layouts Colors */ +@media only screen and (min-width: 768px) { + html.scroll .content-with-menu:before, + html.boxed .content-with-menu:before { + background: #1d2127; + } + + html.scroll .content-with-menu:after, + html.boxed .content-with-menu:after { + background: #000; + box-shadow: 0px 0 4px 2px rgba(0, 0, 0, 0.5); + } +} +/* Unstyle nano for non fixed layouts */ +html.scroll .inner-menu .nano, html.scroll.no-overflowscrolling.custom-scroll .inner-menu .nano, +html.boxed .inner-menu .nano, +html.boxed.no-overflowscrolling.custom-scroll .inner-menu .nano { + position: static; + height: auto; + overflow: visible; + width: auto; +} + +html.scroll .inner-menu .nano > .nano-content, html.scroll.no-overflowscrolling.custom-scroll .inner-menu .nano > .nano-content, +html.boxed .inner-menu .nano > .nano-content, +html.boxed.no-overflowscrolling.custom-scroll .inner-menu .nano > .nano-content { + position: static; + overflow: visible; +} + +@media only screen and (max-width: 767px) { + html.fixed .inner-menu .nano { + position: static; + height: auto; + overflow: visible; + width: auto; + } + + html.fixed .inner-menu .nano .nano-content { + margin-right: 0; + position: static; + overflow: visible; + } +} +/* Fix padding when fixed */ +@media only screen and (min-width: 768px) { + html.fixed .inner-menu { + padding: 0; + } + + html.fixed .inner-menu .nano-content { + padding: 35px; + } + + html.fixed .inner-menu .nano-content:after { + display: block; + content: ''; + height: 35px; + } +} +/* Content With Menu - Inner Menu Style */ +.inner-menu { + background: #1d2127; + border-right: 1px solid #242830; + color: #abb4be; + padding: 0; + margin: 0; +} + +.inner-menu .title { + color: #465162; + font-weight: 600; + margin: 10px 0; + padding: 0; + text-transform: uppercase; +} + +.inner-menu hr.separator { + background-image: -webkit-linear-gradient(left, transparent, rgba(0, 0, 0, 0.4), transparent); + background-image: -moz-linear-gradient(left, transparent, rgba(0, 0, 0, 0.4), transparent); + background-image: -ms-linear-gradient(left, transparent, rgba(0, 0, 0, 0.4), transparent); + background-image: -o-linear-gradient(left, transparent, rgba(0, 0, 0, 0.4), transparent); + margin: 20px -35px 20px; +} + +.inner-menu a, +.inner-menu a:hover { + color: #abb4be; +} + +.inner-menu a.menu-item { + color: #abb4be; + display: block; + margin: 0 -35px 0 -35px; + padding: 10px 50px 10px 50px; + text-decoration: none; +} + +.inner-menu a.menu-item:hover { + background: #21262d; + color: #abb4be; + text-decoration: none; +} + +.inner-menu a.menu-item.active { + background: #282d36; +} + +.inner-menu a.menu-item .label { + font-weight: normal; + font-size: 10px; + font-size: 1rem; + padding: .3em .7em .4em; + margin: .2em -1em 0 0; +} + +/* Content With Menu - Toggle */ +.inner-menu-toggle, +.inner-menu .inner-menu-toggle-inside { + background: #000; + color: #999; + left: 0; + line-height: 52px; + position: relative; + overflow: hidden; + text-align: left; + text-decoration: none; +} + +.inner-menu-toggle:after, +.inner-menu .inner-menu-toggle-inside:after { + box-shadow: 0 0px 3px 0 rgba(255, 255, 255, 0.7); + bottom: -1px; + content: ''; + display: block; + height: 1px; + left: 0; + position: absolute; + right: 0; +} + +.inner-menu-toggle a, +.inner-menu .inner-menu-toggle-inside a { + display: block; + padding-left: 20px; + text-decoration: none; +} + +.inner-menu-toggle a i, +.inner-menu .inner-menu-toggle-inside a i { + vertical-align: middle; +} + +.inner-menu-toggle .inner-menu-collapse, +.inner-menu .inner-menu-toggle-inside .inner-menu-collapse { + display: none; +} + +.inner-menu-toggle a i { + margin-left: 5px; +} + +.inner-menu-toggle-inside { + margin: -35px -35px 15px -35px; +} + +.inner-menu-toggle-inside .inner-menu-collapse i { + margin-right: 5px; +} + +.inner-menu-toggle-inside .inner-menu-expand i { + margin-left: 5px; +} + +/* Content With Menu - Toggle - Outside */ +.inner-menu-toggle { + display: none; +} + +/* Content With Menu - Inner Menu Content */ +.inner-menu-content { + display: none; +} + +html.inner-menu-opened .inner-menu .inner-menu-toggle-inside .inner-menu-collapse { + display: block; +} + +html.inner-menu-opened .inner-menu-expand { + display: none; +} + +html.inner-menu-opened .inner-menu-content { + display: block; +} + +/* Content With Menu - Responsive */ +@media only screen and (max-width: 767px) { + .inner-menu .hidden-xs-inline { + display: none; + } + + .inner-menu .inner-menu-content { + padding: 20px; + } + + .inner-menu-toggle-inside { + margin: 0; + } +} +/* Content With Menu - Toolbar + Layout Fixed */ +@media only screen and (min-width: 768px) { + html.fixed.inner-menu-opened { + left: 600px; + } + + html.fixed .inner-menu-toggle { + position: fixed; + left: 300px; + } +} + +html.dark .inner-menu-toggle:after, +html.dark .inner-menu .inner-menu-toggle-inside:after { + box-shadow: none; +} + +ul.nav-main { + margin-right: 5px; +} + +ul.nav-main > li > a { + padding: 12px 25px; +} + +ul.nav-main > li > a:hover, ul.nav-main > li > a:focus { + background-color: #21262d; +} + +ul.nav-main > li.nav-active > a { + box-shadow: 2px 0 0 #cccccc inset; +} + +ul.nav-main > li.nav-active > a:hover { + color: #abb4be; +} + +ul.nav-main > li.nav-active > i { + color: #cccccc; +} + +ul.nav-main > li.nav-expanded > a { + background: #21262d; +} + +ul.nav-main li a { + font-size: 13px; + font-size: 1.3rem; + color: #fff; + white-space: nowrap; + text-overflow: ellipsis; +} + +ul.nav-main li a span.label { + font-weight: normal; + font-size: 10px; + font-size: 1rem; + padding: .3em .7em .4em; + margin: .4em -1em 0 0; +} + +ul.nav-main li a .not-included { + font-style: normal; + color: #505b67; + display: inline-block; + padding: 0 0 0 6px; +} + +ul.nav-main li span { + vertical-align: middle; +} + +ul.nav-main li i { + font-size: 18px; + font-size: 1.8rem; + width: 1.1em; + margin-right: 0.5em; + text-align: center; + vertical-align: middle; +} + +ul.nav-main li.nav-parent { + position: relative; +} + +ul.nav-main li.nav-parent > a { + cursor: pointer; +} + +ul.nav-main li.nav-parent > a:after { + font-family: 'FontAwesome'; + content: '\f107'; + font-size: 16px; + font-size: 1.6rem; + color: #abb4be; + position: absolute; + right: 0; + top: 0; + padding: 14px 25px; +} + +ul.nav-main li.nav-parent.nav-expanded > a:after { + content: '\f106'; +} + +ul.nav-main li.nav-parent.nav-expanded > ul.nav-children { + display: block; +} + +ul.nav-main li .nav-children { + background: #191c21; + box-shadow: 0px -3px 3px -3px rgba(0, 0, 0, 0.7) inset; + display: none; + padding: 10px 0; +} + +ul.nav-main li .nav-children li a { + padding: 6px 15px 6px 57px; + overflow: hidden; +} + +ul.nav-main li .nav-children li a:hover, ul.nav-main li .nav-children li a:focus { + background: #191c21; +} + +ul.nav-main li .nav-children li a:after { + padding: 6px 25px; +} + +ul.nav-main li .nav-children li.nav-active > a { + color: #cccccc; +} + +ul.nav-main li .nav-children .nav-children { + box-shadow: none; + padding: 0; +} + +ul.nav-main li .nav-children .nav-children li a { + padding: 6px 15px 6px 82px; +} + +ul.nav-main li .nav-children .nav-children .nav-children li a { + padding: 6px 15px 6px 97px; +} + +/* Page Header */ +.page-header { + z-index: 1001; +} + +.page-header h2 { + color: #FFF; + border-bottom: 4px solid #5bc0de; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + display: inline-block; + float: left; + height: 50px; + font-size: 20px; + font-size: 2rem; + letter-spacing: normal; + line-height: 50px; + margin: 0 0 0 -1px; + padding: 0 22px 0 20px; +} + +.page-header .right-wrapper { + float: right; +} + +.page-header .breadcrumbs { + display: inline-block; + font-size: 0; + line-height: 50px; + margin: 0; + padding: 0; +} + +.page-header .breadcrumbs li { + color: #c3c3c3; + display: inline-block; + font-weight: 300; +} + +.page-header .breadcrumbs li:after { + content: '/'; + display: inline-block; + font-size: 14px; + font-size: 1.4rem; + margin: 0 10px; + vertical-align: middle; +} + +.page-header .breadcrumbs li:last-child:after { + display: none; +} + +.page-header .breadcrumbs .fa-home { + font-size: 20px; + font-size: 2rem; +} + +.page-header .breadcrumbs i { + vertical-align: middle; +} + +.page-header .breadcrumbs a, +.page-header .breadcrumbs span { + color: #c3c3c3; + display: inline-block; + font-size: 14px; + font-size: 1.4rem; + line-height: 20px; + vertical-align: middle; +} + +.page-header .sidebar-right-toggle { + cursor: pointer; + color: #c3c3c3; + display: inline-block; + font-size: 17px; + margin: 0 0 0 10px; + height: 50px; + width: 50px; + vertical-align: top; + text-align: center; + -webkit-transition: all 0.15s ease-in-out; + -moz-transition: all 0.15s ease-in-out; + transition: all 0.15s ease-in-out; +} + +.page-header .sidebar-right-toggle i { + line-height: 53px; + vertical-align: middle; +} + +.page-header .sidebar-right-toggle:hover { + color: #cccccc; +} + +/* Header Dark - Page Header */ +html.dark .page-header, +html.header-dark .page-header { + border-left-color: #171717; + box-shadow: 1px 3px 0 1px #2f3139; +} + +html.sidebar-right-opened .page-header .sidebar-right-toggle i:before { + content: "\f054"; +} + +/* Page Header - Mobile */ +@media only screen and (max-width: 767px) { + .page-header { + padding-right: 80px; + } + + .page-header .breadcrumbs { + display: none; + } + + .page-header h2 { + font-size: 16px; + padding: 0 15px 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + max-width: 100%; + } + + .page-header .sidebar-right-toggle { + position: absolute; + right: 0; + top: 0; + } +} +/* Headings */ +h1, +h2, +h3, +.h1, +.h2, +.h3 { + letter-spacing: -1px; +} + +h1, +.h1 { + font-size: 36px; + font-size: 3.6rem; +} + +h2, +.h2 { + font-size: 30px; + font-size: 3rem; +} + +h3, +.h3 { + font-size: 24px; + font-size: 2.4rem; +} + +h4, +.h4 { + font-size: 18px; + font-size: 1.8rem; +} + +h5, +.h5 { + font-size: 14px; + font-size: 1.4rem; +} + +h6, +.h6 { + font-size: 12px; + font-size: 1.2rem; + letter-spacing: 0; +} + +/* Alternative Font Style */ +.alternative-font { + color: #cccccc; + font-family: "Shadows Into Light", cursive; + font-size: 1.6em; +} + +/* Drop Caps */ +p.drop-caps:first-child:first-letter { + float: left; + font-size: 75px; + line-height: 60px; + padding: 4px; + margin-right: 5px; + margin-top: 5px; + font-family: Georgia; + color: #171717; +} + +p.drop-caps.secundary:first-child:first-letter { + background-color: #171717; + color: #FFF; + padding: 6px; + margin-right: 5px; + border-radius: 4px; +} + +p.drop-caps.colored:first-child:first-letter { + color: #cccccc; +} + +p.drop-caps.colored.secundary:first-child:first-letter { + background-color: #cccccc; + color: #FFF; +} + +/* Blockquote */ +blockquote { + font-size: 1em; +} + +/* Hightlight */ +.highlight { + background-color: #cccccc; + color: #FFF; + padding: 3px 6px; +} + +/* Divider Line */ +hr { + border: 0; + height: 1px; + background-image: -webkit-linear-gradient(left, transparent, rgba(0, 0, 0, 0.2), transparent); + background-image: -moz-linear-gradient(left, transparent, rgba(0, 0, 0, 0.2), transparent); + background-image: -ms-linear-gradient(left, transparent, rgba(0, 0, 0, 0.2), transparent); + background-image: -o-linear-gradient(left, transparent, rgba(0, 0, 0, 0.2), transparent); + margin: 22px 0 22px 0; +} + +hr.short { + margin: 11px 0 11px 0; +} + +hr.tall { + margin: 44px 0 44px 0; +} + +hr.taller { + margin: 66px 0 66px 0; +} + +hr.light { + background-image: -webkit-linear-gradient(left, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)); + background-image: -moz-linear-gradient(left, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)); + background-image: -ms-linear-gradient(left, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)); + background-image: -o-linear-gradient(left, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0)); +} + +hr.dotted { + height: 0; + border-bottom: 1px dotted #ddd; +} + +hr.solid { + height: 0; + border-bottom: 1px solid #ddd; +} + +/* Buttons Icon */ +.btn-icon i { + margin-right: 10px; +} + +.btn-icon-right i { + margin-right: 0; + margin-left: 10px; +} + +/* Form Elements */ +input { + outline: none; +} + +label { + font-weight: normal; +} + +textarea { + resize: vertical; +} + +textarea[data-toggle=autosize] { + -webkit-transition: height 0.15s ease-in; + -moz-transition: height 0.15s ease-in; + transition: height 0.15s ease-in; +} + +select { + border: 1px solid #E5E7E9; + border-radius: 6px; + height: 46px; + padding: 12px; + outline: none; +} + +/* Forms Validations */ +label.valid { + display: inline-block; + text-indent: -9999px; +} + +label.error { + color: #C10000; + font-size: 0.9em; + margin-top: -5px; + padding: 0; +} + +/* Miscellaneous */ +body a, body a:focus, body a:hover, body a:active, body a:visited { + outline: none !important; +} + +.center { + text-align: center; +} + +ul, +ol { + margin-bottom: 0; + padding-left: 27px; +} + +blockquote.primary { + border-color: #cccccc; +} + +blockquote.success { + border-color: #47a447; +} + +blockquote.warning { + border-color: #ed9c28; +} + +blockquote.danger { + border-color: #d2322d; +} + +blockquote.info { + border-color: #5bc0de; +} + +blockquote.dark { + border-color: #171717; +} + +.well.primary { + background: #cccccc; + border-color: #b3b3b3; + color: white; +} + +.well.success { + background: #47a447; + border-color: #388038; + color: white; +} + +.well.warning { + background: #ed9c28; + border-color: #d18211; + color: white; +} + +.well.danger { + background: #d2322d; + border-color: #a82824; + color: white; +} + +.well.info { + background: #5bc0de; + border-color: #31b0d5; + color: white; +} + +.well.dark { + background: #171717; + border-color: black; + color: white; +} + +/* Arrows */ +.arrow { + background: transparent url(../images/arrows.png) no-repeat 0 0; + width: 47px; + height: 120px; + display: inline-block; + position: relative; +} + +.arrow.vtl { + background-position: 0 0; + width: 47px; + height: 96px; +} + +.arrow.vtr { + background-position: -101px 0; + width: 47px; + height: 96px; +} + +.arrow.vbl { + background-position: 0 -144px; + width: 47px; + height: 96px; +} + +.arrow.vbr { + background-position: -101px -144px; + width: 47px; + height: 96px; +} + +.arrow.hlt { + background-position: -209px 0; + width: 120px; + height: 47px; +} + +.arrow.hlb { + background-position: -209px -101px; + width: 120px; + height: 47px; +} + +.arrow.hrt { + background-position: -353px 0; + width: 120px; + height: 47px; +} + +.arrow.hrb { + background-position: -353px -101px; + width: 120px; + height: 47px; +} + +.img-thumbnail { + border-radius: 8px; + position: relative; +} + +.img-thumbnail .zoom { + display: block; + position: absolute; + right: 8px; + bottom: 8px; + height: 30px; + width: 30px; + padding: 6px; + font-size: 14px; + line-height: 18px; + background: #CCC; + border-radius: 100%; + color: #FFF; + text-align: center; +} + +.img-thumbnail .zoom i { + position: relative; + top: -1px; + left: -1px; +} + +/* Thumbnail Gallery */ +.thumbnail-gallery { + list-style: none; + margin: 10px 0; + padding: 0; +} + +.thumbnail-gallery .img-thumbnail, +.thumbnail-gallery .thumbnail { + margin: 10px 10px 0 0; +} + +/* Navs */ +ul.nav-list.primary > li { + margin: 0; + padding: 0; +} + +ul.nav-list.primary > li:last-child a { + border-bottom: transparent !important; +} + +ul.nav-list.primary > li a { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + transition: all 0.3s; + background-position: 9px 16px; + background-repeat: no-repeat; + border-bottom: 1px solid #EDEDDE; + padding: 8px 20px; +} + +.changelog h4 { + display: inline-block; + color: #000; + font-size: 1em; + font-weight: 600; +} + +.changelog .release-date { + color: #999; + font-size: 0.9em; +} + +.changelog .label { + display: inline-block; + min-width: 100px; +} + +.scrollable { + overflow: hidden; + position: relative; + width: 100%; +} + +.scrollable .scrollable-content { + bottom: 0; + left: 0; + overflow: hidden; + position: absolute; + right: 0; + top: 0; + padding: 0 37px 0 0; + overflow-x: hidden; + overflow-y: scroll; +} + +.scrollable .scrollable-content::-webkit-scrollbar { + visibility: hidden; +} + +.scrollable .scrollable-pane { + bottom: 0; + opacity: 0.01; + position: absolute; + right: 5px; + top: 0; + transition: all 0.2s ease 0s; + width: 4px; +} + +.scrollable .scrollable-slider { + border-radius: 5px; + background: none repeat scroll 0 0 #CCC; + margin: 0; + position: relative; + transition: opacity 0.2s ease 0s; + opacity: 0; +} + +.scrollable.scrollable-padding .scrollable-content { + padding: 10px 24px 10px 10px; +} + +.scrollable:hover .scrollable-slider, .scrollable.visible-slider .scrollable-slider { + opacity: 1; +} + +.text-xs { + font-size: 10px; + font-size: 1rem; +} + +.text-sm { + font-size: 13px; + font-size: 1.3rem; +} + +.text-md { + font-size: 16px; + font-size: 1.6rem; +} + +.text-lg { + font-size: 19px; + font-size: 1.9rem; +} + +.text-xl { + font-size: 22px; + font-size: 2.2rem; +} + +.text-muted { + color: #999999 !important; +} + +html.dark .text-muted { + color: #505461 !important; +} + +.text-primary { + color: #cccccc !important; +} + +.text-secondary { + color: #e36159 !important; +} + +.text-tertiary { + color: #2baab1 !important; +} + +.text-quartenary { + color: #734ba9 !important; +} + +.text-success { + color: #47a447 !important; +} + +.text-warning { + color: #ed9c28 !important; +} + +.text-danger { + color: #d2322d !important; +} + +.text-info { + color: #5bc0de !important; +} + +.text-dark { + color: #171717 !important; +} + +.text-primary-inverse { + color: white !important; +} + +.text-secondary-inverse { + color: white !important; +} + +.text-tertiary-inverse { + color: white !important; +} + +.text-quartenary-inverse { + color: white !important; +} + +.text-success-inverse { + color: white !important; +} + +.text-warning-inverse { + color: white !important; +} + +.text-danger-inverse { + color: white !important; +} + +.text-info-inverse { + color: white !important; +} + +.text-dark-inverse { + color: white !important; +} + +/* weights */ +.text-weight-light { + font-weight: 300; +} + +.text-weight-normal { + font-weight: 400; +} + +.text-weight-semibold { + font-weight: 600; +} + +.text-weight-bold { + font-weight: 700; +} + +.text-uppercase { + text-transform: uppercase; +} + +.text-lowercase { + text-transform: lowercase; +} + +.text-capitalize { + text-transform: capitalize; +} + +.rounded { + border-radius: 5px; +} + +.b-thin { + border-width: 3px; +} + +.b-normal { + border-width: 5px; +} + +.b-thick { + border-width: 7px; +} + +/* Spacements */ +/* spacement top & bottom */ +.m-none { + margin: 0 !important; +} + +.m-auto { + margin: 0 auto !important; +} + +.m-xs { + margin: 5px !important; +} + +.m-sm { + margin: 10px !important; +} + +.m-md { + margin: 15px !important; +} + +.m-lg { + margin: 20px !important; +} + +.m-xl { + margin: 25px !important; +} + +.m-xlg { + margin: 30px !important; +} + +/* spacement top */ +.mt-none { + margin-top: 0 !important; +} + +.mt-xs { + margin-top: 5px !important; +} + +.mt-sm { + margin-top: 10px !important; +} + +.mt-md { + margin-top: 15px !important; +} + +.mt-lg { + margin-top: 20px !important; +} + +.mt-xl { + margin-top: 25px !important; +} + +.mt-xlg { + margin-top: 30px !important; +} + +/* spacement bottom */ +.mb-none { + margin-bottom: 0 !important; +} + +.mb-xs { + margin-bottom: 5px !important; +} + +.mb-sm { + margin-bottom: 10px !important; +} + +.mb-md { + margin-bottom: 15px !important; +} + +.mb-lg { + margin-bottom: 20px !important; +} + +.mb-xl { + margin-bottom: 25px !important; +} + +.mb-xlg { + margin-bottom: 30px !important; +} + +/* spacement left */ +.mr-none { + margin-left: 0 !important; +} + +.ml-xs { + margin-left: 5px !important; +} + +.ml-sm { + margin-left: 10px !important; +} + +.ml-md { + margin-left: 15px !important; +} + +.ml-lg { + margin-left: 20px !important; +} + +.ml-xl { + margin-left: 25px !important; +} + +.ml-xlg { + margin-left: 30px !important; +} + +/* spacement right */ +.mr-none { + margin-right: 0 !important; +} + +.mr-xs { + margin-right: 5px !important; +} + +.mr-sm { + margin-right: 10px !important; +} + +.mr-md { + margin-right: 15px !important; +} + +.mr-lg { + margin-right: 20px !important; +} + +.mr-xl { + margin-right: 25px !important; +} + +.mr-xlg { + margin-right: 30px !important; +} + +/* Spacement Padding */ +.p-none { + padding: 0 !important; +} + +.p-xs { + padding: 5px !important; +} + +.p-sm { + padding: 10px !important; +} + +.p-md { + padding: 15px !important; +} + +.p-lg { + padding: 20px !important; +} + +.p-xl { + padding: 25px !important; +} + +.p-xlg { + padding: 30px !important; +} + +/* spacement top */ +.pt-none { + padding-top: 0 !important; +} + +.pt-xs { + padding-top: 5px !important; +} + +.pt-sm { + padding-top: 10px !important; +} + +.pt-md { + padding-top: 15px !important; +} + +.pt-lg { + padding-top: 20px !important; +} + +.pt-xl { + padding-top: 25px !important; +} + +.pt-xlg { + padding-top: 30px !important; +} + +/* spacement bottom */ +.pb-none { + padding-bottom: 0 !important; +} + +.pb-xs { + padding-bottom: 5px !important; +} + +.pb-sm { + padding-bottom: 10px !important; +} + +.pb-md { + padding-bottom: 15px !important; +} + +.pb-lg { + padding-bottom: 20px !important; +} + +.pb-xl { + padding-bottom: 25px !important; +} + +.pb-xlg { + padding-bottom: 30px !important; +} + +/* spacement left */ +.pr-none { + padding-left: 0 !important; +} + +.pl-xs { + padding-left: 5px !important; +} + +.pl-sm { + padding-left: 10px !important; +} + +.pl-md { + padding-left: 15px !important; +} + +.pl-lg { + padding-left: 20px !important; +} + +.pl-xl { + padding-left: 25px !important; +} + +.pl-xlg { + padding-left: 30px !important; +} + +/* spacement right */ +.pr-none { + padding-right: 0 !important; +} + +.pr-xs { + padding-right: 5px !important; +} + +.pr-sm { + padding-right: 10px !important; +} + +.pr-md { + padding-right: 15px !important; +} + +.pr-lg { + padding-right: 20px !important; +} + +.pr-xl { + padding-right: 25px !important; +} + +.pr-xlg { + padding-right: 30px !important; +} + +.ib { + display: inline-block; + vertical-align: top; +} + +.va-middle { + vertical-align: middle; +} + +.ws-nowrap { + white-space: nowrap; +} + +.ws-normal { + white-space: normal; +} + +.bg-default { + background: #ebebeb; + color: #777777; +} + +.bg-primary { + background: #cccccc; + color: white; +} + +.bg-secondary { + background: #e36159; + color: white; +} + +.bg-tertiary { + background: #2baab1; + color: white; +} + +.bg-quartenary { + background: #734ba9; + color: white; +} + +.bg-success { + background: #47a447; + color: white; +} + +.bg-warning { + background: #ed9c28; + color: white; +} + +.bg-danger { + background: #d2322d; + color: white; +} + +.bg-info { + background: #5bc0de; + color: white; +} + +.bg-dark { + background: #171717; + color: white; +} + +/* Form - iOS Override */ +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +textarea { + -webkit-appearance: none; +} + +.form-control::-webkit-input-placeholder, +input[type="text"]::-webkit-input-placeholder, +input[type="password"]::-webkit-input-placeholder, +input[type="datetime"]::-webkit-input-placeholder, +input[type="datetime-local"]::-webkit-input-placeholder, +input[type="date"]::-webkit-input-placeholder, +input[type="month"]::-webkit-input-placeholder, +input[type="time"]::-webkit-input-placeholder, +input[type="week"]::-webkit-input-placeholder, +input[type="number"]::-webkit-input-placeholder, +input[type="email"]::-webkit-input-placeholder, +input[type="url"]::-webkit-input-placeholder, +input[type="search"]::-webkit-input-placeholder, +input[type="tel"]::-webkit-input-placeholder, +input[type="color"]::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #bdbdbd; +} + +.form-control::-moz-placeholder, +input[type="text"]::-moz-placeholder, +input[type="password"]::-moz-placeholder, +input[type="datetime"]::-moz-placeholder, +input[type="datetime-local"]::-moz-placeholder, +input[type="date"]::-moz-placeholder, +input[type="month"]::-moz-placeholder, +input[type="time"]::-moz-placeholder, +input[type="week"]::-moz-placeholder, +input[type="number"]::-moz-placeholder, +input[type="email"]::-moz-placeholder, +input[type="url"]::-moz-placeholder, +input[type="search"]::-moz-placeholder, +input[type="tel"]::-moz-placeholder, +input[type="color"]::-moz-placeholder, +textarea::-moz-placeholder { + color: #bdbdbd; +} + +.form-control:-ms-input-placeholder, +input[type="text"]:-ms-input-placeholder, +input[type="password"]:-ms-input-placeholder, +input[type="datetime"]:-ms-input-placeholder, +input[type="datetime-local"]:-ms-input-placeholder, +input[type="date"]:-ms-input-placeholder, +input[type="month"]:-ms-input-placeholder, +input[type="time"]:-ms-input-placeholder, +input[type="week"]:-ms-input-placeholder, +input[type="number"]:-ms-input-placeholder, +input[type="email"]:-ms-input-placeholder, +input[type="url"]:-ms-input-placeholder, +input[type="search"]:-ms-input-placeholder, +input[type="tel"]:-ms-input-placeholder, +input[type="color"]:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #bdbdbd; +} + +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} + +html.dark .form-control { + background-color: #282d36; + border-color: #282d36; + color: #EEE; +} + +html.dark .form-control[disabled], +html.dark .form-control[readonly], +html.dark fieldset[disabled] .form-control { + background-color: #21262d; +} + +html.dark .input-group-addon { + background-color: #21262d; + border-color: #21262d; + color: #EEE; +} + +/* Form - Bootstrap Override */ +.btn-lg, +.btn-group-lg > .btn { + line-height: 1.334; +} + +select.input-sm, select.input-lg { + line-height: 1; +} + +/* Form - Custom Fields */ +.required { + display: inline-block; + color: #d2322d; + font-size: 0.8em; + font-weight: bold; + position: relative; + top: -0.2em; +} + +label.error { + color: #B94A48; + margin-top: 2px; +} + +/* Form - Group Override */ +.form-group:after { + clear: both; + display: block; + content: ''; +} + +.form-group:last-child, .form-group:last-of-type { + margin-bottom: 0; +} + +/* Form - Bordered */ +.form-bordered .form-group { + border-bottom: 1px solid #eff2f7; + padding-bottom: 15px; + margin-bottom: 15px; +} + +.form-bordered .form-group:last-child, .form-bordered .form-group:last-of-type { + border-bottom: none !important; + padding-bottom: 0px !important; + margin-bottom: 0px !important; +} + +/* Dark - Form - Bordered */ +html.dark .form-bordered .form-group { + border-bottom: 1px solid #242830; + padding-bottom: 15px; + margin-bottom: 15px; +} + +/* Form - Vertical Group / Stacked */ +.form-group-vertical { + position: relative; + white-space: nowrap; +} + +.form-group-vertical .form-control { + border-radius: 0; + margin-top: -1px; + z-index: 1; +} + +.form-group-vertical .form-control:first-child, .form-group-vertical .form-control:first-of-type { + border-radius: 4px 4px 0 0; +} + +.form-group-vertical .form-control:last-child, .form-group-vertical .form-control:last-of-type { + border-radius: 0 0 4px 4px; +} + +.form-group-vertical .form-control:focus { + position: relative; + z-index: 2; +} + +.form-group-vertical .input-group { + margin-top: -1px; +} + +.form-group-vertical .input-group .form-control { + margin-top: 0; +} + +.form-group-vertical .input-group:first-child .input-group-addon, .form-group-vertical .input-group:first-of-type .input-group-addon { + border-radius: 4px 0 0 0; +} + +.form-group-vertical .input-group:first-child .form-control, .form-group-vertical .input-group:first-of-type .form-control { + border-radius: 0 4px 0 0; +} + +.form-group-vertical .input-group:last-child .input-group-addon, .form-group-vertical .input-group:last-of-type .input-group-addon { + border-radius: 0 0 0 4px; +} + +.form-group-vertical .input-group:last-child .form-control, .form-group-vertical .input-group:last-of-type .form-control { + border-radius: 0 0 4px 0; +} + +.form-group-vertical .input-group.input-group-icon:first-child .input-group-addon, .form-group-vertical .input-group.input-group-icon:first-of-type .input-group-addon { + border-radius: 4px 4px 0 0; +} + +.form-group-vertical .input-group.input-group-icon:first-child .form-control, .form-group-vertical .input-group.input-group-icon:first-of-type .form-control { + border-radius: 4px 4px 0 0; +} + +.form-group-vertical .input-group.input-group-icon:last-child .input-group-addon, .form-group-vertical .input-group.input-group-icon:last-of-type .input-group-addon { + border-radius: 0 0 4px 4px; +} + +.form-group-vertical .input-group.input-group-icon:last-child .form-control, .form-group-vertical .input-group.input-group-icon:last-of-type .form-control { + border-radius: 0 0 4px 4px; +} + +/* Form - Input Override */ +.input-lg { + border-radius: 4px; +} + +/* Form - Input Icon */ +.input-group-icon, +.input-search { + width: 100%; + table-layout: fixed; +} + +.input-group-icon input.form-control, +.input-search input.form-control { + font-size: 12px; + font-size: 1.2rem; + padding-right: 36px; +} + +.input-group-icon input.form-control:first-child, .input-group-icon input.form-control:last-child, +.input-search input.form-control:first-child, +.input-search input.form-control:last-child { + border-radius: 4px; +} + +.input-group-icon .input-group-btn, +.input-search .input-group-btn { + border-radius: 500px; + width: 0; +} + +.input-group-icon .input-group-btn:first-child, .input-group-icon .input-group-btn:last-child, +.input-search .input-group-btn:first-child, +.input-search .input-group-btn:last-child { + border-radius: 500px; +} + +.input-group-icon .input-group-btn button, +.input-search .input-group-btn button { + position: absolute; + top: 0; + left: 0; + bottom: 0; + border: 0; + z-index: 3; + background: transparent; +} + +.input-group-icon .input-group-btn button:active, +.input-search .input-group-btn button:active { + -webkit-box-shadow: none; + box-shadow: none; +} + +.input-group-icon .input-group-btn:last-child button, +.input-search .input-group-btn:last-child button { + left: auto; + right: 0; +} + +.input-group-icon .input-group-btn + input.form-control, +.input-search .input-group-btn + input.form-control { + padding-right: 12px; + padding-left: 36px; +} + +.input-group-icon .input-group-addon, +.input-search .input-group-addon { + position: relative; + padding: 0; + border: 0 none; + width: 0; +} + +.input-group-icon .input-group-addon span.icon, +.input-search .input-group-addon span.icon { + position: absolute; + top: 0; + bottom: 0; + left: 0; + border: 0; + z-index: 3; + width: auto; + display: inline-block; + vertical-align: middle; + text-align: center; + padding: 6px 12px; + background: transparent; + line-height: 1.42857143; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + pointer-events: none; +} + +.input-group-icon .input-group-addon span.icon.icon-lg, +.input-search .input-group-addon span.icon.icon-lg { + padding: 10px 14px; + font-size: 18px; +} + +.input-group-icon .input-group-addon:last-child span.icon, +.input-search .input-group-addon:last-child span.icon { + left: auto; + right: 0; +} + +.input-group-icon .input-group-addon + input.form-control, +.input-search .input-group-addon + input.form-control { + padding-right: 12px; + padding-left: 36px; +} + +/* Form - Input Search */ +.input-search { + width: 100%; +} + +.input-search input.form-control:focus { + border-color: #ccc; + -webkit-box-shadow: none; + box-shadow: none; +} + +.input-search .input-group-btn { + color: #ccc; +} + +.input-search .input-group-btn .btn { + padding-left: 15px; +} + +.input-search .input-group-btn .btn-default { + color: #ccc; +} + +/* Dark */ +.input-search { + width: 100%; +} + +.input-search input.form-control:focus { + border-color: #1d2127; +} + +.input-search .input-group-btn .btn { + background: transparent !important; +} + +/* Form - Round Input */ +input.input-rounded { + -webkit-border-radius: 500px; + border-radius: 500px; +} + +.input-group-rounded input.form-control, +.input-search input.form-control { + -webkit-border-radius: 500px; + border-radius: 500px; +} + +.input-group-rounded input.form-control:first-child, .input-group-rounded input.form-control:last-child, +.input-search input.form-control:first-child, +.input-search input.form-control:last-child { + border-radius: 500px; +} + +.input-group-rounded .input-group-addon:first-child, +.input-search .input-group-addon:first-child { + border-radius: 500px 0 0 500px; +} + +.input-group-rounded .input-group-addon:last-child, +.input-search .input-group-addon:last-child { + border-radius: 0 500px 500px 0; +} + +/* Form - Custom Checkbox */ +.checkbox-custom { + position: relative; + padding: 0 0 0 25px; + margin-bottom: 7px; + margin-top: 0; +} + +.checkbox-custom.checkbox-inline { + display: inline-block; + vertical-align: middle; +} + +.form-group .checkbox-custom.checkbox-inline { + margin-top: 7px; + padding-top: 0; +} + +.checkbox-custom:last-child, .checkbox-custom:last-of-type { + margin-bottom: 0; +} + +.checkbox-custom input[type="checkbox"] { + opacity: 0; + position: absolute; + top: 50%; + left: 3px; + margin: -6px 0 0 0; + z-index: 2; + cursor: pointer; +} + +.checkbox-custom input[type="checkbox"]:checked + label:after { + position: absolute; + display: inline-block; + font-family: 'FontAwesome'; + content: '\F00C'; + top: 50%; + left: 4px; + margin-top: -5px; + font-size: 11px; + line-height: 1; + width: 16px; + height: 16px; + color: #333; +} + +.checkbox-custom input[type="checkbox"]:disabled { + cursor: not-allowed; +} + +.checkbox-custom input[type="checkbox"]:disabled:checked + label:after { + color: #999; +} + +.checkbox-custom input[type="checkbox"]:disabled + label { + cursor: not-allowed; +} + +.checkbox-custom input[type="checkbox"]:disabled + label:before { + background-color: #eee; +} + +.checkbox-custom label { + cursor: pointer; + margin-bottom: 0; + text-align: left; + line-height: 1.2; +} + +.checkbox-custom label:before { + content: ''; + position: absolute; + top: 50%; + left: 0; + margin-top: -9px; + width: 19px; + height: 18px; + display: inline-block; + border-radius: 2px; + border: 1px solid #bbb; + background: #fff; +} + +.checkbox-custom label + label.error { + display: block; +} + +html.dark .checkbox-custom label:before { + background: #282d36; + border-color: #21262d; +} + +html.dark .checkbox-custom input[type="checkbox"]:checked + label:after { + color: #fff; +} + +html.dark .checkbox-custom input[type="checkbox"]:disabled + label:before { + background: #242830; + border-color: #242830; +} + +html.dark .checkbox-primary input[type="checkbox"]:checked + label:after, +.checkbox-primary input[type="checkbox"]:checked + label:after { + color: #fff; +} + +html.dark .checkbox-primary label:before, +.checkbox-primary label:before { + background: #cccccc; + border-color: #bfbfbf; +} + +html.dark .checkbox-text-primary input[type="checkbox"]:checked + label:after, +.checkbox-text-primary input[type="checkbox"]:checked + label:after { + color: #cccccc; +} + +html.dark .checkbox-success input[type="checkbox"]:checked + label:after, +.checkbox-success input[type="checkbox"]:checked + label:after { + color: #fff; +} + +html.dark .checkbox-success label:before, +.checkbox-success label:before { + background: #47a447; + border-color: #3f923f; +} + +html.dark .checkbox-text-success input[type="checkbox"]:checked + label:after, +.checkbox-text-success input[type="checkbox"]:checked + label:after { + color: #47a447; +} + +html.dark .checkbox-warning input[type="checkbox"]:checked + label:after, +.checkbox-warning input[type="checkbox"]:checked + label:after { + color: #fff; +} + +html.dark .checkbox-warning label:before, +.checkbox-warning label:before { + background: #ed9c28; + border-color: #e89113; +} + +html.dark .checkbox-text-warning input[type="checkbox"]:checked + label:after, +.checkbox-text-warning input[type="checkbox"]:checked + label:after { + color: #ed9c28; +} + +html.dark .checkbox-danger input[type="checkbox"]:checked + label:after, +.checkbox-danger input[type="checkbox"]:checked + label:after { + color: #fff; +} + +html.dark .checkbox-danger label:before, +.checkbox-danger label:before { + background: #d2322d; + border-color: #bd2d29; +} + +html.dark .checkbox-text-danger input[type="checkbox"]:checked + label:after, +.checkbox-text-danger input[type="checkbox"]:checked + label:after { + color: #d2322d; +} + +html.dark .checkbox-info input[type="checkbox"]:checked + label:after, +.checkbox-info input[type="checkbox"]:checked + label:after { + color: #fff; +} + +html.dark .checkbox-info label:before, +.checkbox-info label:before { + background: #5bc0de; + border-color: #46b8da; +} + +html.dark .checkbox-text-info input[type="checkbox"]:checked + label:after, +.checkbox-text-info input[type="checkbox"]:checked + label:after { + color: #5bc0de; +} + +html.dark .checkbox-dark input[type="checkbox"]:checked + label:after, +.checkbox-dark input[type="checkbox"]:checked + label:after { + color: #fff; +} + +html.dark .checkbox-dark label:before, +.checkbox-dark label:before { + background: #171717; + border-color: #0a0a0a; +} + +html.dark .checkbox-text-dark input[type="checkbox"]:checked + label:after, +.checkbox-text-dark input[type="checkbox"]:checked + label:after { + color: #171717; +} + +/* Form - Custom Radio */ +.radio-custom { + position: relative; + padding: 0 0 0 25px; + margin-bottom: 7px; + margin-top: 0; +} + +.radio-custom.radio-inline { + display: inline-block; + vertical-align: middle; +} + +.form-group .radio-custom.radio-inline { + margin-top: 7px; + padding-top: 0; +} + +.radio-custom:last-child, .radio-custom:last-of-type { + margin-bottom: 0; +} + +.radio-custom input[type="radio"] { + opacity: 0; + position: absolute; + top: 50%; + left: 3px; + margin: -6px 0 0 0; + z-index: 2; + cursor: pointer; +} + +.radio-custom input[type="radio"]:checked + label:after { + content: ''; + position: absolute; + top: 50%; + left: 4px; + margin-top: -5px; + display: inline-block; + font-size: 11px; + line-height: 1; + width: 10px; + height: 10px; + background-color: #444; + border-radius: 50px; + -webkit-box-shadow: 0px 0px 1px #444; + box-shadow: 0px 0px 1px #444; +} + +.radio-custom input[type="radio"]:disabled { + cursor: not-allowed; +} + +.radio-custom input[type="radio"]:disabled:checked + label:after { + color: #999; +} + +.radio-custom input[type="radio"]:disabled + label { + cursor: not-allowed; +} + +.radio-custom input[type="radio"]:disabled + label:before { + background-color: #eee; +} + +.radio-custom label { + cursor: pointer; + margin-bottom: 0; + text-align: left; + line-height: 1.2; +} + +.radio-custom label:before { + content: ''; + position: absolute; + top: 50%; + left: 0; + margin-top: -9px; + width: 18px; + height: 18px; + display: inline-block; + border-radius: 50px; + border: 1px solid #bbb; + background: #fff; +} + +.radio-custom label + label.error { + display: block; +} + +html.dark .radio-custom label:before { + background: #282d36; + border-color: #21262d; +} + +html.dark .radio-custom input[type="radio"]:checked + label:after { + background-color: #fff; +} + +html.dark .radio-custom input[type="radio"]:disabled + label:before { + background: #242830; + border-color: #242830; +} + +html.dark .radio-primary input[type="radio"]:checked + label:after, +.radio-primary input[type="radio"]:checked + label:after { + background: #cccccc; + -webkit-box-shadow: 0px 0px 1px #cccccc; + box-shadow: 0px 0px 1px #cccccc; +} + +html.dark .radio-success input[type="radio"]:checked + label:after, +.radio-success input[type="radio"]:checked + label:after { + background: #47a447; + -webkit-box-shadow: 0px 0px 1px #47a447; + box-shadow: 0px 0px 1px #47a447; +} + +html.dark .radio-warning input[type="radio"]:checked + label:after, +.radio-warning input[type="radio"]:checked + label:after { + background: #ed9c28; + -webkit-box-shadow: 0px 0px 1px #ed9c28; + box-shadow: 0px 0px 1px #ed9c28; +} + +html.dark .radio-danger input[type="radio"]:checked + label:after, +.radio-danger input[type="radio"]:checked + label:after { + background: #d2322d; + -webkit-box-shadow: 0px 0px 1px #d2322d; + box-shadow: 0px 0px 1px #d2322d; +} + +html.dark .radio-info input[type="radio"]:checked + label:after, +.radio-info input[type="radio"]:checked + label:after { + background: #5bc0de; + -webkit-box-shadow: 0px 0px 1px #5bc0de; + box-shadow: 0px 0px 1px #5bc0de; +} + +html.dark .radio-dark input[type="radio"]:checked + label:after, +.radio-dark input[type="radio"]:checked + label:after { + background: #171717; + -webkit-box-shadow: 0px 0px 1px #171717; + box-shadow: 0px 0px 1px #171717; +} + +/* Form - Error Container */ +div.validation-message ul { + display: none; + list-style: none; + margin: -15px -15px 15px -15px; + padding: 15px; + border-bottom: 1px solid #FFCBCB; + background: #FFEFEF; +} + +div.validation-message ul label.error { + display: block; + padding-left: 22px; + position: relative; +} + +div.validation-message ul label.error:before { + font-family: 'FontAwesome'; + content: '\f00d'; + position: absolute; + top: 0; + left: 0; + font-size: 16px; + color: #D9534F; + display: inline-block; +} + +.select2-drop-mask { + z-index: 10010; +} + +.select2-drop { + z-index: 10011; +} + +.select2-search { + z-index: 10012; +} + +html.dark .fileupload .uneditable-input { + background-color: #282d36; + border-color: #282d36; +} + +html.dark .fileupload-new .input-append .btn-file { + border-color: #21262d; +} + +/* Nano Scroller Plugin */ +html.no-overflowscrolling .nano { + height: 100%; + position: relative; + overflow: hidden; + width: 100%; +} + +html.no-overflowscrolling .nano > .nano-content { + bottom: 0; + left: 0; + position: absolute; + overflow: hidden; + right: 0; + top: 0; +} + +html.no-overflowscrolling .nano > .nano-content:focus { + outline: none; +} + +html.no-overflowscrolling .nano > .nano-content::-webkit-scrollbar { + display: none; + visibility: hidden; +} + +html.no-overflowscrolling .nano.has-scrollbar > .nano-content::-webkit-scrollbar { + display: block; + visibility: visible; +} + +html.no-overflowscrolling .nano > .nano-pane { + bottom: 0; + position: absolute; + opacity: .01; + right: 0; + top: 0; + visibility: hidden\9; + /* Target only IE7 and IE8 with this hack */ + width: 4px; + -webkit-transition: .2s; + -moz-transition: .2s; + -o-transition: .2s; + transition: .2s; +} + +html.no-overflowscrolling .nano > .nano-pane > .nano-slider { + background: #cccccc; + margin: 0; + position: relative; + visibility: hidden; +} + +html.no-overflowscrolling .nano:hover > .nano-pane, +html.no-overflowscrolling .nano .nano-pane.active, +html.no-overflowscrolling .nano .nano-pane.flashed { + opacity: 0.99; +} + +html.no-overflowscrolling .nano:hover > .nano-pane > .nano-slider { + visibility: visible; +} + +html.no-overflowscrolling.custom-scroll .nano > .nano-content { + overflow: scroll; + overflow-x: hidden; +} + +@media only screen and (max-width: 767px) { + html.no-overflowscrolling .nano > .nano-content { + overflow: scroll !important; + overflow-x: hidden !important; + } +} + +@media only screen and (min-width: 768px) { + html.overflowscrolling.fixed .sidebar-left .nano, + html.overflowscrolling.fixed .sidebar-right .nano, + html.overflowscrolling.fixed .inner-menu .nano { + height: 100%; + overflow: hidden; + -webkit-overflow-scrolling: touch; + } + + html.overflowscrolling.fixed .sidebar-left .nano > .nano-pane > .nano-slider, + html.overflowscrolling.fixed .sidebar-right .nano > .nano-pane > .nano-slider, + html.overflowscrolling.fixed .inner-menu .nano > .nano-pane > .nano-slider { + visibility: visible; + } + + html.overflowscrolling.fixed.custom-scroll .sidebar-left .nano > .nano-content, + html.overflowscrolling.fixed.custom-scroll .sidebar-right .nano > .nano-content, + html.overflowscrolling.fixed.custom-scroll .inner-menu .nano > .nano-content { + overflow-y: scroll; + overflow-x: hidden; + } +} +/* Toolbar */ +.inner-toolbar { + background: #1d2127; + margin: -40px -40px 30px; + padding: 0; + border-left: 1px solid #121418; +} + +.inner-toolbar > ul { + list-style: none; + padding: 0; + margin: 0; +} + +.inner-toolbar > ul > li { + display: inline-block; + padding: 15px; + font-size: 13px; + border-right: 1px solid #121418; +} + +.inner-toolbar > ul > li > a { + display: inline-block; + padding: 0; + color: #abb4be; +} + +.inner-toolbar > ul > li > a:hover, .inner-toolbar > ul > li > a:focus { + color: #fff; + text-decoration: none; +} + +.inner-toolbar > ul > li.right { + float: right; + padding-right: 10px; +} + +.inner-toolbar > ul > li i.fa { + font-size: 14px; +} + +.inner-toolbar > ul > li > .btn { + margin-top: -6px; +} + +.inner-toolbar .nav-pills { + margin-top: -8px; +} + +.inner-toolbar .nav-pills > li > label { + margin-bottom: 0; + margin-right: 12px; + margin-top: 8px; +} + +.inner-toolbar .nav-pills a { + color: #abb4be; + padding-top: 8px; + padding-bottom: 8px; +} + +.inner-toolbar .nav-pills a:hover { + background: #171717; + color: #FFF; +} + +.inner-toolbar .nav-pills .active a { + color: #FFF; +} + +/* Toolbar - Responsive */ +@media only screen and (max-width: 767px) { + .inner-toolbar { + clear: both; + margin: -40px -15px 30px; + padding: 0 15px; + } + + .inner-toolbar ul > li { + border-right: 0; + } + + .inner-toolbar ul > li:first-child { + padding-left: 0; + } + + .inner-toolbar ul > li.right { + padding-left: 0; + padding-right: 0; + } +} + +@media only screen and (max-width: 480px) { + .inner-toolbar .nav-pills a { + padding-left: 10px; + padding-right: 10px; + } + + .inner-toolbar ul > li.right { + clear: both; + float: none; + vertical-align: top; + } +} +/* Toolbar + Layout Fixed */ +@media only screen and (min-width: 768px) { + html.fixed .inner-toolbar { + left: 300px; + right: 0; + margin: 0; + padding: 0; + position: fixed; + top: 114px; + z-index: 1001; + } +} +/* dark */ +html.dark .inner-toolbar { + border-left: none; + border-bottom: 1px solid #242830; +} + +html.dark .inner-toolbar > ul > li { + border-color: #242830; +} + +@-webkit-keyframes animateLoader { + 0% { + -webkit-transform: rotate(0deg); + } + + 100% { + -webkit-transform: rotate(220deg); + } +} + +@-moz-keyframes animateLoader { + 0% { + -moz-transform: rotate(0deg); + } + + 100% { + -moz-transform: rotate(220deg); + } +} + +@keyframes animateLoader { + 0% { + -webkit-transform: rotate(0deg); + -moz-transform: rotate(0deg); + -ms-transform: rotate(0deg); + -o-transform: rotate(0deg); + transform: rotate(0deg); + } + + 100% { + -webkit-transform: rotate(220deg); + -moz-transform: rotate(220deg); + -ms-transform: rotate(220deg); + -o-transform: rotate(220deg); + transform: rotate(220deg); + } +} + +@-webkit-keyframes animateLoaderAfterWhite { + 0% { + box-shadow: 0 0 0 6px #FFF inset; + -webkit-transform: rotate(-140deg); + } + + 50% { + box-shadow: 0 0 0 2px #FFF inset; + } + + 100% { + box-shadow: 0 0 0 6px #FFF inset; + -webkit-transform: rotate(140deg); + } +} + +@-moz-keyframes animateLoaderAfterWhite { + 0% { + box-shadow: 0 0 0 6px #FFF inset; + -moz-transform: rotate(-140deg); + } + + 50% { + box-shadow: 0 0 0 2px #FFF inset; + } + + 100% { + box-shadow: 0 0 0 6px #FFF inset; + -moz-transform: rotate(140deg); + } +} + +@keyframes animateLoaderAfterWhite { + 0% { + box-shadow: 0 0 0 6px #FFF inset; + -webkit-transform: rotate(-140deg); + -moz-transform: rotate(-140deg); + -ms-transform: rotate(-140deg); + -o-transform: rotate(-140deg); + transform: rotate(-140deg); + } + + 50% { + box-shadow: 0 0 0 2px #FFF inset; + } + + 100% { + box-shadow: 0 0 0 6px #FFF inset; + -webkit-transform: rotate(140deg); + -moz-transform: rotate(140deg); + -ms-transform: rotate(140deg); + -o-transform: rotate(140deg); + transform: rotate(140deg); + } +} + +@-webkit-keyframes animateLoaderAfterBlack { + 0% { + box-shadow: 0 0 0 6px #000 inset; + -webkit-transform: rotate(-140deg); + } + + 50% { + box-shadow: 0 0 0 2px #000 inset; + } + + 100% { + box-shadow: 0 0 0 6px #000 inset; + -webkit-transform: rotate(140deg); + } +} + +@-moz-keyframes animateLoaderAfterBlack { + 0% { + box-shadow: 0 0 0 6px #000 inset; + -moz-transform: rotate(-140deg); + } + + 50% { + box-shadow: 0 0 0 2px #000 inset; + } + + 100% { + box-shadow: 0 0 0 6px #000 inset; + -moz-transform: rotate(140deg); + } +} + +@keyframes animateLoaderAfterBlack { + 0% { + box-shadow: 0 0 0 6px #000 inset; + -webkit-transform: rotate(-140deg); + -moz-transform: rotate(-140deg); + -ms-transform: rotate(-140deg); + -o-transform: rotate(-140deg); + transform: rotate(-140deg); + } + + 50% { + box-shadow: 0 0 0 2px #000 inset; + } + + 100% { + box-shadow: 0 0 0 6px #000 inset; + -webkit-transform: rotate(140deg); + -moz-transform: rotate(140deg); + -ms-transform: rotate(140deg); + -o-transform: rotate(140deg); + transform: rotate(140deg); + } +} + +.loading-overlay-showing { + overflow: hidden; +} + +.loading-overlay-showing > .loading-overlay { + opacity: 1; + visibility: visible; + -webkit-transition-delay: 0; + -moz-transition-delay: 0; + transition-delay: 0; +} + +.loading-overlay { + -webkit-transition: visibility 0s ease-in-out 0.5s, opacity 0.5s ease-in-out; + -moz-transition: visibility 0s ease-in-out 0.5s, opacity 0.5s ease-in-out; + transition: visibility 0s ease-in-out 0.5s, opacity 0.5s ease-in-out; + bottom: 0; + left: 0; + position: absolute; + opacity: 0; + right: 0; + top: 0; + visibility: hidden; +} + +.loading-overlay.dark { + background: #1d2127; +} + +.loading-overlay.light { + background: #FFF; +} + +.loading-overlay .loader { + -webkit-animation: animateLoader 1s linear infinite; + -moz-animation: animateLoader 1s linear infinite; + animation: animateLoader 1s linear infinite; + clip: rect(0, 30px, 30px, 15px); + height: 30px; + left: 50%; + margin-left: -15px; + margin-top: -15px; + position: absolute; + text-align: left; + top: 50%; + width: 30px; +} + +.loading-overlay .loader.white:after { + -webkit-animation: animateLoaderAfterWhite 1s ease-in-out infinite; + -moz-animation: animateLoaderAfterWhite 1s ease-in-out infinite; + animation: animateLoaderAfterWhite 1s ease-in-out infinite; +} + +.loading-overlay .loader.black:after { + -webkit-animation: animateLoaderAfterBlack 1s ease-in-out infinite; + -moz-animation: animateLoaderAfterBlack 1s ease-in-out infinite; + animation: animateLoaderAfterBlack 1s ease-in-out infinite; +} + +.loading-overlay .loader:after { + border-radius: 50%; + clip: rect(0, 30px, 30px, 15px); + content: ''; + height: 30px; + position: absolute; + width: 30px; +} + +body > .loading-overlay { + position: fixed; + z-index: 999999; +} + +.img-rounded { + border-radius: 6px; +} + +.img-circle { + border-radius: 50%; +} + +.img-thumbnail { + border-radius: 8px; + position: relative; +} + +body { + /* Button Basic */ + /* Buttons - Social */ + /* Buttons - States */; +} + +body .btn:focus, +body .btn:active:focus, +body .btn.active:focus { + outline: none; +} + +body .btn { + white-space: normal; +} + +body .btn-facebook, body .btn-facebook:active, body .btn-facebook:hover, body .btn-facebook:focus, +body .btn-twitter, +body .btn-twitter:active, +body .btn-twitter:hover, +body .btn-twitter:focus, +body .btn-gplus, +body .btn-gplus:active, +body .btn-gplus:hover, +body .btn-gplus:focus { + color: #FFF; + font-weight: 300; + padding-left: 30px; + padding-right: 30px; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); +} + +body .btn-facebook, body .btn-facebook:focus { + background: #3B5998; + border: 1px solid #37538D; +} + +body .btn-facebook:hover { + background: #4162a7; + border-color: #3d5c9c; +} + +body .btn-facebook:active { + background: #37538d; + border-color: #334d82; +} + +body .btn-twitter, body .btn-twitter:focus { + background: #55ACEE; + border: 1px solid #47A5ED; +} + +body .btn-twitter:hover { + background: #63b3ef; + border-color: #55acee; +} + +body .btn-twitter:active { + background: #47a5ed; + border-color: #399eec; +} + +body .btn-gplus, body .btn-gplus:focus { + background: #D95232; + border: 1px solid #D44927; +} + +body .btn-gplus:hover { + background: #dc6143; + border-color: #da5635; +} + +body .btn-gplus:active { + background: #d04727; + border-color: #c34324; +} + +body .btn-primary { + border-color: #cccccc; + background-color: #cccccc; + border-color: #cccccc #cccccc #b3b3b3; + color: white; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +body .btn-primary:hover { + border-color: #d9d9d9; + background-color: #d9d9d9; + color: white; +} + +body .btn-primary:active, body .btn-primary:focus { + border-color: #bfbfbf; + background-color: #bfbfbf; + color: white; +} + +body .btn-primary.dropdown-toggle { + border-left-color: #bfbfbf; +} + +body .btn-primary[disabled] { + border-color: white; + background-color: white; +} + +body .btn-success { + border-color: #47a447; + background-color: #47a447; + border-color: #47a447 #47a447 #388038; + color: white; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +body .btn-success:hover { + border-color: #51b451; + background-color: #51b451; + color: white; +} + +body .btn-success:active, body .btn-success:focus { + border-color: #3f923f; + background-color: #3f923f; + color: white; +} + +body .btn-success.dropdown-toggle { + border-left-color: #3f923f; +} + +body .btn-success[disabled] { + border-color: #86cb86; + background-color: #86cb86; +} + +body .btn-warning { + border-color: #ed9c28; + background-color: #ed9c28; + border-color: #ed9c28 #ed9c28 #d18211; + color: white; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +body .btn-warning:hover { + border-color: #efa740; + background-color: #efa740; + color: white; +} + +body .btn-warning:active, body .btn-warning:focus { + border-color: #e89113; + background-color: #e89113; + color: white; +} + +body .btn-warning.dropdown-toggle { + border-left-color: #e89113; +} + +body .btn-warning[disabled] { + border-color: #f5c786; + background-color: #f5c786; +} + +body .btn-danger { + border-color: #d2322d; + background-color: #d2322d; + border-color: #d2322d #d2322d #a82824; + color: white; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +body .btn-danger:hover { + border-color: #d64742; + background-color: #d64742; + color: white; +} + +body .btn-danger:active, body .btn-danger:focus { + border-color: #bd2d29; + background-color: #bd2d29; + color: white; +} + +body .btn-danger.dropdown-toggle { + border-left-color: #bd2d29; +} + +body .btn-danger[disabled] { + border-color: #e48481; + background-color: #e48481; +} + +body .btn-info { + border-color: #5bc0de; + background-color: #5bc0de; + border-color: #5bc0de #5bc0de #31b0d5; + color: white; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +body .btn-info:hover { + border-color: #70c8e2; + background-color: #70c8e2; + color: white; +} + +body .btn-info:active, body .btn-info:focus { + border-color: #46b8da; + background-color: #46b8da; + color: white; +} + +body .btn-info.dropdown-toggle { + border-left-color: #46b8da; +} + +body .btn-info[disabled] { + border-color: #b0e1ef; + background-color: #b0e1ef; +} + +body .btn-dark { + border-color: #171717; + background-color: #171717; + border-color: #171717 #171717 black; + color: white; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +body .btn-dark:hover { + border-color: #242424; + background-color: #242424; + color: white; +} + +body .btn-dark:active, body .btn-dark:focus { + border-color: #0a0a0a; + background-color: #0a0a0a; + color: white; +} + +body .btn-dark.dropdown-toggle { + border-left-color: #0a0a0a; +} + +body .btn-dark[disabled] { + border-color: #4a4a4a; + background-color: #4a4a4a; +} + +html.dark .btn-default { + background-color: #282d36; + border-color: #282d36; + color: #EEE; +} + +html.dark .btn-default:hover { + background-color: #2a3039; + border-color: #2a3039; +} + +html.dark .btn-default:focus, html.dark .btn-default:active { + background-color: #242830; + border-color: #242830; +} + +html.dark .btn-default:hover, +html.dark .btn-default:focus, +html.dark .btn-default:active, +html.dark .btn-default.active, +html.dark .open > .dropdown-toggle.btn-default { + color: #EEE; + background-color: #242830; + border-color: #242830; +} + +/* Notifications */ +.notifications { + display: inline-block; + list-style: none; + margin: 4px -10px 0 0; + padding: 0; + vertical-align: middle; +} + +.notifications > li { + float: left; + margin: 0 10px 0 0; + position: relative; +} + +.notifications > li .notification-icon { + background: #FFF; + border-radius: 50%; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.3); + display: inline-block; + height: 30px; + position: relative; + width: 30px; + text-align: center; +} + +.notifications > li .notification-icon i { + color: #777; + line-height: 30px; + vertical-align: middle; +} + +.notifications > li .notification-icon i.fa-tasks { + line-height: 32px; +} + +.notifications > li .notification-icon .badge { + background: #D2312D; + color: #FFF; + font-size: 10px; + font-weight: normal; + height: 16px; + padding: 3px 5px 3px 5px; + position: absolute; + right: -8px; + top: -3px; +} + +.notifications > li > a { + border: none; + display: inline-block; +} + +.notifications .notification-menu { + border: none; + box-shadow: 0 0 2px rgba(0, 0, 0, 0.3); + left: auto; + margin: 10px 0 0 0; + padding: 0; + right: -5px; + width: 245px; +} + +.notifications .notification-menu.large { + width: 325px; +} + +.notifications .notification-menu .notification-title { + background: #cccccc; + border-radius: 3px 3px 0 0; + color: white; + font-size: 11px; + font-size: 1.1rem; + line-height: 15px; + line-height: 1.5rem; + padding: 8px 6px 8px 12px; + text-transform: uppercase; +} + +.notifications .notification-menu .notification-title .label { + font-size: 10px; + font-size: 1rem; + font-weight: 200; + line-height: 14px; + margin-left: 10px; + margin-top: -2px; + min-width: 35px; +} + +.notifications .notification-menu .notification-title .label-default { + background: #006697; + color: #FFF; +} + +.notifications .notification-menu .content { + padding: 12px; +} + +.notifications .notification-menu hr { + background: #e6e6e6; + height: 1px; + margin: 12px 0; +} + +.notifications .notification-menu .view-more { + color: #acacac; + font-size: 11px; + font-size: 1.1rem; + line-height: 11px; + line-height: 1.1rem; + text-transform: uppercase; +} + +/* notification menu - pin */ +.notifications .notification-menu:before, +.notifications .notification-icon:before { + border-bottom: 6px solid #cccccc; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + content: ''; + height: 0; + margin-right: -3px; + width: 0; + position: absolute; + pointer-events: none; +} + +.notifications .notification-menu:before { + bottom: 100%; + right: 16px; +} + +.notifications .notification-icon:before { + display: none; + right: 11px; + top: 35px; + z-index: 9999; +} + +/* notification menu - emails */ +.notification-menu { + color: #acacac; +} + +.notification-menu ul { + list-style: none; + margin: 0; + padding: 0; +} + +.notification-menu li { + margin: 0 0 12px; +} + +.notification-menu li:last-child { + margin-bottom: 0; +} + +.notification-menu a { + display: block; + text-decoration: none; +} + +.notification-menu .image { + float: left; + margin: 0 10px 0 0; +} + +.notification-menu .image i { + border-radius: 35px; + height: 35px; + line-height: 35px; + text-align: center; + width: 35px; +} + +.notification-menu .truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.notification-menu .title { + color: #000011; + display: block; + font-size: 13px; + font-size: 1.3rem; + line-height: 17px; + line-height: 1.7rem; + padding: 2px 0 0; +} + +.notification-menu .message { + color: #acacac; + display: block; + font-size: 11px; + font-size: 1.1rem; + line-height: 15px; + line-height: 1.5rem; + padding: 0; +} + +html.dark .notifications > li .notification-icon, +html.header-dark .notifications > li .notification-icon { + background: #282d36; +} + +html.dark .notifications > li .notification-icon i, +html.header-dark .notifications > li .notification-icon i { + color: #c3c3c3; +} + +/* Notifications Mobile */ +@media only screen and (max-width: 767px) { + .notifications { + float: right; + margin: 16px 8px 0 0; + } + + .notifications > li { + position: static; + } + + .notifications > li.open .notification-icon:before { + display: block; + } + + .notifications > li .notification-menu { + left: 15px; + right: 15px; + top: auto; + width: auto !important; + } + + .notifications > li .notification-menu:before { + display: none; + } +} +/* Userbox */ +.userbox { + display: inline-block; + margin: 3px 17px 0 0; + position: relative; + vertical-align: middle; +} + +.userbox > a { + display: inline-block; + text-decoration: none; +} + +.userbox a:hover { + text-decoration: none; +} + +.userbox .profile-info, +.userbox .profile-picture { + display: inline-block; + vertical-align: middle; +} + +.userbox .profile-picture img { + width: 35px; + color: transparent; +} + +.userbox .profile-info { + margin: 0 25px 0 10px; +} + +.userbox .name, +.userbox .role { + display: block; +} + +.userbox .name { + color: #000011; + font-size: 13px; + font-size: 1.3rem; + line-height: 1.2em; +} + +.userbox .role { + color: #ACACAC; + font-size: 11px; + font-size: 1.1rem; + line-height: 1.2em; +} + +.userbox .custom-caret { + color: #000011; + font-size: 16px; + font-weight: bold; +} + +.userbox .custom-caret:before { + content: "\f107"; +} + +/* Userbox - Open */ +.userbox.open > a { + position: relative; + z-index: 993; +} + +.userbox.open > a .custom-caret:before { + content: "\f106"; +} + +.userbox.open .dropdown-menu { + border: none; + box-shadow: 0 1px 2px 1px rgba(0, 0, 0, 0.2); + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + left: -11px; + padding: 45px 10px 0; + top: -10px; + width: 100%; + z-index: 992; +} + +.userbox.open .dropdown-menu li { + margin-bottom: 5px; +} + +.userbox.open .dropdown-menu a { + border-radius: 2px; + color: #7d7d7d; + display: block; + font-size: 12px; + font-size: 1.2rem; + line-height: 15px; + line-height: 1.5rem; + padding: 5px 10px; +} + +.userbox.open .dropdown-menu a:hover { + background: #cccccc; + color: white; +} + +.userbox.open .dropdown-menu i { + font-size: 17px; + font-size: 1.7rem; + margin-right: 3px; + vertical-align: middle; +} + +/* Userbox - Mobile */ +@media only screen and (max-width: 767px) { + .userbox { + float: left; + margin: 16px 0 0 12px; + position: relative; + } + + .userbox:after { + background: #E9E9E6; + content: ''; + height: 63px; + margin: 0; + position: absolute; + right: -21px; + top: -18px; + width: 1px; + } + + .userbox .profile-picture { + display: none; + } + + .userbox.open .dropdown-menu { + left: -5px; + padding: 43px 0 0 0; + } +} +/* Header Dark - Userbox */ +html.dark .userbox:after, +html.header-dark .userbox:after { + background: #121518; +} + +html.dark .userbox .name, +html.dark .userbox .custom-caret, +html.header-dark .userbox .name, +html.header-dark .userbox .custom-caret { + color: #c3c3c3; +} + +html.dark .userbox.open .dropdown-menu .name, +html.dark .userbox.open .dropdown-menu .custom-caret, +html.header-dark .userbox.open .dropdown-menu .name, +html.header-dark .userbox.open .dropdown-menu .custom-caret { + color: #c3c3c3; +} + +html.dark .userbox.open .dropdown-menu a, +html.header-dark .userbox.open .dropdown-menu a { + color: #c3c3c3; +} + +html.dark .userbox.open .dropdown-menu a:hover, +html.header-dark .userbox.open .dropdown-menu a:hover { + color: #FFF; +} + +html.dark .userbox .dropdown-menu, +html.header-dark .userbox .dropdown-menu { + background: #282d36; +} + +html.dark .userbox .dropdown-menu .divider, +html.header-dark .userbox .dropdown-menu .divider { + background: #1d2127; +} + +html.dark .userbox .dropdown-menu a, +html.header-dark .userbox .dropdown-menu a { + color: #c3c3c3; +} + +.nav-pills > .active a, .nav-pills > .active a:hover, .nav-pills > .active a:focus { + background-color: #cccccc; +} + +.pagination > li a { + color: #cccccc; +} + +.pagination > li a:hover, .pagination > li a:focus { + color: #d9d9d9; +} + +.pagination > li.active a, .pagination > li.active a:hover, .pagination > li.active a:focus, +.pagination > li.active span, +.pagination > li.active span:hover, +.pagination > li.active span:focus { + background-color: #cccccc; + border-color: #cccccc; +} + +.pagination > li.active a { + background-color: #cccccc; +} + +.progress-bar-primary { + background-color: #cccccc; +} + +.progress-bar.progress-without-number[aria-valuenow="1"], +.progress-bar.progress-without-number[aria-valuenow="2"] { + min-width: 0; +} + +.progress-bar.progress-bar-primary[aria-valuenow="0"] { + background: transparent; +} + +.sidebar-right .sidebar-widget { + margin: 0; +} + +.sidebar-widget { + margin: 0 30px 0 25px; +} + +.sidebar-widget .widget-header { + position: relative; + margin: 0; +} + +.sidebar-widget .widget-header h6 { + font-size: 13px; + font-size: 1.3rem; + color: #465162; + font-weight: 600; + margin: 0; + padding: 0; + text-transform: uppercase; +} + +.sidebar-widget .widget-header .btn-widget-act { + position: relative; + top: -2px; + border-color: #0a0a0a; + background-color: #0a0a0a; + border-color: #0a0a0a black black; +} + +.sidebar-widget .widget-header .btn-widget-act:hover { + border-color: #121212; + background-color: #121212; +} + +.sidebar-widget .widget-header .btn-widget-act:active, .sidebar-widget .widget-header .btn-widget-act:focus { + border-color: black; + background-color: black; +} + +.sidebar-widget .widget-header .btn-widget-act.dropdown-toggle { + border-left-color: black; +} + +.sidebar-widget .widget-header .widget-toggle { + font-size: 17px; + font-size: 1.7rem; + line-height: 13px; + line-height: 1.3rem; + color: #465162; + position: absolute; + right: 0; + top: 0; + cursor: pointer; + text-align: center; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + -webkit-transition-property: -webkit-transform; + -moz-transition-property: -moz-transform; + transition-property: transform; + -webkit-transition-duration: 0.2s; + -moz-transition-duration: 0.2s; + transition-duration: 0.2s; + -webkit-transition-timing-function: linear; + -moz-transition-timing-function: linear; + transition-timing-function: linear; +} + +.sidebar-widget .widget-content { + padding: 15px 0 0; +} + +.sidebar-widget.widget-collapsed .widget-header .widget-toggle { + -webkit-transform: none; + -moz-transform: none; + -ms-transform: none; + -o-transform: none; + transform: none; +} + +.sidebar-widget.widget-collapsed .widget-content { + display: none; +} + +.sidebar-widget.widget-tasks ul li { + position: relative; +} + +.sidebar-widget.widget-tasks ul li a { + color: #abb4be; + display: block; + margin: 0 -25px 0 -30px; + padding: 10px 0 10px 55px; +} + +.sidebar-widget.widget-tasks ul li a:hover { + background: #21262d; + text-decoration: none; +} + +.sidebar-widget.widget-tasks ul li:before { + border: 5px solid #cccccc; + border-radius: 100px; + content: ''; + display: inline-block; + left: 0; + margin: -5px 0 0; + position: absolute; + top: 50%; + z-index: 999; +} + +.sidebar-widget.widget-tasks ul li:nth-child(6n+1):before { + border-color: #d64b4b; +} + +.sidebar-widget.widget-tasks ul li:nth-child(6n+2):before { + border-color: #0090d9; +} + +.sidebar-widget.widget-tasks ul li:nth-child(6n+3):before { + border-color: #4dd79c; +} + +.sidebar-widget.widget-tasks ul li:nth-child(6n+4):before { + border-color: #d9a300; +} + +.sidebar-widget.widget-tasks ul li:nth-child(6n+5):before { + border-color: #c926ff; +} + +.sidebar-widget.widget-tasks ul li:nth-child(6n+6):before { + border-color: #ffff26; +} + +.sidebar-widget.widget-stats ul { + list-style: none; + margin: 0; + padding: 0; +} + +.sidebar-widget.widget-stats .stats-title { + color: #a6a6a6; +} + +.sidebar-widget.widget-stats .stats-complete { + float: right; + font-size: 10px; + font-size: 1rem; + color: #666; +} + +.sidebar-widget.widget-stats .progress { + height: 7px; + background: #474453; + box-shadow: 0 1px 0 #585564 inset; + margin-bottom: 25px; +} + +.sidebar-widget.widget-calendar { + margin: 0 0 25px; +} + +.sidebar-widget.widget-calendar .datepicker { + background: transparent; +} + +.sidebar-widget.widget-calendar ul { + list-style: none; + margin: 0; + padding: 20px 0; + border-top: 1px solid #000; +} + +.sidebar-widget.widget-calendar ul time { + display: block; + font-size: 12px; + font-size: 1.2rem; + line-height: 1.3em; + font-weight: 600; + color: #777777; + margin-bottom: 0.1em; +} + +.sidebar-widget.widget-calendar ul span { + font-size: 14px; + font-size: 1.4rem; + line-height: 1.3em; + color: white; +} + +.sidebar-widget.widget-friends ul { + list-style: none; + margin: 0; + padding: 10px 2px; +} + +.sidebar-widget.widget-friends ul li { + padding: 10px 0; +} + +.sidebar-widget.widget-friends ul li .profile-info, +.sidebar-widget.widget-friends ul li .profile-picture { + display: inline-block; + vertical-align: middle; +} + +.sidebar-widget.widget-friends ul li .profile-picture { + position: relative; + width: 35px; +} + +.sidebar-widget.widget-friends ul li .profile-picture img { + width: 100%; + height: auto; +} + +.sidebar-widget.widget-friends ul li .profile-info { + margin: 0 35px 0 10px; +} + +.sidebar-widget.widget-friends ul li span.name { + display: block; + color: white; + font-weight: 600; + vertical-align: top; + line-height: 1.3em; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + margin-bottom: 0.2em; +} + +.sidebar-widget.widget-friends ul li span.title { + display: block; + font-size: 12px; + font-size: 1.2rem; + line-height: 1.3em; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; +} + +.sidebar-widget.widget-friends ul li.status-online .profile-picture:after, .sidebar-widget.widget-friends ul li.status-offline .profile-picture:after { + display: none; + position: absolute; + top: -4px; + right: -4px; + content: ''; + width: 15px; + height: 15px; + border: 2px solid #000; + border-radius: 50%; +} + +.sidebar-widget.widget-friends ul li.status-online .profile-picture:after { + display: block; + background-color: #1AAE88; +} + +.sidebar-widget.widget-friends ul li.status-offline .profile-picture:after { + display: block; + background-color: #D2312D; +} + +/* Scroll to Top */ +html .scroll-to-top { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + transition: all 0.3s; + background: #282d36; + border-radius: 7px 7px 0 0; + bottom: 0px; + color: #FFF; + display: block; + height: 9px; + opacity: 0; + padding: 5px 10px 25px; + position: fixed; + right: 10px; + text-align: center; + text-decoration: none; + min-width: 39px; + z-index: 1040; +} + +html .scroll-to-top:hover { + opacity: 1; +} + +html .scroll-to-top.visible { + opacity: 0.75; +} + +html .scroll-to-top span { + display: inline-block; + padding: 0 5px; +} + +html.ie11 .scroll-to-top { + right: 25px; +} + +/* Responsive */ +@media (max-width: 991px) { + html .scroll-to-top.hidden-mobile { + display: none !important; + } +} + +.panel { + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; + border: none; + /* WHY? + + .panel { + margin-top: 35px; + }*/; +} + +.panel-heading { + background: #0d4f88; + border-radius: 5px 5px 0 0; + border-bottom: 1px solid #428bca; + padding: 18px; + position: relative; +} + +.panel-heading.bg-primary { + background: #cccccc; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-secondary { + background: #e36159; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-tertiary { + background: #2baab1; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-quartenary { + background: #734ba9; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-success { + background: #47a447; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-warning { + background: #ed9c28; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-danger { + background: #d2322d; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-info { + background: #5bc0de; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-dark { + background: #171717; + color: white; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-heading.bg-white { + background: #fff; + border-bottom: 0 none; + border-right: 0 none; +} + +.panel-actions { + right: 15px; + position: absolute; + top: 15px; +} + +.panel-actions a, +.panel-actions .panel-action { + background-color: transparent; + border-radius: 2px; + color: #b4b4b4; + font-size: 14px; + height: 24px; + line-height: 24px; + text-align: center; + width: 24px; +} + +.panel-actions a:hover, +.panel-actions .panel-action:hover { + background-color: #eeeeee; + color: #b4b4b4; + text-decoration: none; +} + +.panel-actions a, .panel-actions a:focus, .panel-actions a:hover, .panel-actions a:active, .panel-actions a:visited, +.panel-actions .panel-action, +.panel-actions .panel-action:focus, +.panel-actions .panel-action:hover, +.panel-actions .panel-action:active, +.panel-actions .panel-action:visited { + outline: none !important; + text-decoration: none !important; +} + +.panel-title { + color: #f5f5f5; + font-size: 20px; + font-weight: 400; + line-height: 20px; + padding: 0; + text-transform: none; +} + +.panel-subtitle { + color: #808697; + font-size: 12px; + line-height: 1.2em; + margin: 7px 0 0; + padding: 0; +} + +.panel-body { + background: #fdfdfd; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + border-radius: 5px; +} + +.panel-body-nopadding { + padding: 0; +} + +.panel-heading + .panel-body { + border-radius: 0 0 5px 5px; +} + +.panel-footer { + border-radius: 0 0 5px 5px; + margin-top: -5px; +} + +.panel-footer-btn-group { + display: table; + width: 100%; + padding: 0; +} + +.panel-footer-btn-group a { + background-color: #f5f5f5; + display: table-cell; + width: 1%; + border-left: 1px solid #ddd; + padding: 10px 15px; + text-decoration: none; +} + +.panel-footer-btn-group a:hover { + background-color: #f0f0f0; + box-shadow: 0 0 7px rgba(0, 0, 0, 0.1) inset; +} + +.panel-footer-btn-group a:first-child { + border-left: none; +} + +.panel-body.bg-primary { + background: #cccccc; + color: white; +} + +.panel-body.bg-secondary { + background: #e36159; + color: white; +} + +.panel-body.bg-tertiary { + background: #2baab1; + color: white; +} + +.panel-body.bg-quartenary { + background: #734ba9; + color: white; +} + +.panel-body.bg-success { + background: #47a447; + color: white; +} + +.panel-body.bg-warning { + background: #ed9c28; + color: white; +} + +.panel-body.bg-danger { + background: #d2322d; + color: white; +} + +.panel-body.bg-info { + background: #5bc0de; + color: white; +} + +.panel-body.bg-dark { + background: #171717; + color: white; +} + +.panel-featured { + border-top: 3px solid #33353f; +} + +.panel-featured .panel-heading { + border-radius: 0; +} + +.panel-featured-top { + border-top: 3px solid #33353f; +} + +.panel-featured-right { + border-right: 3px solid #33353f; +} + +.panel-featured-bottom { + border-bottom: 3px solid #33353f; +} + +.panel-featured-left { + border-left: 3px solid #33353f; +} + +.panel-featured-primary { + border-color: #cccccc; +} + +.panel-featured-primary .panel-title { + color: #cccccc; +} + +.panel-featured-secondary { + border-color: #e36159; +} + +.panel-featured-secondary .panel-title { + color: #e36159; +} + +.panel-featured-tertiary { + border-color: #2baab1; +} + +.panel-featured-tertiary .panel-title { + color: #2baab1; +} + +.panel-featured-quartenary { + border-color: #734ba9; +} + +.panel-featured-quartenary .panel-title { + color: #734ba9; +} + +.panel-featured-success { + border-color: #47a447; +} + +.panel-featured-success .panel-title { + color: #47a447; +} + +.panel-featured-warning { + border-color: #ed9c28; +} + +.panel-featured-warning .panel-title { + color: #ed9c28; +} + +.panel-featured-danger { + border-color: #d2322d; +} + +.panel-featured-danger .panel-title { + color: #d2322d; +} + +.panel-featured-info { + border-color: #5bc0de; +} + +.panel-featured-info .panel-title { + color: #5bc0de; +} + +.panel-featured-dark { + border-color: #171717; +} + +.panel-featured-dark .panel-title { + color: #171717; +} + +.panel-highlight .panel-heading { + background-color: #cccccc; + border-color: #cccccc; + color: #fff; +} + +.panel-highlight .panel-title { + color: #fff; +} + +.panel-highlight .panel-subtitle { + color: #fff; + color: rgba(255, 255, 255, 0.7); +} + +.panel-highlight .panel-actions a { + background-color: rgba(0, 0, 0, 0.1); + color: #fff; +} + +.panel-highlight .panel-body { + background-color: #cccccc; + color: #fff; +} + +.panel-highlight-title .panel-heading { + background-color: #2BAAB1; +} + +.panel-highlight-title .panel-title { + color: #fff; +} + +.panel-highlight-title .panel-subtitle { + color: #fff; + color: rgba(255, 255, 255, 0.7); +} + +.panel-highlight-title .panel-actions a { + background-color: rgba(0, 0, 0, 0.1); + color: #fff; +} + +.panel-heading-icon { + margin: 0 auto; + font-size: 42px; + font-size: 4.2rem; + width: 90px; + height: 90px; + line-height: 90px; + text-align: center; + color: #fff; + background-color: rgba(0, 0, 0, 0.1); + -webkit-border-radius: 55px; + border-radius: 55px; +} + +.panel-heading-icon.bg-primary { + background: #cccccc; + color: white; +} + +.panel-heading-icon.bg-secondary { + background: #e36159; + color: white; +} + +.panel-heading-icon.bg-tertiary { + background: #2baab1; + color: white; +} + +.panel-heading-icon.bg-quartenary { + background: #734ba9; + color: white; +} + +.panel-heading-icon.bg-success { + background: #47a447; + color: white; +} + +.panel-heading-icon.bg-warning { + background: #ed9c28; + color: white; +} + +.panel-heading-icon.bg-danger { + background: #d2322d; + color: white; +} + +.panel-heading-icon.bg-info { + background: #5bc0de; + color: white; +} + +.panel-heading-icon.bg-dark { + background: #171717; + color: white; +} + +.panel-heading-profile-picture img { + display: block; + margin: 0 auto; + width: 100px; + height: 100px; + border: 4px solid #fff; + -webkit-border-radius: 50px; + border-radius: 50px; +} + +.panel-icon { + color: #fff; + font-size: 42px; + float: left; +} + +.panel-icon ~ .panel-title, .panel-icon ~ .panel-subtitle { + margin-left: 64px; +} + +/* Dark - Panels */ +html.dark .panel-heading { + background: #282d36; + border-bottom-color: #1d2127; +} + +html.dark .panel-actions a:hover { + background-color: #242830; +} + +html.dark .panel-body { + background: #2e353e; +} + +html.dark .panel-footer { + background: #242830; + border-top-color: #191c21; +} + +html .panel-primary .panel-heading { + background: #cccccc; +} + +html .panel-primary .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-primary .panel-title { + color: white; +} + +html .panel-primary .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-secondary .panel-heading { + background: #e36159; +} + +html .panel-secondary .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-secondary .panel-title { + color: white; +} + +html .panel-secondary .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-tertiary .panel-heading { + background: #2baab1; +} + +html .panel-tertiary .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-tertiary .panel-title { + color: white; +} + +html .panel-tertiary .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-quartenary .panel-heading { + background: #734ba9; +} + +html .panel-quartenary .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-quartenary .panel-title { + color: white; +} + +html .panel-quartenary .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-success .panel-heading { + background: #47a447; +} + +html .panel-success .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-success .panel-title { + color: white; +} + +html .panel-success .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-warning .panel-heading { + background: #ed9c28; +} + +html .panel-warning .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-warning .panel-title { + color: white; +} + +html .panel-warning .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-danger .panel-heading { + background: #d2322d; +} + +html .panel-danger .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-danger .panel-title { + color: white; +} + +html .panel-danger .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-info .panel-heading { + background: #5bc0de; +} + +html .panel-info .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-info .panel-title { + color: white; +} + +html .panel-info .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-dark .panel-heading { + background: #171717; +} + +html .panel-dark .panel-subtitle { + opacity: 0.8; + color: white; +} + +html .panel-dark .panel-title { + color: white; +} + +html .panel-dark .panel-actions a { + background-color: transparent !important; + color: white; +} + +html .panel-transparent > .panel-heading { + background: none; + border: 0; + padding-left: 0; + padding-right: 0; +} + +html .panel-transparent > .panel-heading .panel-actions { + right: 0; +} + +html .panel-transparent > .panel-heading + .panel-body { + border-radius: 5px; +} + +html .panel-transparent > .panel-body { + padding: 0; + border-radius: 0; + background: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} + +html .panel .panel-heading-transparent { + background: none; + border: 0; + padding-left: 0; + padding-right: 0; +} + +html .panel .panel-heading-transparent .panel-actions { + right: 0; +} + +html .panel .panel-heading-transparent + .panel-body { + border-radius: 5px; +} + +.panel-horizontal { + display: table; + width: 100%; +} + +.panel-horizontal .panel-heading, +.panel-horizontal .panel-body, +.panel-horizontal .panel-footer { + display: table-cell; + vertical-align: middle; +} + +.panel-horizontal .panel-heading { + border-radius: 5px 0 0 5px; +} + +.panel-horizontal .panel-heading + .panel-body { + border-radius: 0 5px 5px 0; +} + +.panel-horizontal .panel-footer { + border-radius: 0 5px 5px 0; + margin-top: 0; +} + +.panel-action-toggle, +.panel-action-dismiss { + display: inline-block; + font: normal normal normal 14px/1 FontAwesome; + font-size: inherit; + text-rendering: auto; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.panel-action-toggle:before { + content: "\f0d7"; +} + +.panel-collapsed .panel-action-toggle:before { + content: "\f0d8"; +} + +.panel-action-dismiss:before { + content: "\f00d"; +} + +.panel-collapsed .panel-body, +.panel-collapsed .panel-footer { + display: none; +} + +@media only screen and (max-width: 767px) { + .panel-actions { + float: none; + margin-bottom: 15px; + position: static; + text-align: right; + } + + .panel-actions a { + vertical-align: top; + } +} +/* tabs */ +.tabs { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + margin-bottom: 35px; +} + +/* navigation */ +.nav-tabs { + margin: 0; + font-size: 0; +} + +.nav-tabs li { + display: inline-block; + float: none; +} + +.nav-tabs li:last-child a { + margin-right: 0; +} + +.nav-tabs li a { + border-radius: 5px 5px 0 0; + font-size: 13px; + font-size: 1.3rem; + margin-right: 1px; +} + +.nav-tabs li a, .nav-tabs li a:hover { + background: #f4f4f4; + border-bottom: none; + border-left: 1px solid #eeeeee; + border-right: 1px solid #eeeeee; + border-top: 3px solid #dddddd; + color: #555555; +} + +.nav-tabs li a:hover { + border-bottom-color: transparent; + border-top: 3px solid #555555; + box-shadow: none; +} + +.nav-tabs li a:active, .nav-tabs li a:focus { + border-bottom: 0; +} + +.nav-tabs li.active a, +.nav-tabs li.active a:hover, +.nav-tabs li.active a:focus { + background: white; + border-left-color: #eeeeee; + border-right-color: #eeeeee; + border-top: 3px solid #555555; + color: #555555; +} + +/* content */ +.tab-content { + border-radius: 0 0 4px 4px; + box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.04); + background-color: white; + border: 1px solid #eeeeee; + border-top: 0; + padding: 15px; +} + +/* content - footer inside */ +.tab-content .panel-footer { + margin: -15px; + margin-top: 15px; +} + +/* Justified */ +.nav-tabs.nav-justified { + margin-bottom: -1px; + border-left: 1px solid transparent; + border-right: 1px solid transparent; +} + +.nav-tabs.nav-justified li { + margin-bottom: 0; +} + +.nav-tabs.nav-justified li:first-child a, +.nav-tabs.nav-justified li:first-child a:hover { + border-radius: 5px 0 0 0; + border-left: none; +} + +.nav-tabs.nav-justified li:last-child a, +.nav-tabs.nav-justified li:last-child a:hover { + border-radius: 0 5px 0 0; + border-right: none; +} + +.nav-tabs.nav-justified li a { + border-left: none; + border-right: none; + border-bottom: 1px solid #DDD; + border-radius: 0; + margin-right: 0; +} + +.nav-tabs.nav-justified li a:hover, .nav-tabs.nav-justified li a:focus { + border-bottom: 1px solid #DDD; + border-left: none; + border-right: none; +} + +.nav-tabs.nav-justified li.active a, +.nav-tabs.nav-justified li.active a:hover, +.nav-tabs.nav-justified li.active a:focus { + background: white; + border-left-color: #eeeeee; + border-right-color: #eeeeee; + border-top: 3px solid #555555; + color: #555555; +} + +.nav-tabs.nav-justified li.active a { + border-bottom: 1px solid #FFF; +} + +.nav-tabs.nav-justified li.active a, .nav-tabs.nav-justified li.active a:hover, .nav-tabs.nav-justified li.active a:focus { + border-top-color: #555555; + border-top-width: 3px; + border-left: none; + border-right: none; +} + +.nav-tabs.nav-justified li.active a:hover { + border-bottom: 1px solid #FFF; +} + +/* Bottom Tabs */ +.tabs.tabs-bottom .tab-content { + border-radius: 4px 4px 0 0; + border-bottom: 0; + border-top: 1px solid #eeeeee; +} + +.tabs.tabs-bottom .nav-tabs { + border-bottom: none; + border-top: 1px solid #dddddd; +} + +.tabs.tabs-bottom .nav-tabs li { + margin-bottom: 0; + margin-top: -1px; +} + +.tabs.tabs-bottom .nav-tabs li:last-child a { + margin-right: 0; +} + +.tabs.tabs-bottom .nav-tabs li a { + border-radius: 0 0 5px 5px; + font-size: 13px; + font-size: 1.3rem; + margin-right: 1px; +} + +.tabs.tabs-bottom .nav-tabs li a, .tabs.tabs-bottom .nav-tabs li a:hover, .tabs.tabs-bottom .nav-tabs li a:focus, .tabs.tabs-bottom .nav-tabs li a:active { + border-bottom: 3px solid #dddddd; + border-top: 1px solid #dddddd; +} + +.tabs.tabs-bottom .nav-tabs li a:hover, .tabs.tabs-bottom .nav-tabs li a:focus, .tabs.tabs-bottom .nav-tabs li a:active { + border-bottom: 3px solid #555555; + border-top: 1px solid #dddddd; +} + +.tabs.tabs-bottom .nav-tabs li.active a, +.tabs.tabs-bottom .nav-tabs li.active a:hover, +.tabs.tabs-bottom .nav-tabs li.active a:focus { + border-bottom: 3px solid #555555; + border-top-color: transparent; +} + +/* Bottom Tabs with Justified Nav */ +.tabs.tabs-bottom .nav.nav-tabs.nav-justified { + border-top: none; +} + +.tabs.tabs-bottom .nav.nav-tabs.nav-justified li a { + margin-right: 0; + border-top-color: #dddddd; +} + +.tabs.tabs-bottom .nav.nav-tabs.nav-justified li:first-child a { + border-radius: 0 0 0 5px; +} + +.tabs.tabs-bottom .nav.nav-tabs.nav-justified li:last-child a { + margin-right: 0; + border-radius: 0 0 5px 0; +} + +.tabs.tabs-bottom .nav.nav-tabs.nav-justified li.active a, +.tabs.tabs-bottom .nav.nav-tabs.nav-justified li.active a:hover, +.tabs.tabs-bottom .nav.nav-tabs.nav-justified li.active a:focus { + border-top-color: transparent; +} + +/* Vertical */ +.tabs-vertical { + display: table; + width: 100%; +} + +.tabs-vertical .tab-content { + display: table-cell; + vertical-align: top; +} + +.tabs-vertical .nav-tabs { + border-bottom: none; + display: table-cell; + height: 100%; + float: none; + padding: 0; + vertical-align: top; +} + +.tabs-vertical .nav-tabs > li { + display: block; +} + +.tabs-vertical .nav-tabs > li a { + border-radius: 0; + display: block; + padding-top: 10px; +} + +.tabs-vertical .nav-tabs > li a, .tabs-vertical .nav-tabs > li a:hover, .tabs-vertical .nav-tabs > li a:focus { + border-bottom: none; + border-top: none; +} + +.tabs-vertical .nav-tabs > li.active a, +.tabs-vertical .nav-tabs > li.active a:hover, .tabs-vertical .nav-tabs > li.active:focus { + border-top: none; +} + +/* Vertical - Left Side */ +.tabs-left .tab-content { + border-radius: 0 5px 5px 5px; + border-left: none; +} + +.tabs-left .nav-tabs > li { + margin-right: -1px; +} + +.tabs-left .nav-tabs > li:first-child a { + border-radius: 5px 0 0 0; +} + +.tabs-left .nav-tabs > li:last-child a { + border-radius: 0 0 0 5px; +} + +.tabs-left .nav-tabs > li a { + border-right: 1px solid #eeeeee; + border-left: 3px solid #dddddd; + margin-right: 1px; + margin-left: -3px; +} + +.tabs-left .nav-tabs > li a:hover { + border-left-color: #555555; +} + +.tabs-left .nav-tabs > li.active a, +.tabs-left .nav-tabs > li.active a:hover, +.tabs-left .nav-tabs > li.active a:focus { + border-left: 3px solid #555555; + border-right-color: #FFF; +} + +/* Vertical - Right Side */ +.tabs-right .tab-content { + border-radius: 5px 0 5px 5px; + border-right: none; +} + +.tabs-right .nav-tabs > li { + margin-left: -1px; +} + +.tabs-right .nav-tabs > li:first-child a { + border-radius: 0 5px 0 0; +} + +.tabs-right .nav-tabs > li:last-child a { + border-radius: 0 0 5px 0; +} + +.tabs-right .nav-tabs > li a { + border-right: 3px solid #dddddd; + border-left: 1px solid #eeeeee; + margin-right: 1px; + margin-left: 1px; +} + +.tabs-right .nav-tabs > li a:hover { + border-right-color: #555555; +} + +.tabs-right .nav-tabs > li.active a, +.tabs-right .nav-tabs > li.active a:hover, +.tabs-right .nav-tabs > li.active a:focus { + border-right: 3px solid #555555; + border-left: 1px solid #FFF; +} + +/* dark */ +html.dark .tabs .nav-tabs li a, +html.dark .tabs .nav-tabs li a:focus { + border-top-color: #282d36; + border-left-color: #282d36; + border-right-color: #282d36; + background: #282d36; +} + +html.dark .tabs .nav-tabs li a:hover { + border-top-color: #808697; +} + +html.dark .tabs .nav-tabs li.active a, +html.dark .tabs .nav-tabs li.active a:hover, +html.dark .tabs .nav-tabs li.active a:focus { + border-top-color: #808697; +} + +html.dark .tabs .nav-tabs.nav-justified { + border-left-width: 0; + border-right-width: 0; + border-left-color: transparent; + border-right-color: transparent; +} + +html.dark .tabs .nav-tabs.nav-justified li a, +html.dark .tabs .nav-tabs.nav-justified li a:hover, +html.dark .tabs .nav-tabs.nav-justified li a:focus { + border-bottom-color: #282d36; +} + +html.dark .tabs.tabs-left .nav-tabs > li a, html.dark .tabs.tabs-right .nav-tabs > li a { + background: #282d36; + border-left-color: #282d36; + border-right-color: #282d36; +} + +html.dark .tabs.tabs-left .nav-tabs > li:last-child a, html.dark .tabs.tabs-right .nav-tabs > li:last-child a { + border-bottom-color: #282d36; +} + +html.dark .tabs.tabs-left .nav-tabs > li.active a, +html.dark .tabs.tabs-left .nav-tabs > li.active a:hover, +html.dark .tabs.tabs-left .nav-tabs > li.active a:focus { + border-left: 3px solid #555555; +} + +html.dark .tabs.tabs-left .nav-tabs > li a:hover { + border-left: 3px solid #555555; +} + +html.dark .tabs .nav-tabs { + border-color: #282d36; +} + +html.dark .tabs .nav-tabs li.active a, +html.dark .tabs .nav-tabs li.active a:hover, +html.dark .tabs .nav-tabs li.active a:focus, +html.dark .tabs .nav-tabs.nav-justified li.active a, +html.dark .tabs .nav-tabs.nav-justified li.active a:hover, +html.dark .tabs .nav-tabs.nav-justified li.active a:focus { + background: #2e353e; + border-left-color: #2e353e; + border-right-color: #2e353e; +} + +html.dark .tabs .nav-tabs.nav-justified li.active a { + border-bottom-color: #2e353e; +} + +html.dark .tabs.tabs-vertical { + border-top-color: #2e353e; +} + +html.dark .tabs.tabs-bottom .nav-tabs li a, +html.dark .tabs.tabs-bottom .nav-tabs li a:focus { + border-bottom-color: #282d36; + border-top-color: #2e353e; +} + +html.dark .tabs.tabs-bottom .nav-tabs li a:hover { + border-bottom-color: #808697; + border-top-color: #2e353e; +} + +html.dark .tabs.tabs-bottom .nav-tabs li.active a, +html.dark .tabs.tabs-bottom .nav-tabs li.active a:hover, +html.dark .tabs.tabs-bottom .nav-tabs li.active a:focus { + border-bottom-color: #808697; + border-top-color: #2e353e; +} + +html.dark .tabs .tab-content { + background: #2e353e; + border-color: #2e353e; +} + +html.dark .tabs-primary.tabs-bottom .nav-tabs li a, +html.dark .tabs-primary.tabs-bottom .nav-tabs li a:hover, +html.dark .tabs-primary.tabs-bottom .nav-tabs li a:focus, html.dark .tabs-primary.tabs-bottom .nav-tabs.nav-justified li a, +html.dark .tabs-primary.tabs-bottom .nav-tabs.nav-justified li a:hover, +html.dark .tabs-primary.tabs-bottom .nav-tabs.nav-justified li a:focus { + border-top-color: #2e353e !important; +} + +html.dark .nav-tabs li.active a, +html.dark .nav-tabs li.active a:hover, +html.dark .nav-tabs li.active a:focus, +html.dark .nav-tabs li a { + color: #808697; +} + +html.dark .tab-content { + background: #2e353e; + border-color: #1d2127; +} + +/* states */ +html body .tabs-primary .nav-tabs li a, html body .tabs-primary .nav-tabs li a:hover, html body .tabs-primary .nav-tabs.nav-justified li a, html body .tabs-primary .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-primary .nav-tabs li a, +html.dark body .tabs-primary .nav-tabs li a:hover, +html.dark body .tabs-primary .nav-tabs.nav-justified li a, +html.dark body .tabs-primary .nav-tabs.nav-justified li a:hover { + color: #cccccc; +} + +html body .tabs-primary .nav-tabs li a:hover, html body .tabs-primary .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-primary .nav-tabs li a:hover, +html.dark body .tabs-primary .nav-tabs.nav-justified li a:hover { + border-top-color: #cccccc; +} + +html body .tabs-primary .nav-tabs li.active a, +html body .tabs-primary .nav-tabs li.active a:hover, +html body .tabs-primary .nav-tabs li.active a:focus, html body .tabs-primary .nav-tabs.nav-justified li.active a, +html body .tabs-primary .nav-tabs.nav-justified li.active a:hover, +html body .tabs-primary .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-primary .nav-tabs li.active a, +html.dark body .tabs-primary .nav-tabs li.active a:hover, +html.dark body .tabs-primary .nav-tabs li.active a:focus, +html.dark body .tabs-primary .nav-tabs.nav-justified li.active a, +html.dark body .tabs-primary .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-primary .nav-tabs.nav-justified li.active a:focus { + border-top-color: #cccccc; + color: #cccccc; +} + +html body .tabs-primary.tabs-bottom .nav-tabs li a:hover, html body .tabs-primary.tabs-bottom .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-primary.tabs-bottom .nav-tabs li a:hover, +html.dark body .tabs-primary.tabs-bottom .nav-tabs.nav-justified li a:hover { + border-bottom-color: #cccccc; +} + +html body .tabs-primary.tabs-bottom .nav-tabs li.active a, +html body .tabs-primary.tabs-bottom .nav-tabs li.active a:hover, +html body .tabs-primary.tabs-bottom .nav-tabs li.active a:focus, html body .tabs-primary.tabs-bottom .nav-tabs.nav-justified li.active a, +html body .tabs-primary.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html body .tabs-primary.tabs-bottom .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-primary.tabs-bottom .nav-tabs li.active a, +html.dark body .tabs-primary.tabs-bottom .nav-tabs li.active a:hover, +html.dark body .tabs-primary.tabs-bottom .nav-tabs li.active a:focus, +html.dark body .tabs-primary.tabs-bottom .nav-tabs.nav-justified li.active a, +html.dark body .tabs-primary.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-primary.tabs-bottom .nav-tabs.nav-justified li.active a:focus { + border-bottom-color: #cccccc; +} + +html body .tabs-primary.tabs-vertical.tabs-left li a:hover, +html.dark body .tabs-primary.tabs-vertical.tabs-left li a:hover { + border-left-color: #cccccc; +} + +html body .tabs-primary.tabs-vertical.tabs-left li.active a, +html body .tabs-primary.tabs-vertical.tabs-left li.active a:hover, +html body .tabs-primary.tabs-vertical.tabs-left li.active a:focus, +html.dark body .tabs-primary.tabs-vertical.tabs-left li.active a, +html.dark body .tabs-primary.tabs-vertical.tabs-left li.active a:hover, +html.dark body .tabs-primary.tabs-vertical.tabs-left li.active a:focus { + border-left-color: #cccccc; +} + +html body .tabs-primary.tabs-vertical.tabs-right li a:hover, +html.dark body .tabs-primary.tabs-vertical.tabs-right li a:hover { + border-right-color: #cccccc; +} + +html body .tabs-primary.tabs-vertical.tabs-right li.active a, +html body .tabs-primary.tabs-vertical.tabs-right li.active a:hover, +html body .tabs-primary.tabs-vertical.tabs-right li.active a:focus, +html.dark body .tabs-primary.tabs-vertical.tabs-right li.active a, +html.dark body .tabs-primary.tabs-vertical.tabs-right li.active a:hover, +html.dark body .tabs-primary.tabs-vertical.tabs-right li.active a:focus { + border-right-color: #cccccc; +} + +html body .tabs-success .nav-tabs li a, html body .tabs-success .nav-tabs li a:hover, html body .tabs-success .nav-tabs.nav-justified li a, html body .tabs-success .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-success .nav-tabs li a, +html.dark body .tabs-success .nav-tabs li a:hover, +html.dark body .tabs-success .nav-tabs.nav-justified li a, +html.dark body .tabs-success .nav-tabs.nav-justified li a:hover { + color: #47a447; +} + +html body .tabs-success .nav-tabs li a:hover, html body .tabs-success .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-success .nav-tabs li a:hover, +html.dark body .tabs-success .nav-tabs.nav-justified li a:hover { + border-top-color: #47a447; +} + +html body .tabs-success .nav-tabs li.active a, +html body .tabs-success .nav-tabs li.active a:hover, +html body .tabs-success .nav-tabs li.active a:focus, html body .tabs-success .nav-tabs.nav-justified li.active a, +html body .tabs-success .nav-tabs.nav-justified li.active a:hover, +html body .tabs-success .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-success .nav-tabs li.active a, +html.dark body .tabs-success .nav-tabs li.active a:hover, +html.dark body .tabs-success .nav-tabs li.active a:focus, +html.dark body .tabs-success .nav-tabs.nav-justified li.active a, +html.dark body .tabs-success .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-success .nav-tabs.nav-justified li.active a:focus { + border-top-color: #47a447; + color: #47a447; +} + +html body .tabs-success.tabs-bottom .nav-tabs li a:hover, html body .tabs-success.tabs-bottom .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-success.tabs-bottom .nav-tabs li a:hover, +html.dark body .tabs-success.tabs-bottom .nav-tabs.nav-justified li a:hover { + border-bottom-color: #47a447; +} + +html body .tabs-success.tabs-bottom .nav-tabs li.active a, +html body .tabs-success.tabs-bottom .nav-tabs li.active a:hover, +html body .tabs-success.tabs-bottom .nav-tabs li.active a:focus, html body .tabs-success.tabs-bottom .nav-tabs.nav-justified li.active a, +html body .tabs-success.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html body .tabs-success.tabs-bottom .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-success.tabs-bottom .nav-tabs li.active a, +html.dark body .tabs-success.tabs-bottom .nav-tabs li.active a:hover, +html.dark body .tabs-success.tabs-bottom .nav-tabs li.active a:focus, +html.dark body .tabs-success.tabs-bottom .nav-tabs.nav-justified li.active a, +html.dark body .tabs-success.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-success.tabs-bottom .nav-tabs.nav-justified li.active a:focus { + border-bottom-color: #47a447; +} + +html body .tabs-success.tabs-vertical.tabs-left li a:hover, +html.dark body .tabs-success.tabs-vertical.tabs-left li a:hover { + border-left-color: #47a447; +} + +html body .tabs-success.tabs-vertical.tabs-left li.active a, +html body .tabs-success.tabs-vertical.tabs-left li.active a:hover, +html body .tabs-success.tabs-vertical.tabs-left li.active a:focus, +html.dark body .tabs-success.tabs-vertical.tabs-left li.active a, +html.dark body .tabs-success.tabs-vertical.tabs-left li.active a:hover, +html.dark body .tabs-success.tabs-vertical.tabs-left li.active a:focus { + border-left-color: #47a447; +} + +html body .tabs-success.tabs-vertical.tabs-right li a:hover, +html.dark body .tabs-success.tabs-vertical.tabs-right li a:hover { + border-right-color: #47a447; +} + +html body .tabs-success.tabs-vertical.tabs-right li.active a, +html body .tabs-success.tabs-vertical.tabs-right li.active a:hover, +html body .tabs-success.tabs-vertical.tabs-right li.active a:focus, +html.dark body .tabs-success.tabs-vertical.tabs-right li.active a, +html.dark body .tabs-success.tabs-vertical.tabs-right li.active a:hover, +html.dark body .tabs-success.tabs-vertical.tabs-right li.active a:focus { + border-right-color: #47a447; +} + +html body .tabs-warning .nav-tabs li a, html body .tabs-warning .nav-tabs li a:hover, html body .tabs-warning .nav-tabs.nav-justified li a, html body .tabs-warning .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-warning .nav-tabs li a, +html.dark body .tabs-warning .nav-tabs li a:hover, +html.dark body .tabs-warning .nav-tabs.nav-justified li a, +html.dark body .tabs-warning .nav-tabs.nav-justified li a:hover { + color: #ed9c28; +} + +html body .tabs-warning .nav-tabs li a:hover, html body .tabs-warning .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-warning .nav-tabs li a:hover, +html.dark body .tabs-warning .nav-tabs.nav-justified li a:hover { + border-top-color: #ed9c28; +} + +html body .tabs-warning .nav-tabs li.active a, +html body .tabs-warning .nav-tabs li.active a:hover, +html body .tabs-warning .nav-tabs li.active a:focus, html body .tabs-warning .nav-tabs.nav-justified li.active a, +html body .tabs-warning .nav-tabs.nav-justified li.active a:hover, +html body .tabs-warning .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-warning .nav-tabs li.active a, +html.dark body .tabs-warning .nav-tabs li.active a:hover, +html.dark body .tabs-warning .nav-tabs li.active a:focus, +html.dark body .tabs-warning .nav-tabs.nav-justified li.active a, +html.dark body .tabs-warning .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-warning .nav-tabs.nav-justified li.active a:focus { + border-top-color: #ed9c28; + color: #ed9c28; +} + +html body .tabs-warning.tabs-bottom .nav-tabs li a:hover, html body .tabs-warning.tabs-bottom .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-warning.tabs-bottom .nav-tabs li a:hover, +html.dark body .tabs-warning.tabs-bottom .nav-tabs.nav-justified li a:hover { + border-bottom-color: #ed9c28; +} + +html body .tabs-warning.tabs-bottom .nav-tabs li.active a, +html body .tabs-warning.tabs-bottom .nav-tabs li.active a:hover, +html body .tabs-warning.tabs-bottom .nav-tabs li.active a:focus, html body .tabs-warning.tabs-bottom .nav-tabs.nav-justified li.active a, +html body .tabs-warning.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html body .tabs-warning.tabs-bottom .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-warning.tabs-bottom .nav-tabs li.active a, +html.dark body .tabs-warning.tabs-bottom .nav-tabs li.active a:hover, +html.dark body .tabs-warning.tabs-bottom .nav-tabs li.active a:focus, +html.dark body .tabs-warning.tabs-bottom .nav-tabs.nav-justified li.active a, +html.dark body .tabs-warning.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-warning.tabs-bottom .nav-tabs.nav-justified li.active a:focus { + border-bottom-color: #ed9c28; +} + +html body .tabs-warning.tabs-vertical.tabs-left li a:hover, +html.dark body .tabs-warning.tabs-vertical.tabs-left li a:hover { + border-left-color: #ed9c28; +} + +html body .tabs-warning.tabs-vertical.tabs-left li.active a, +html body .tabs-warning.tabs-vertical.tabs-left li.active a:hover, +html body .tabs-warning.tabs-vertical.tabs-left li.active a:focus, +html.dark body .tabs-warning.tabs-vertical.tabs-left li.active a, +html.dark body .tabs-warning.tabs-vertical.tabs-left li.active a:hover, +html.dark body .tabs-warning.tabs-vertical.tabs-left li.active a:focus { + border-left-color: #ed9c28; +} + +html body .tabs-warning.tabs-vertical.tabs-right li a:hover, +html.dark body .tabs-warning.tabs-vertical.tabs-right li a:hover { + border-right-color: #ed9c28; +} + +html body .tabs-warning.tabs-vertical.tabs-right li.active a, +html body .tabs-warning.tabs-vertical.tabs-right li.active a:hover, +html body .tabs-warning.tabs-vertical.tabs-right li.active a:focus, +html.dark body .tabs-warning.tabs-vertical.tabs-right li.active a, +html.dark body .tabs-warning.tabs-vertical.tabs-right li.active a:hover, +html.dark body .tabs-warning.tabs-vertical.tabs-right li.active a:focus { + border-right-color: #ed9c28; +} + +html body .tabs-danger .nav-tabs li a, html body .tabs-danger .nav-tabs li a:hover, html body .tabs-danger .nav-tabs.nav-justified li a, html body .tabs-danger .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-danger .nav-tabs li a, +html.dark body .tabs-danger .nav-tabs li a:hover, +html.dark body .tabs-danger .nav-tabs.nav-justified li a, +html.dark body .tabs-danger .nav-tabs.nav-justified li a:hover { + color: #d2322d; +} + +html body .tabs-danger .nav-tabs li a:hover, html body .tabs-danger .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-danger .nav-tabs li a:hover, +html.dark body .tabs-danger .nav-tabs.nav-justified li a:hover { + border-top-color: #d2322d; +} + +html body .tabs-danger .nav-tabs li.active a, +html body .tabs-danger .nav-tabs li.active a:hover, +html body .tabs-danger .nav-tabs li.active a:focus, html body .tabs-danger .nav-tabs.nav-justified li.active a, +html body .tabs-danger .nav-tabs.nav-justified li.active a:hover, +html body .tabs-danger .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-danger .nav-tabs li.active a, +html.dark body .tabs-danger .nav-tabs li.active a:hover, +html.dark body .tabs-danger .nav-tabs li.active a:focus, +html.dark body .tabs-danger .nav-tabs.nav-justified li.active a, +html.dark body .tabs-danger .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-danger .nav-tabs.nav-justified li.active a:focus { + border-top-color: #d2322d; + color: #d2322d; +} + +html body .tabs-danger.tabs-bottom .nav-tabs li a:hover, html body .tabs-danger.tabs-bottom .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-danger.tabs-bottom .nav-tabs li a:hover, +html.dark body .tabs-danger.tabs-bottom .nav-tabs.nav-justified li a:hover { + border-bottom-color: #d2322d; +} + +html body .tabs-danger.tabs-bottom .nav-tabs li.active a, +html body .tabs-danger.tabs-bottom .nav-tabs li.active a:hover, +html body .tabs-danger.tabs-bottom .nav-tabs li.active a:focus, html body .tabs-danger.tabs-bottom .nav-tabs.nav-justified li.active a, +html body .tabs-danger.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html body .tabs-danger.tabs-bottom .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-danger.tabs-bottom .nav-tabs li.active a, +html.dark body .tabs-danger.tabs-bottom .nav-tabs li.active a:hover, +html.dark body .tabs-danger.tabs-bottom .nav-tabs li.active a:focus, +html.dark body .tabs-danger.tabs-bottom .nav-tabs.nav-justified li.active a, +html.dark body .tabs-danger.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-danger.tabs-bottom .nav-tabs.nav-justified li.active a:focus { + border-bottom-color: #d2322d; +} + +html body .tabs-danger.tabs-vertical.tabs-left li a:hover, +html.dark body .tabs-danger.tabs-vertical.tabs-left li a:hover { + border-left-color: #d2322d; +} + +html body .tabs-danger.tabs-vertical.tabs-left li.active a, +html body .tabs-danger.tabs-vertical.tabs-left li.active a:hover, +html body .tabs-danger.tabs-vertical.tabs-left li.active a:focus, +html.dark body .tabs-danger.tabs-vertical.tabs-left li.active a, +html.dark body .tabs-danger.tabs-vertical.tabs-left li.active a:hover, +html.dark body .tabs-danger.tabs-vertical.tabs-left li.active a:focus { + border-left-color: #d2322d; +} + +html body .tabs-danger.tabs-vertical.tabs-right li a:hover, +html.dark body .tabs-danger.tabs-vertical.tabs-right li a:hover { + border-right-color: #d2322d; +} + +html body .tabs-danger.tabs-vertical.tabs-right li.active a, +html body .tabs-danger.tabs-vertical.tabs-right li.active a:hover, +html body .tabs-danger.tabs-vertical.tabs-right li.active a:focus, +html.dark body .tabs-danger.tabs-vertical.tabs-right li.active a, +html.dark body .tabs-danger.tabs-vertical.tabs-right li.active a:hover, +html.dark body .tabs-danger.tabs-vertical.tabs-right li.active a:focus { + border-right-color: #d2322d; +} + +html body .tabs-info .nav-tabs li a, html body .tabs-info .nav-tabs li a:hover, html body .tabs-info .nav-tabs.nav-justified li a, html body .tabs-info .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-info .nav-tabs li a, +html.dark body .tabs-info .nav-tabs li a:hover, +html.dark body .tabs-info .nav-tabs.nav-justified li a, +html.dark body .tabs-info .nav-tabs.nav-justified li a:hover { + color: #5bc0de; +} + +html body .tabs-info .nav-tabs li a:hover, html body .tabs-info .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-info .nav-tabs li a:hover, +html.dark body .tabs-info .nav-tabs.nav-justified li a:hover { + border-top-color: #5bc0de; +} + +html body .tabs-info .nav-tabs li.active a, +html body .tabs-info .nav-tabs li.active a:hover, +html body .tabs-info .nav-tabs li.active a:focus, html body .tabs-info .nav-tabs.nav-justified li.active a, +html body .tabs-info .nav-tabs.nav-justified li.active a:hover, +html body .tabs-info .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-info .nav-tabs li.active a, +html.dark body .tabs-info .nav-tabs li.active a:hover, +html.dark body .tabs-info .nav-tabs li.active a:focus, +html.dark body .tabs-info .nav-tabs.nav-justified li.active a, +html.dark body .tabs-info .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-info .nav-tabs.nav-justified li.active a:focus { + border-top-color: #5bc0de; + color: #5bc0de; +} + +html body .tabs-info.tabs-bottom .nav-tabs li a:hover, html body .tabs-info.tabs-bottom .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-info.tabs-bottom .nav-tabs li a:hover, +html.dark body .tabs-info.tabs-bottom .nav-tabs.nav-justified li a:hover { + border-bottom-color: #5bc0de; +} + +html body .tabs-info.tabs-bottom .nav-tabs li.active a, +html body .tabs-info.tabs-bottom .nav-tabs li.active a:hover, +html body .tabs-info.tabs-bottom .nav-tabs li.active a:focus, html body .tabs-info.tabs-bottom .nav-tabs.nav-justified li.active a, +html body .tabs-info.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html body .tabs-info.tabs-bottom .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-info.tabs-bottom .nav-tabs li.active a, +html.dark body .tabs-info.tabs-bottom .nav-tabs li.active a:hover, +html.dark body .tabs-info.tabs-bottom .nav-tabs li.active a:focus, +html.dark body .tabs-info.tabs-bottom .nav-tabs.nav-justified li.active a, +html.dark body .tabs-info.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-info.tabs-bottom .nav-tabs.nav-justified li.active a:focus { + border-bottom-color: #5bc0de; +} + +html body .tabs-info.tabs-vertical.tabs-left li a:hover, +html.dark body .tabs-info.tabs-vertical.tabs-left li a:hover { + border-left-color: #5bc0de; +} + +html body .tabs-info.tabs-vertical.tabs-left li.active a, +html body .tabs-info.tabs-vertical.tabs-left li.active a:hover, +html body .tabs-info.tabs-vertical.tabs-left li.active a:focus, +html.dark body .tabs-info.tabs-vertical.tabs-left li.active a, +html.dark body .tabs-info.tabs-vertical.tabs-left li.active a:hover, +html.dark body .tabs-info.tabs-vertical.tabs-left li.active a:focus { + border-left-color: #5bc0de; +} + +html body .tabs-info.tabs-vertical.tabs-right li a:hover, +html.dark body .tabs-info.tabs-vertical.tabs-right li a:hover { + border-right-color: #5bc0de; +} + +html body .tabs-info.tabs-vertical.tabs-right li.active a, +html body .tabs-info.tabs-vertical.tabs-right li.active a:hover, +html body .tabs-info.tabs-vertical.tabs-right li.active a:focus, +html.dark body .tabs-info.tabs-vertical.tabs-right li.active a, +html.dark body .tabs-info.tabs-vertical.tabs-right li.active a:hover, +html.dark body .tabs-info.tabs-vertical.tabs-right li.active a:focus { + border-right-color: #5bc0de; +} + +html body .tabs-dark .nav-tabs li a, html body .tabs-dark .nav-tabs li a:hover, html body .tabs-dark .nav-tabs.nav-justified li a, html body .tabs-dark .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-dark .nav-tabs li a, +html.dark body .tabs-dark .nav-tabs li a:hover, +html.dark body .tabs-dark .nav-tabs.nav-justified li a, +html.dark body .tabs-dark .nav-tabs.nav-justified li a:hover { + color: #171717; +} + +html body .tabs-dark .nav-tabs li a:hover, html body .tabs-dark .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-dark .nav-tabs li a:hover, +html.dark body .tabs-dark .nav-tabs.nav-justified li a:hover { + border-top-color: #171717; +} + +html body .tabs-dark .nav-tabs li.active a, +html body .tabs-dark .nav-tabs li.active a:hover, +html body .tabs-dark .nav-tabs li.active a:focus, html body .tabs-dark .nav-tabs.nav-justified li.active a, +html body .tabs-dark .nav-tabs.nav-justified li.active a:hover, +html body .tabs-dark .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-dark .nav-tabs li.active a, +html.dark body .tabs-dark .nav-tabs li.active a:hover, +html.dark body .tabs-dark .nav-tabs li.active a:focus, +html.dark body .tabs-dark .nav-tabs.nav-justified li.active a, +html.dark body .tabs-dark .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-dark .nav-tabs.nav-justified li.active a:focus { + border-top-color: #171717; + color: #171717; +} + +html body .tabs-dark.tabs-bottom .nav-tabs li a:hover, html body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li a:hover, +html.dark body .tabs-dark.tabs-bottom .nav-tabs li a:hover, +html.dark body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li a:hover { + border-bottom-color: #171717; +} + +html body .tabs-dark.tabs-bottom .nav-tabs li.active a, +html body .tabs-dark.tabs-bottom .nav-tabs li.active a:hover, +html body .tabs-dark.tabs-bottom .nav-tabs li.active a:focus, html body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a, +html body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a:focus, +html.dark body .tabs-dark.tabs-bottom .nav-tabs li.active a, +html.dark body .tabs-dark.tabs-bottom .nav-tabs li.active a:hover, +html.dark body .tabs-dark.tabs-bottom .nav-tabs li.active a:focus, +html.dark body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a, +html.dark body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a:focus { + border-bottom-color: #171717; +} + +html body .tabs-dark.tabs-vertical.tabs-left li a:hover, +html.dark body .tabs-dark.tabs-vertical.tabs-left li a:hover { + border-left-color: #171717; +} + +html body .tabs-dark.tabs-vertical.tabs-left li.active a, +html body .tabs-dark.tabs-vertical.tabs-left li.active a:hover, +html body .tabs-dark.tabs-vertical.tabs-left li.active a:focus, +html.dark body .tabs-dark.tabs-vertical.tabs-left li.active a, +html.dark body .tabs-dark.tabs-vertical.tabs-left li.active a:hover, +html.dark body .tabs-dark.tabs-vertical.tabs-left li.active a:focus { + border-left-color: #171717; +} + +html body .tabs-dark.tabs-vertical.tabs-right li a:hover, +html.dark body .tabs-dark.tabs-vertical.tabs-right li a:hover { + border-right-color: #171717; +} + +html body .tabs-dark.tabs-vertical.tabs-right li.active a, +html body .tabs-dark.tabs-vertical.tabs-right li.active a:hover, +html body .tabs-dark.tabs-vertical.tabs-right li.active a:focus, +html.dark body .tabs-dark.tabs-vertical.tabs-right li.active a, +html.dark body .tabs-dark.tabs-vertical.tabs-right li.active a:hover, +html.dark body .tabs-dark.tabs-vertical.tabs-right li.active a:focus { + border-right-color: #171717; +} + +/* dark */ +html.dark body .tabs-dark .nav-tabs li a, html.dark body .tabs-dark .nav-tabs li a:hover, html.dark body .tabs-dark .nav-tabs.nav-justified li a, html.dark body .tabs-dark .nav-tabs.nav-justified li a:hover { + color: #FFF; +} + +html.dark body .tabs-dark .nav-tabs li a:hover, html.dark body .tabs-dark .nav-tabs.nav-justified li a:hover { + border-top-color: #FFF; +} + +html.dark body .tabs-dark .nav-tabs li.active a, +html.dark body .tabs-dark .nav-tabs li.active a:hover, +html.dark body .tabs-dark .nav-tabs li.active a:focus, html.dark body .tabs-dark .nav-tabs.nav-justified li.active a, +html.dark body .tabs-dark .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-dark .nav-tabs.nav-justified li.active a:focus { + border-top-color: #FFF; + color: #FFF; +} + +html.dark body .tabs-dark.tabs-bottom .nav-tabs li a:hover, html.dark body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li a:hover { + border-bottom-color: #FFF; +} + +html.dark body .tabs-dark.tabs-bottom .nav-tabs li.active a, +html.dark body .tabs-dark.tabs-bottom .nav-tabs li.active a:hover, +html.dark body .tabs-dark.tabs-bottom .nav-tabs li.active a:focus, html.dark body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a, +html.dark body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a:hover, +html.dark body .tabs-dark.tabs-bottom .nav-tabs.nav-justified li.active a:focus { + border-bottom-color: #FFF; +} + +html.dark body .tabs-dark.tabs-vertical.tabs-left li a:hover { + border-left-color: #FFF; +} + +html.dark body .tabs-dark.tabs-vertical.tabs-left li.active a, +html.dark body .tabs-dark.tabs-vertical.tabs-left li.active a:hover, +html.dark body .tabs-dark.tabs-vertical.tabs-left li.active a:focus { + border-left-color: #FFF; +} + +html.dark body .tabs-dark.tabs-vertical.tabs-right li a:hover { + border-right-color: #FFF; +} + +html.dark body .tabs-dark.tabs-vertical.tabs-right li.active a, +html.dark body .tabs-dark.tabs-vertical.tabs-right li.active a:hover, +html.dark body .tabs-dark.tabs-vertical.tabs-right li.active a:focus { + border-right-color: #FFF; +} + +/* Slider - */ +.ui-slider.ui-widget-content { + background: #ebebeb; + border: none; +} + +/* Sliders - Horizontal */ +.ui-slider-horizontal { + height: 6px; +} + +.ui-slider-horizontal .ui-slider-handle { + top: -7px; +} + +/* Sliders - Vertical */ +.ui-slider-vertical { + display: inline-block; + width: 6px; +} + +.ui-slider-vertical .ui-slider-handle { + left: -7px; +} + +/* Sliders - UI Handle */ +.ui-slider .ui-slider-handle { + background: #d9d9d9; + border: 6px solid #fff; + border-radius: 50%; + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.4); + cursor: pointer; + height: 20px; + width: 20px; +} + +.ui-slider .ui-slider-handle:hover { + box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.3); +} + +/* Sliders - UI Handle (Fix Windows Mobile Devices) */ +.ui-slider .ui-slider-handle { + -ms-touch-action: none; + touch-action: none; +} + +/* Sliders - Range */ +.ui-slider .ui-slider-range { + background: #d9d9d9; +} + +/* Sliders - Contextual */ +.slider-primary .ui-slider-range, +.slider-primary .ui-slider-handle { + background: #cccccc; +} + +.slider-gradient.slider-primary .ui-slider-range, +.slider-gradient.slider-primary .ui-slider-handle { + background-image: -webkit-linear-gradient(#e6e6e6 0, #cccccc 50%, #b3b3b3 100%); + background-image: linear-gradient(to , #cccccc 50%, #b3b3b3 100%); +} + +.slider-gradient.ui-slider-vertical.slider-primary .ui-slider-range, +.slider-gradient.ui-slider-vertical.slider-primary .ui-slider-handle { + background-image: -webkit-linear-gradient( left , #e6e6e6 0, #cccccc 50%, #b3b3b3 100%); + background-image: linear-gradient(to right, #e6e6e6 0, #cccccc 50%, #b3b3b3 100%); +} + +.slider-success .ui-slider-range, +.slider-success .ui-slider-handle { + background: #47a447; +} + +.slider-gradient.slider-success .ui-slider-range, +.slider-gradient.slider-success .ui-slider-handle { + background-image: -webkit-linear-gradient(#63bb63 0, #47a447 50%, #388038 100%); + background-image: linear-gradient(to , #47a447 50%, #388038 100%); +} + +.slider-gradient.ui-slider-vertical.slider-success .ui-slider-range, +.slider-gradient.ui-slider-vertical.slider-success .ui-slider-handle { + background-image: -webkit-linear-gradient( left , #63bb63 0, #47a447 50%, #388038 100%); + background-image: linear-gradient(to right, #63bb63 0, #47a447 50%, #388038 100%); +} + +.slider-warning .ui-slider-range, +.slider-warning .ui-slider-handle { + background: #ed9c28; +} + +.slider-gradient.slider-warning .ui-slider-range, +.slider-gradient.slider-warning .ui-slider-handle { + background-image: -webkit-linear-gradient(#f1b257 0, #ed9c28 50%, #d18211 100%); + background-image: linear-gradient(to , #ed9c28 50%, #d18211 100%); +} + +.slider-gradient.ui-slider-vertical.slider-warning .ui-slider-range, +.slider-gradient.ui-slider-vertical.slider-warning .ui-slider-handle { + background-image: -webkit-linear-gradient( left , #f1b257 0, #ed9c28 50%, #d18211 100%); + background-image: linear-gradient(to right, #f1b257 0, #ed9c28 50%, #d18211 100%); +} + +.slider-danger .ui-slider-range, +.slider-danger .ui-slider-handle { + background: #d2322d; +} + +.slider-gradient.slider-danger .ui-slider-range, +.slider-gradient.slider-danger .ui-slider-handle { + background-image: -webkit-linear-gradient(#db5b57 0, #d2322d 50%, #a82824 100%); + background-image: linear-gradient(to , #d2322d 50%, #a82824 100%); +} + +.slider-gradient.ui-slider-vertical.slider-danger .ui-slider-range, +.slider-gradient.ui-slider-vertical.slider-danger .ui-slider-handle { + background-image: -webkit-linear-gradient( left , #db5b57 0, #d2322d 50%, #a82824 100%); + background-image: linear-gradient(to right, #db5b57 0, #d2322d 50%, #a82824 100%); +} + +.slider-info .ui-slider-range, +.slider-info .ui-slider-handle { + background: #5bc0de; +} + +.slider-gradient.slider-info .ui-slider-range, +.slider-gradient.slider-info .ui-slider-handle { + background-image: -webkit-linear-gradient(#85d0e7 0, #5bc0de 50%, #31b0d5 100%); + background-image: linear-gradient(to , #5bc0de 50%, #31b0d5 100%); +} + +.slider-gradient.ui-slider-vertical.slider-info .ui-slider-range, +.slider-gradient.ui-slider-vertical.slider-info .ui-slider-handle { + background-image: -webkit-linear-gradient( left , #85d0e7 0, #5bc0de 50%, #31b0d5 100%); + background-image: linear-gradient(to right, #85d0e7 0, #5bc0de 50%, #31b0d5 100%); +} + +.slider-dark .ui-slider-range, +.slider-dark .ui-slider-handle { + background: #171717; +} + +.slider-gradient.slider-dark .ui-slider-range, +.slider-gradient.slider-dark .ui-slider-handle { + background-image: -webkit-linear-gradient(#313131 0, #171717 50%, black 100%); + background-image: linear-gradient(to , #171717 50%, black 100%); +} + +.slider-gradient.ui-slider-vertical.slider-dark .ui-slider-range, +.slider-gradient.ui-slider-vertical.slider-dark .ui-slider-handle { + background-image: -webkit-linear-gradient( left , #313131 0, #171717 50%, black 100%); + background-image: linear-gradient(to right, #313131 0, #171717 50%, black 100%); +} + +html.dark .ui-slider.ui-widget-content { + background: #21262d; +} + +/* Alert new states */ +.alert-default { + background-color: #ebebeb; + border-color: #e3e3e3; + color: #6c6c6c; +} + +.alert-default .alert-link { + color: #454545; +} + +.alert-primary { + background-color: #cccccc; + border-color: #c4c4c4; + color: white; +} + +.alert-primary .alert-link { + color: #999999; +} + +.alert-dark { + background-color: #313131; + border-color: black; + color: #cacaca; +} + +.alert-dark .alert-link { + color: #f0f0f0; +} + +/* Notification */ +.ui-pnotify { + right: 15px; + top: 15px; +} + +.ui-pnotify .notification { + border-radius: 5px; + box-shadow: none; + padding: 15px 15px 15px 75px; +} + +.ui-pnotify .notification .ui-pnotify-icon { + left: 0; + position: absolute; + top: 0; + width: 75px; + text-align: center; +} + +.ui-pnotify .notification .ui-pnotify-icon > span { + border: 2px solid #FFF; + border-radius: 50%; + display: inline-block; + float: none; + font-size: 35px; + height: 50px; + line-height: 48px; + margin: 8px 0 0; + padding: 0; + width: 50px; + text-align: center; +} + +.ui-pnotify .notification .ui-pnotify-title { + font-size: 14px; + letter-spacing: 0; +} + +.ui-pnotify .notification .ui-pnotify-text { + font-size: 12px; + line-height: 1.3em; +} + +.ui-pnotify .notification.notification-danger .ui-pnotify-icon > span.fa-times { + line-height: 47px; +} + +.ui-pnotify .ui-pnotify-shadow { + box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.4); +} + +.ui-pnotify.ui-pnotify-no-icon .notification { + padding-left: 15px; +} + +.ui-pnotify .ui-pnotify-sharp { + border-radius: 0; +} + +body .ui-pnotify.icon-nb .notification .ui-pnotify-icon > span { + border-color: transparent; + border-radius: 0; +} + +.ui-pnotify.stack-bar-top { + right: 0; + top: 0; +} + +.ui-pnotify.stack-bar-top .notification { + border-radius: 0; +} + +.ui-pnotify.stack-bar-top .notification .ui-pnotify-icon > span { + margin-top: 7px; +} + +.ui-pnotify.stack-bar-bottom { + bottom: 0; + left: auto; + margin-left: 15%; + right: auto; + top: auto; +} + +.ui-pnotify.stack-bar-bottom .notification { + border-radius: 0; +} + +.ui-pnotify.stack-bar-bottom .notification .ui-pnotify-icon > span { + margin-top: 9px; +} + +.ui-pnotify.click-2-close { + cursor: pointer; +} + +/* Notification States */ +.ui-pnotify .notification-primary { + background: rgba(204, 204, 204, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify .notification-primary .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.stack-bar-top .notification-primary, .ui-pnotify.stack-bar-bottom .notification-primary { + background: #cccccc; +} + +.ui-pnotify.notification-primary .notification, +.ui-pnotify.notification-primary .notification-primary { + background: rgba(204, 204, 204, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-primary .notification .ui-pnotify-icon > span, +.ui-pnotify.notification-primary .notification-primary .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-primary.stack-bar-top .notification, +.ui-pnotify.notification-primary.stack-bar-top .notification-primary, .ui-pnotify.notification-primary.stack-bar-bottom .notification, +.ui-pnotify.notification-primary.stack-bar-bottom .notification-primary { + background: #cccccc; +} + +.ui-pnotify .notification-success { + background: rgba(71, 164, 71, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify .notification-success .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.stack-bar-top .notification-success, .ui-pnotify.stack-bar-bottom .notification-success { + background: #47a447; +} + +.ui-pnotify.notification-success .notification, +.ui-pnotify.notification-success .notification-success { + background: rgba(71, 164, 71, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-success .notification .ui-pnotify-icon > span, +.ui-pnotify.notification-success .notification-success .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-success.stack-bar-top .notification, +.ui-pnotify.notification-success.stack-bar-top .notification-success, .ui-pnotify.notification-success.stack-bar-bottom .notification, +.ui-pnotify.notification-success.stack-bar-bottom .notification-success { + background: #47a447; +} + +.ui-pnotify .notification-warning { + background: rgba(237, 156, 40, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify .notification-warning .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.stack-bar-top .notification-warning, .ui-pnotify.stack-bar-bottom .notification-warning { + background: #ed9c28; +} + +.ui-pnotify.notification-warning .notification, +.ui-pnotify.notification-warning .notification-warning { + background: rgba(237, 156, 40, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-warning .notification .ui-pnotify-icon > span, +.ui-pnotify.notification-warning .notification-warning .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-warning.stack-bar-top .notification, +.ui-pnotify.notification-warning.stack-bar-top .notification-warning, .ui-pnotify.notification-warning.stack-bar-bottom .notification, +.ui-pnotify.notification-warning.stack-bar-bottom .notification-warning { + background: #ed9c28; +} + +.ui-pnotify .notification-danger { + background: rgba(210, 50, 45, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify .notification-danger .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.stack-bar-top .notification-danger, .ui-pnotify.stack-bar-bottom .notification-danger { + background: #d2322d; +} + +.ui-pnotify.notification-danger .notification, +.ui-pnotify.notification-danger .notification-danger { + background: rgba(210, 50, 45, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-danger .notification .ui-pnotify-icon > span, +.ui-pnotify.notification-danger .notification-danger .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-danger.stack-bar-top .notification, +.ui-pnotify.notification-danger.stack-bar-top .notification-danger, .ui-pnotify.notification-danger.stack-bar-bottom .notification, +.ui-pnotify.notification-danger.stack-bar-bottom .notification-danger { + background: #d2322d; +} + +.ui-pnotify .notification-info { + background: rgba(91, 192, 222, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify .notification-info .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.stack-bar-top .notification-info, .ui-pnotify.stack-bar-bottom .notification-info { + background: #5bc0de; +} + +.ui-pnotify.notification-info .notification, +.ui-pnotify.notification-info .notification-info { + background: rgba(91, 192, 222, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-info .notification .ui-pnotify-icon > span, +.ui-pnotify.notification-info .notification-info .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-info.stack-bar-top .notification, +.ui-pnotify.notification-info.stack-bar-top .notification-info, .ui-pnotify.notification-info.stack-bar-bottom .notification, +.ui-pnotify.notification-info.stack-bar-bottom .notification-info { + background: #5bc0de; +} + +.ui-pnotify .notification-dark { + background: rgba(23, 23, 23, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify .notification-dark .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.stack-bar-top .notification-dark, .ui-pnotify.stack-bar-bottom .notification-dark { + background: #171717; +} + +.ui-pnotify.notification-dark .notification, +.ui-pnotify.notification-dark .notification-dark { + background: rgba(23, 23, 23, 0.95); + color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-dark .notification .ui-pnotify-icon > span, +.ui-pnotify.notification-dark .notification-dark .ui-pnotify-icon > span { + border-color: rgba(255, 255, 255, 0.7); +} + +.ui-pnotify.notification-dark.stack-bar-top .notification, +.ui-pnotify.notification-dark.stack-bar-top .notification-dark, .ui-pnotify.notification-dark.stack-bar-bottom .notification, +.ui-pnotify.notification-dark.stack-bar-bottom .notification-dark { + background: #171717; +} + +/* Notification Responsive */ +@media only screen and (max-width: 767px) { + html > body > .ui-pnotify { + bottom: auto !important; + left: 0 !important; + margin: 0 !important; + right: 0 !important; + top: 60px !important; + width: auto !important; + } + + html > body > .ui-pnotify .notification { + border-radius: 0 !important; + height: auto !important; + position: static !important; + width: 100%; + } + + html > body > .ui-pnotify .notification .ui-pnotify-title, + html > body > .ui-pnotify .notification .ui-pnotify-text { + padding-right: 35px !important; + } + + html > body > .ui-pnotify .notification .ui-pnotify-sticker { + display: none !important; + } + + html > body > .ui-pnotify .notification .ui-pnotify-closer { + display: block !important; + font-size: 24px !important; + visibility: visible !important; + } +} +/* Progress bar overwrite style */ +.progress-bar { + background: #cccccc; +} + +.progress .progress-bar { + box-shadow: none; + border-radius: 4px; +} + +/* Progress bar default style */ +.progress { + background: #474453; + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.4) inset; +} + +/* Progress bar light style */ +.progress.light { + background: #f6f7f8; + background: -webkit-linear-gradient(#f6f7f8, #f6f7f8 10%, whitesmoke 11%); + background: linear-gradient(#f6f7f8, #f6f7f8 10%, whitesmoke 11%); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1) inset; +} + +/* Progress bar roundness generic */ +.progress-squared, .progress-squared .progress-bar { + border-radius: 0 !important; +} + +/* Progress bar sizes */ +.progress-xs { + height: 7px; +} + +.progress-xs, .progress-xs .progress-bar { + border-radius: 7px; +} + +.progress-xs .progress-bar { + direction: ltr !important; + text-indent: -9999px; +} + +.progress-xs.progress-half-rounded, .progress-xs.progress-half-rounded .progress-bar { + border-radius: 2px; +} + +.progress-xs.progress-striped .progress-bar { + background-size: 15px 15px; +} + +.progress-sm { + border-radius: 12px; + height: 12px; +} + +.progress-sm, .progress-sm .progress-bar { + border-radius: 12px; +} + +.progress-sm .progress-bar { + font-size: 10px; + line-height: 12px; +} + +.progress-sm.progress-half-rounded, .progress-sm.progress-half-rounded .progress-bar { + border-radius: 4px; +} + +.progress-sm.progress-striped .progress-bar { + background-size: 20px 20px; +} + +.progress-md { + border-radius: 14px; + height: 14px; +} + +.progress-md, .progress-md .progress-bar { + border-radius: 14px; +} + +.progress-md .progress-bar { + font-size: 11px; + line-height: 14px; +} + +.progress-md.progress-half-rounded, .progress-md.progress-half-rounded .progress-bar { + border-radius: 4px; +} + +.progress-md.progress-striped .progress-bar { + background-size: 25px 25px; +} + +.progress-lg { + border-radius: 16px; + height: 16px; +} + +.progress-lg, .progress-lg .progress-bar { + border-radius: 16px; +} + +.progress-lg .progress-bar { + line-height: 16px; +} + +.progress-lg.progress-half-rounded, .progress-lg.progress-half-rounded .progress-bar { + border-radius: 5px; +} + +.progress-lg.progress-striped .progress-bar { + background-size: 30px 30px; +} + +.progress-xl { + border-radius: 18px; + height: 18px; +} + +.progress-xl, .progress-xl .progress-bar { + border-radius: 18px; +} + +.progress-xl .progress-bar { + line-height: 18px; +} + +.progress-xl.progress-half-rounded, .progress-xl.progress-half-rounded .progress-bar { + border-radius: 6px; +} + +.progress-xl.progress-striped .progress-bar { + background-size: 35px 35px; +} + +/* Progress bar states */ +.progress .progress-bar-primary { + background-color: #cccccc; +} + +.progress .progress-bar-success { + background-color: #47a447; +} + +.progress .progress-bar-warning { + background-color: #ed9c28; +} + +.progress .progress-bar-danger { + background-color: #d2322d; +} + +.progress .progress-bar-info { + background-color: #5bc0de; +} + +.progress .progress-bar-dark { + background-color: #171717; +} + +.circular-bar { + margin-bottom: 25px; +} + +.circular-bar .circular-bar-chart { + position: relative; +} + +.circular-bar strong { + display: block; + font-weight: 600; + font-size: 18px; + line-height: 30px; + position: absolute; + top: 35%; + width: 80%; + left: 10%; + text-align: center; +} + +.circular-bar label { + display: block; + font-weight: 100; + font-size: 17px; + line-height: 20px; + position: absolute; + top: 50%; + width: 80%; + left: 10%; + text-align: center; +} + +.panel-group .panel-accordion { + border: 1px solid #DDD; +} + +.panel-group .panel-accordion .panel-heading { + border-radius: 5px; + padding: 0; +} + +.panel-group .panel-accordion .panel-heading a { + color: #cccccc; + display: block; + padding: 15px; + font-size: 16px; + border-radius: 5px; +} + +.panel-group .panel-accordion .panel-heading a:hover, .panel-group .panel-accordion .panel-heading a:focus { + text-decoration: none; +} + +.panel-group .panel-accordion .panel-heading a .fa { + margin-right: 4px; +} + +.panel-group .panel-accordion .panel-body { + border-radius: 0 0 5px 5px; +} + +.panel-group .panel-accordion.panel-accordion-first { + border-radius: 0 0 5px 5px; +} + +.panel-group .panel-accordion.panel-accordion-first .panel-heading { + border-radius: 0 0 5px 5px; +} + +.panel-group .panel-accordion-primary .panel-heading .panel-title a { + background: #cccccc; + color: #FFF; +} + +.panel-group .panel-accordion-success .panel-heading .panel-title a { + background: #47a447; + color: #FFF; +} + +.panel-group .panel-accordion-warning .panel-heading .panel-title a { + background: #ed9c28; + color: #FFF; +} + +.panel-group .panel-accordion-danger .panel-heading .panel-title a { + background: #d2322d; + color: #FFF; +} + +.panel-group .panel-accordion-info .panel-heading .panel-title a { + background: #5bc0de; + color: #FFF; +} + +.panel-group .panel-accordion-dark .panel-heading .panel-title a { + background: #171717; + color: #FFF; +} + +html.dark .panel-group .panel-accordion { + border-color: #282d36; +} + +html.dark .panel-group .panel-accordion .panel { + background-color: #282d36; +} + +html.dark .panel-group .panel-accordion .panel-default { + border-color: #282d36; +} + +html.dark .panel-group .panel-accordion .panel-heading { + background-color: #2e353e; +} + +html.dark .panel-group .panel-accordion .form-control { + background-color: #21262d; + border-color: #21262d; +} + +.chart { + width: 100%; +} + +.chart.chart-xs { + height: 150px; +} + +.chart.chart-sm { + height: 184px; +} + +.chart.chart-md { + height: 350px; +} + +.chart.chart-lg { + height: 500px; +} + +#flotTip { + padding: 4px 8px; + background-color: #000; + z-index: 100; + color: #FFF; + opacity: .7; + font-size: 11px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.jqstooltip { + min-width: 30px; + min-height: 25px; + border: 0 !important; + height: auto !important; + width: auto !important; +} + +.circular-bar { + margin: 25px 0; +} + +.circular-bar .circular-bar-chart { + position: relative; +} + +.circular-bar strong { + display: block; + font-weight: 600; + font-size: 18px; + line-height: 30px; + position: absolute; + top: 35%; + width: 80%; + left: 10%; + text-align: center; +} + +.circular-bar label { + display: block; + font-weight: 100; + font-size: 17px; + line-height: 20px; + position: absolute; + top: 50%; + width: 80%; + left: 10%; + text-align: center; +} + +.circular-bar.circular-bar-xs { + width: 50px; +} + +.circular-bar.circular-bar-xs strong { + display: none; +} + +.circular-bar.circular-bar-xs label { + font-size: 11px; + left: 0; + text-align: center; + top: 28%; + width: 100%; +} + +.gauge-chart { + margin: 25px 0; +} + +.gauge-chart strong { + display: block; + font-weight: 600; + font-size: 18px; + line-height: 30px; + text-align: center; + margin-top: 10px; +} + +.gauge-chart label { + display: block; + font-weight: 100; + font-size: 17px; + line-height: 20px; + padding-bottom: 5px; + text-align: center; +} + +.small-chart-wrapper { + display: inline-block; + margin: 10px 15px; + width: 100%; +} + +.small-chart-wrapper .small-chart { + display: inline-block; + float: left; + margin-bottom: 8px; + min-width: 80px; +} + +.small-chart-wrapper .small-chart-info { + display: inline-block; + padding: 0 0 0 10px; +} + +.small-chart-wrapper .small-chart-info label { + display: block; + font-size: 11px; + text-transform: uppercase; + color: #a0a0a0; + padding: 0; + margin: 0; + line-height: 15px; +} + +.small-chart-wrapper .small-chart-info strong { + display: block; + font-size: 13px; + padding: 0; + margin: 0; + line-height: 15px; +} + +.small-chart-wrapper + .small-chart-wrapper { + margin-left: 25px; +} + +@media only screen and (max-width: 767px) { + .small-chart-wrapper { + margin-right: 0; + margin-left: 0; + text-align: center; + } + + .small-chart-wrapper .small-chart { + width: 100%; + text-align: center; + } + + .small-chart-wrapper .small-chart-info { + padding-left: 0; + } +} + +.liquid-meter { + position: relative; + max-height: 200px; + max-width: 200px; + margin: 0 auto; + width: 100%; + padding-bottom: 50%; +} + +.liquid-meter meter { + display: none; +} + +.liquid-meter.liquid-meter-loaded { + width: auto; + padding-bottom: 0; +} + +.liquid-meter.liquid-meter-loaded:before { + display: none; +} + +.liquid-meter-wrapper.liquid-meter-xs .liquid-meter { + max-height: 120px; + max-width: 120px; +} + +.liquid-meter-wrapper.liquid-meter-sm .liquid-meter { + max-height: 150px; + max-width: 150px; +} + +.liquid-meter-wrapper.liquid-meter-md .liquid-meter { + max-height: 200px; + max-width: 200px; +} + +.liquid-meter-wrapper.liquid-meter-lg .liquid-meter { + max-height: 230px; + max-width: 230px; +} + +.liquid-meter-wrapper .liquid-meter-selector { + margin-top: 3px; +} + +.liquid-meter-wrapper .liquid-meter-selector a { + text-transform: uppercase; + font-weight: 300; + font-size: 11px; + color: #9b9b9b; + border-right: 1px solid #e4e4e4; + display: inline-block; + padding-right: 8px; + margin-right: 8px; +} + +.liquid-meter-wrapper .liquid-meter-selector a.active { + color: #cccccc; +} + +.liquid-meter-wrapper .liquid-meter-selector a:last-child { + border-right: 0; + padding-right: 0; + margin-right: 0; +} + +.chart-data-selector { + visibility: hidden; + max-height: 255px; + padding: 6px; +} + +.chart-data-selector h2 { + color: #33353f; + font-size: 20px; + line-height: 20px; + margin: 0; + padding: 0; + text-transform: none; + letter-spacing: -1px; +} + +.chart-data-selector h2 .multiselect { + background: #f6f6f6; + border: 0 none; + font-size: 20px; + font-weight: 600; + margin: -4px 0 0 4px !important; + padding: 3px 12px 3px 8px; +} + +.chart-data-selector h2 .multiselect:hover, .chart-data-selector h2 .multiselect:focus, .chart-data-selector h2 .multiselect:active { + text-decoration: none; +} + +.chart-data-selector h2 .multiselect-container { + margin: 0 0 0 4px; + min-width: 120%; +} + +.chart-data-selector .chart-data-selector-items { + position: relative; + overflow: hidden; +} + +.chart-data-selector .chart-data-selector-items .chart-active { + visibility: hidden; +} + +.chart-data-selector .chart-data-selector-items .chart-hidden { + visibility: hidden; +} + +.chart-data-selector.ready { + max-height: none; + visibility: visible; +} + +.chart-data-selector.ready .chart-active { + visibility: visible; + position: relative; + z-index: 2; +} + +.chart-data-selector.ready .chart-hidden { + visibility: hidden; + position: absolute; + z-index: 1; + top: -9999px; +} + +.ct-chart .ct-label, +.ct-chart .ct-label.ct-horizontal, +.ct-chart .ct-label.ct-vertical { + font-size: 12px; + font-size: 1.2rem; +} + +.ct-chart .ct-series.ct-series-a .ct-bar, +.ct-chart .ct-series.ct-series-a .ct-line, +.ct-chart .ct-series.ct-series-a .ct-point, +.ct-chart .ct-series.ct-series-a .ct-slice.ct-donut { + stroke: #cccccc; +} + +.ct-chart .ct-series.ct-series-a .ct-area, +.ct-chart .ct-series.ct-series-a .ct-slice:not(.ct-donut) { + fill: #cccccc; +} + +.ct-chart .ct-series.ct-series-b .ct-bar, +.ct-chart .ct-series.ct-series-b .ct-line, +.ct-chart .ct-series.ct-series-b .ct-point, +.ct-chart .ct-series.ct-series-b .ct-slice.ct-donut { + stroke: #a6a6a6; +} + +.ct-chart .ct-series.ct-series-b .ct-area, +.ct-chart .ct-series.ct-series-b .ct-slice:not(.ct-donut) { + fill: #a6a6a6; +} + +.ct-chart .ct-series.ct-series-c .ct-bar, +.ct-chart .ct-series.ct-series-c .ct-line, +.ct-chart .ct-series.ct-series-c .ct-point, +.ct-chart .ct-series.ct-series-c .ct-slice.ct-donut { + stroke: #e36159; +} + +.ct-chart .ct-series.ct-series-c .ct-area, +.ct-chart .ct-series.ct-series-c .ct-slice:not(.ct-donut) { + fill: #e36159; +} + +.ct-chart .ct-series.ct-series-d .ct-bar, +.ct-chart .ct-series.ct-series-d .ct-line, +.ct-chart .ct-series.ct-series-d .ct-point, +.ct-chart .ct-series.ct-series-d .ct-slice.ct-donut { + stroke: #cd2c23; +} + +.ct-chart .ct-series.ct-series-d .ct-area, +.ct-chart .ct-series.ct-series-d .ct-slice:not(.ct-donut) { + fill: #cd2c23; +} + +.ct-chart .ct-series.ct-series-e .ct-bar, +.ct-chart .ct-series.ct-series-e .ct-line, +.ct-chart .ct-series.ct-series-e .ct-point, +.ct-chart .ct-series.ct-series-e .ct-slice.ct-donut { + stroke: #2baab1; +} + +.ct-chart .ct-series.ct-series-e .ct-area, +.ct-chart .ct-series.ct-series-e .ct-slice:not(.ct-donut) { + fill: #2baab1; +} + +.ct-chart .ct-series.ct-series-f .ct-bar, +.ct-chart .ct-series.ct-series-f .ct-line, +.ct-chart .ct-series.ct-series-f .ct-point, +.ct-chart .ct-series.ct-series-f .ct-slice.ct-donut { + stroke: #1c6f73; +} + +.ct-chart .ct-series.ct-series-f .ct-area, +.ct-chart .ct-series.ct-series-f .ct-slice:not(.ct-donut) { + fill: #1c6f73; +} + +.ct-chart .ct-series.ct-series-g .ct-bar, +.ct-chart .ct-series.ct-series-g .ct-line, +.ct-chart .ct-series.ct-series-g .ct-point, +.ct-chart .ct-series.ct-series-g .ct-slice.ct-donut { + stroke: #734ba9; +} + +.ct-chart .ct-series.ct-series-g .ct-area, +.ct-chart .ct-series.ct-series-g .ct-slice:not(.ct-donut) { + fill: #734ba9; +} + +.ct-chart .ct-series.ct-series-h .ct-bar, +.ct-chart .ct-series.ct-series-h .ct-line, +.ct-chart .ct-series.ct-series-h .ct-point, +.ct-chart .ct-series.ct-series-h .ct-slice.ct-donut { + stroke: #4f3374; +} + +.ct-chart .ct-series.ct-series-h .ct-area, +.ct-chart .ct-series.ct-series-h .ct-slice:not(.ct-donut) { + fill: #4f3374; +} + +.ct-chart .ct-series.ct-series-i .ct-bar, +.ct-chart .ct-series.ct-series-i .ct-line, +.ct-chart .ct-series.ct-series-i .ct-point, +.ct-chart .ct-series.ct-series-i .ct-slice.ct-donut { + stroke: #a6a6a6; +} + +.ct-chart .ct-series.ct-series-i .ct-area, +.ct-chart .ct-series.ct-series-i .ct-slice:not(.ct-donut) { + fill: #a6a6a6; +} + +.ct-chart .ct-series.ct-series-j .ct-bar, +.ct-chart .ct-series.ct-series-j .ct-line, +.ct-chart .ct-series.ct-series-j .ct-point, +.ct-chart .ct-series.ct-series-j .ct-slice.ct-donut { + stroke: #f2f2f2; +} + +.ct-chart .ct-series.ct-series-j .ct-area, +.ct-chart .ct-series.ct-series-j .ct-slice:not(.ct-donut) { + fill: #f2f2f2; +} + +.ct-chart .ct-series.ct-series-k .ct-bar, +.ct-chart .ct-series.ct-series-k .ct-line, +.ct-chart .ct-series.ct-series-k .ct-point, +.ct-chart .ct-series.ct-series-k .ct-slice.ct-donut { + stroke: #ee9f9a; +} + +.ct-chart .ct-series.ct-series-k .ct-area, +.ct-chart .ct-series.ct-series-k .ct-slice:not(.ct-donut) { + fill: #ee9f9a; +} + +.ct-chart .ct-series.ct-series-l .ct-bar, +.ct-chart .ct-series.ct-series-l .ct-line, +.ct-chart .ct-series.ct-series-l .ct-point, +.ct-chart .ct-series.ct-series-l .ct-slice.ct-donut { + stroke: #53ced5; +} + +.ct-chart .ct-series.ct-series-l .ct-area, +.ct-chart .ct-series.ct-series-l .ct-slice:not(.ct-donut) { + fill: #53ced5; +} + +.ct-chart .ct-series.ct-series-m .ct-bar, +.ct-chart .ct-series.ct-series-m .ct-line, +.ct-chart .ct-series.ct-series-m .ct-point, +.ct-chart .ct-series.ct-series-m .ct-slice.ct-donut { + stroke: #9b7cc5; +} + +.ct-chart .ct-series.ct-series-m .ct-area, +.ct-chart .ct-series.ct-series-m .ct-slice:not(.ct-donut) { + fill: #9b7cc5; +} + +.ct-chart .ct-series.ct-series-n .ct-bar, +.ct-chart .ct-series.ct-series-n .ct-line, +.ct-chart .ct-series.ct-series-n .ct-point, +.ct-chart .ct-series.ct-series-n .ct-slice.ct-donut { + stroke: #737373; +} + +.ct-chart .ct-series.ct-series-n .ct-area, +.ct-chart .ct-series.ct-series-n .ct-slice:not(.ct-donut) { + fill: #737373; +} + +.ct-chart .ct-series.ct-series-o .ct-bar, +.ct-chart .ct-series.ct-series-o .ct-line, +.ct-chart .ct-series.ct-series-o .ct-point, +.ct-chart .ct-series.ct-series-o .ct-slice.ct-donut { + stroke: white; +} + +.ct-chart .ct-series.ct-series-o .ct-area, +.ct-chart .ct-series.ct-series-o .ct-slice:not(.ct-donut) { + fill: white; +} + +.ct-chart .tooltip { + opacity: 1; + position: absolute; + display: inline-block; + min-width: 115px; + padding: 8px; + background: #cccccc; + color: white; + font-weight: 500; + text-align: center; + pointer-events: none; + z-index: 1; +} + +.ct-chart .tooltip:after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + width: 0; + height: 0; + margin-left: -15px; + border: 15px solid transparent; + border-top-color: #cccccc; +} + +html.dark .chart-data-selector h2 .multiselect { + background-color: #282d36; +} + +.jstree-default .jstree-checkbox { + background-image: url(../images/jstree.png); +} + +.jstree-default .jstree-icon { + color: #333; +} + +.jstree-default .jstree-hovered { + background-color: white; +} + +.jstree-default .jstree-clicked { + background-color: white; +} + +.jstree-default .jstree-disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.jstree-default .colored { + color: #cccccc; +} + +.jstree-default .colored .jstree-icon { + color: #cccccc; +} + +.jstree-default .colored-icon .jstree-icon { + color: #cccccc; +} + +.jstree-default .folder .jstree-icon { + color: #ddc03f !important; +} + +/* dark */ +html.dark body .jstree-default .jstree-checkbox { + background-image: url(../images/jstree-dark.png); +} + +html.dark body .jstree-default .jstree-hovered { + background-color: #21262d !important; + box-shadow: none; +} + +html.dark body .jstree-default .jstree-clicked { + background-color: #1d2127 !important; + box-shadow: none; +} + +html.dark body .jstree-default .jstree-icon { + color: #808697; +} + +/* Word Rotate */ +.word-rotate { + visibility: hidden; + width: 100px; + height: 0px; + margin-bottom: -7px; + display: inline-block; + overflow: hidden; + text-align: center; + position: relative; + top: -1px; +} + +.word-rotate.active { + visibility: visible; + width: auto; +} + +.word-rotate .word-rotate-items { + position: relative; + top: 0; + width: 100%; +} + +.word-rotate .word-rotate-items span { + display: block; + white-space: nowrap; +} + +.word-rotate.highlight { + top: 1px; +} + +/* Word Rotate - Titles */ +h1 .word-rotate { + margin-bottom: -12px; +} + +h2 .word-rotate { + margin-bottom: -12px; +} + +h2.word-rotator-title { + line-height: 54px; +} + +.dd { + position: relative; + display: block; + margin: 0; + padding: 0; + list-style: none; + font-size: 13px; + line-height: 20px; +} + +.dd-list { + display: block; + position: relative; + margin: 0; + padding: 0; + list-style: none; +} + +.dd-list .dd-list { + padding-left: 30px; +} + +.dd-collapsed .dd-list { + display: none; +} + +.dd-item, .dd-empty, .dd-placeholder { + display: block; + position: relative; + margin: 0; + padding: 0; + min-height: 20px; + font-size: 13px; + line-height: 20px; +} + +.dd-handle { + display: block; + height: 34px; + margin: 5px 0; + padding: 6px 10px; + color: #333; + text-decoration: none; + font-weight: 600; + border: 1px solid #CCC; + background: #F6F6F6; + -webkit-border-radius: 3px; + border-radius: 3px; + box-sizing: border-box; + -moz-box-sizing: border-box; +} + +.dd-handle:hover { + color: #cccccc; + background: #fff; +} + +.dd-item > button { + display: block; + position: relative; + cursor: pointer; + float: left; + width: 25px; + height: 20px; + margin: 7px 0; + padding: 0; + text-indent: 100%; + white-space: nowrap; + overflow: hidden; + border: 0; + background: transparent; + font-size: 12px; + line-height: 1; + text-align: center; + font-weight: bold; +} + +.dd-item > button:before { + content: '+'; + display: block; + position: absolute; + width: 100%; + text-align: center; + text-indent: 0; +} + +.dd-item > button[data-action="collapse"]:before { + content: '-'; +} + +.dd-placeholder { + margin: 5px 0; + padding: 0; + min-height: 30px; + background: white; + border: 1px dashed #cccccc; + box-sizing: border-box; + -moz-box-sizing: border-box; +} + +.dd-empty { + margin: 5px 0; + padding: 0; + min-height: 30px; + background: #f2fbff; + border: 1px dashed #b6bcbf; + box-sizing: border-box; + -moz-box-sizing: border-box; + border: 1px dashed #bbb; + min-height: 100px; + background-color: #e5e5e5; + background-image: -webkit-linear-gradient(45deg, white 25%, transparent 25%, transparent 75%, white 75%, white), -webkit-linear-gradient(45deg, white 25%, transparent 25%, transparent 75%, white 75%, white); + background-image: -moz-linear-gradient(45deg, white 25%, transparent 25%, transparent 75%, white 75%, white), -moz-linear-gradient(45deg, white 25%, transparent 25%, transparent 75%, white 75%, white); + background-image: linear-gradient(45deg, white 25%, transparent 25%, transparent 75%, white 75%, white), linear-gradient(45deg, white 25%, transparent 25%, transparent 75%, white 75%, white); + background-size: 60px 60px; + background-position: 0 0, 30px 30px; +} + +.dd-dragel { + position: absolute; + pointer-events: none; + z-index: 9999; +} + +.dd-dragel > .dd-item .dd-handle { + margin-top: 0; +} + +.dd-dragel .dd-handle { + -webkit-box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1); + box-shadow: 2px 4px 6px 0 rgba(0, 0, 0, 0.1); +} + +/* dark */ +html.dark .dd-handle { + background: #282d36; + border-color: #21262d; + color: #808697; +} + +html.dark .dd-handle:hover { + background: #21262d; +} + +.owl-carousel .item.spaced { + margin: 5px; +} + +.toggle { + margin: 10px 0 0; + position: relative; + clear: both; +} + +.toggle > input { + cursor: pointer; + filter: alpha(opacity=0); + height: 45px; + margin: 0; + opacity: 0; + position: absolute; + width: 100%; + z-index: 2; +} + +.toggle > label { + -webkit-transition: all 0.15s ease-out; + -moz-transition: all 0.15s ease-out; + transition: all 0.15s ease-out; + background: #F4F4F4; + border-left: 3px solid #cccccc; + border-radius: 5px; + color: #cccccc; + display: block; + font-size: 1.1em; + min-height: 20px; + padding: 12px 20px 12px 10px; + position: relative; + cursor: pointer; + font-weight: 400; +} + +.toggle > label:-moz-selection { + background: none; +} + +.toggle > label i.fa-minus { + display: none; +} + +.toggle > label i.fa-plus { + display: inline; +} + +.toggle > label:selection { + background: none; +} + +.toggle > label:before { + border: 6px solid transparent; + border-left-color: inherit; + content: ''; + margin-top: -6px; + position: absolute; + right: 4px; + top: 50%; +} + +.toggle > label:hover { + background: #f5f5f5; +} + +.toggle > label + p { + display: block; + overflow: hidden; + padding-left: 30px; + text-overflow: ellipsis; + white-space: nowrap; + height: 25px; +} + +.toggle > label i { + font-size: 0.7em; + margin-right: 8px; + position: relative; + top: -1px; +} + +.toggle > .toggle-content { + display: none; +} + +.toggle > .toggle-content > p { + margin-bottom: 0; + padding: 10px 0; +} + +.toggle.active i.fa-minus { + display: inline; + color: #FFF; +} + +.toggle.active i.fa-plus { + display: none; +} + +.toggle.active > label { + background: #cccccc; + border-color: #cccccc; + color: #FFF; +} + +.toggle.active > label:before { + border: 6px solid transparent; + border-top-color: #FFF; + margin-top: -3px; + right: 10px; +} + +.toggle.active > p { + white-space: normal; +} + +.toggle > p.preview-active { + height: auto; + white-space: normal; +} + +/* dark */ +html.dark .toggle > label { + background: #282d36; +} + +.label-default { + background: #ebebeb; + color: #777777; +} + +.label-sm { + font-size: 50%; +} + +.label-primary { + background: #cccccc; + color: white; +} + +.label-success { + background: #47a447; + color: white; +} + +.label-warning { + background: #ed9c28; + color: white; +} + +.label-danger { + background: #d2322d; + color: white; +} + +.label-info { + background: #5bc0de; + color: white; +} + +.label-dark { + background: #171717; + color: white; +} + +.mfp-bg { + z-index: 10000; +} + +.mfp-wrap { + z-index: 10001; +} + +.mfp-wrap .mfp-content { + z-index: 10001; +} + +.modal-block { + background: transparent; + padding: 0; + text-align: left; + max-width: 600px; + margin: 40px auto; + position: relative; +} + +.modal-block.modal-block-xs { + max-width: 200px; +} + +.modal-block.modal-block-sm { + max-width: 400px; +} + +.modal-block.modal-block-md { + max-width: 600px; +} + +.modal-block.modal-block-lg { + max-width: 900px; +} + +.modal-block.modal-block-full { + max-width: 98%; +} + +.modal-block.modal-header-color .panel-heading h2 { + color: #FFF; +} + +.modal-block.modal-full-color { + color: #FFF; +} + +.modal-block.modal-full-color .panel-heading { + border: 0; +} + +.modal-block.modal-full-color .panel-heading h2 { + color: #FFF; +} + +.modal-block.modal-full-color .panel-footer { + border: 0; +} + +.modal-block.modal-full-color .panel-body { + background-color: transparent; +} + +.modal-block.modal-full-color .fa { + color: #FFF !important; +} + +/* Modal Wrapper */ +.modal-wrapper { + position: relative; + padding: 25px 0; +} + +/* Modal Icon */ +.modal-icon { + float: left; + width: 20%; + text-align: center; +} + +.modal-icon .fa { + font-size: 52px; + position: relative; + top: -10px; + color: #cccccc; +} + +.modal-icon.center { + float: none; + width: auto; + padding-top: 20px; +} + +.modal-icon.center + .modal-text { + float: none; + width: auto; +} + +.modal-icon + .modal-text { + float: left; + width: 80%; +} + +/* Modal Text */ +.modal-text { + padding: 0 5px; +} + +.modal-text h1, .modal-text h2, .modal-text h3, .modal-text h4, .modal-text h5, .modal-text h6 { + padding: 0; + margin: -7px 0 4px 0; +} + +.modal-block-primary .fa { + color: #cccccc; +} + +.modal-block-primary.modal-header-color .panel-heading { + background-color: #cccccc; +} + +.modal-block-primary.modal-full-color .panel { + background-color: #e0e0e0; +} + +.modal-block-primary.modal-full-color .panel-heading { + background-color: #cccccc; +} + +.modal-block-primary.modal-full-color .panel-footer { + background-color: #e0e0e0; +} + +.modal-block-success .fa { + color: #47a447; +} + +.modal-block-success.modal-header-color .panel-heading { + background-color: #47a447; +} + +.modal-block-success.modal-full-color .panel { + background-color: #5cb85c; +} + +.modal-block-success.modal-full-color .panel-heading { + background-color: #47a447; +} + +.modal-block-success.modal-full-color .panel-footer { + background-color: #5cb85c; +} + +.modal-block-warning .fa { + color: #ed9c28; +} + +.modal-block-warning.modal-header-color .panel-heading { + background-color: #ed9c28; +} + +.modal-block-warning.modal-full-color .panel { + background-color: #f0ad4e; +} + +.modal-block-warning.modal-full-color .panel-heading { + background-color: #ed9c28; +} + +.modal-block-warning.modal-full-color .panel-footer { + background-color: #f0ad4e; +} + +.modal-block-danger .fa { + color: #d2322d; +} + +.modal-block-danger.modal-header-color .panel-heading { + background-color: #d2322d; +} + +.modal-block-danger.modal-full-color .panel { + background-color: #d9534f; +} + +.modal-block-danger.modal-full-color .panel-heading { + background-color: #d2322d; +} + +.modal-block-danger.modal-full-color .panel-footer { + background-color: #d9534f; +} + +.modal-block-info .fa { + color: #5bc0de; +} + +.modal-block-info.modal-header-color .panel-heading { + background-color: #5bc0de; +} + +.modal-block-info.modal-full-color .panel { + background-color: #7dcde5; +} + +.modal-block-info.modal-full-color .panel-heading { + background-color: #5bc0de; +} + +.modal-block-info.modal-full-color .panel-footer { + background-color: #7dcde5; +} + +.modal-block-dark .fa { + color: #171717; +} + +.modal-block-dark.modal-header-color .panel-heading { + background-color: #171717; +} + +.modal-block-dark.modal-full-color .panel { + background-color: #2b2b2b; +} + +.modal-block-dark.modal-full-color .panel-heading { + background-color: #171717; +} + +.modal-block-dark.modal-full-color .panel-footer { + background-color: #2b2b2b; +} + +html.dark .modal-content { + background-color: #1d2127; +} + +html.dark .modal-header, +html.dark .modal-footer { + border-color: #282d36; +} + +/* Close */ +.mfp-close, +.mfp-close-btn-in .mfp-close { + font-family: "Open Sans", Arial, sans-serif; + font-weight: 600; + font-size: 22px; + color: #838383; +} + +/* No Margins */ +.mfp-no-margins img.mfp-img { + padding: 0; +} + +.mfp-no-margins .mfp-figure:after { + top: 0; + bottom: 0; +} + +.mfp-no-margins .mfp-container { + padding: 0; +} + +/* Zoom */ +.mfp-with-zoom .mfp-container, .mfp-with-zoom.mfp-bg { + opacity: 0.001; + -webkit-backface-visibility: hidden; + -webkit-transition: all 0.3s ease-out; + -moz-transition: all 0.3s ease-out; + -o-transition: all 0.3s ease-out; + transition: all 0.3s ease-out; +} + +.mfp-with-zoom.mfp-ready .mfp-container { + opacity: 1; +} + +.mfp-with-zoom.mfp-ready.mfp-bg { + opacity: 0.8; +} + +.mfp-with-zoom.mfp-removing .mfp-container, .mfp-with-zoom.mfp-removing.mfp-bg { + opacity: 0; +} + +/* Animnate */ +.my-mfp-zoom-in .zoom-anim-dialog { + opacity: 0; + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + -webkit-transform: scale(0.8); + -moz-transform: scale(0.8); + -ms-transform: scale(0.8); + -o-transform: scale(0.8); + transform: scale(0.8); +} + +.my-mfp-zoom-in.mfp-ready .zoom-anim-dialog { + opacity: 1; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -ms-transform: scale(1); + -o-transform: scale(1); + transform: scale(1); +} + +.my-mfp-zoom-in.mfp-removing .zoom-anim-dialog { + -webkit-transform: scale(0.8); + -moz-transform: scale(0.8); + -ms-transform: scale(0.8); + -o-transform: scale(0.8); + transform: scale(0.8); + opacity: 0; +} + +.my-mfp-zoom-in.mfp-bg { + opacity: 0.001; + /* Chrome opacity transition bug */ + -webkit-transition: opacity 0.3s ease-out; + -moz-transition: opacity 0.3s ease-out; + -o-transition: opacity 0.3s ease-out; + transition: opacity 0.3s ease-out; +} + +.my-mfp-zoom-in.mfp-ready.mfp-bg { + opacity: 0.8; +} + +.my-mfp-zoom-in.mfp-removing.mfp-bg { + opacity: 0; +} + +.my-mfp-slide-bottom .zoom-anim-dialog { + opacity: 0; + -webkit-transition: all 0.2s ease-out; + -moz-transition: all 0.2s ease-out; + -o-transition: all 0.2s ease-out; + transition: all 0.2s ease-out; + -webkit-transform: translateY(-20px) perspective(600px) rotateX(10deg); + -moz-transform: translateY(-20px) perspective(600px) rotateX(10deg); + -ms-transform: translateY(-20px) perspective(600px) rotateX(10deg); + -o-transform: translateY(-20px) perspective(600px) rotateX(10deg); + transform: translateY(-20px) perspective(600px) rotateX(10deg); +} + +.my-mfp-slide-bottom.mfp-ready .zoom-anim-dialog { + opacity: 1; + -webkit-transform: translateY(0) perspective(600px) rotateX(0); + -moz-transform: translateY(0) perspective(600px) rotateX(0); + -ms-transform: translateY(0) perspective(600px) rotateX(0); + -o-transform: translateY(0) perspective(600px) rotateX(0); + transform: translateY(0) perspective(600px) rotateX(0); +} + +.my-mfp-slide-bottom.mfp-removing .zoom-anim-dialog { + opacity: 0; + -webkit-transform: translateY(-10px) perspective(600px) rotateX(10deg); + -moz-transform: translateY(-10px) perspective(600px) rotateX(10deg); + -ms-transform: translateY(-10px) perspective(600px) rotateX(10deg); + -o-transform: translateY(-10px) perspective(600px) rotateX(10deg); + transform: translateY(-10px) perspective(600px) rotateX(10deg); +} + +.my-mfp-slide-bottom.mfp-bg { + opacity: 0.01; + -webkit-transition: opacity 0.3s ease-out; + -moz-transition: opacity 0.3s ease-out; + -o-transition: opacity 0.3s ease-out; + transition: opacity 0.3s ease-out; +} + +.my-mfp-slide-bottom.mfp-ready.mfp-bg { + opacity: 0.8; +} + +.my-mfp-slide-bottom.mfp-removing.mfp-bg { + opacity: 0; +} + +/* Dialog */ +.dialog { + background: white; + padding: 20px 30px; + text-align: left; + margin: 40px auto; + position: relative; + max-width: 600px; +} + +.dialog.dialog-xs { + max-width: 200px; +} + +.dialog.dialog-sm { + max-width: 400px; +} + +.dialog.dialog-md { + max-width: 600px; +} + +.dialog.dialog-lg { + max-width: 900px; +} + +/* White Popup Block */ +.white-popup-block { + background: #FFF; + padding: 20px 30px; + text-align: left; + max-width: 600px; + margin: 40px auto; + position: relative; +} + +.white-popup-block.white-popup-block-xs { + max-width: 200px; +} + +.white-popup-block.white-popup-block-sm { + max-width: 400px; +} + +.white-popup-block.white-popup-block-md { + max-width: 600px; +} + +.white-popup-block.white-popup-block-lg { + max-width: 900px; +} + +/* Dark */ +html.dark .white-popup-block, +html.dark .dialog { + background: #1d2127; +} + +/* +Animate.css - http: //daneden.me/animate +Licensed under the MIT license + +Copyright (c) 2013 Daniel Eden + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +.appear-animation { + opacity: 0; +} + +.appear-animation-visible { + opacity: 1; +} + +.animated, +.appear-animation { + -webkit-animation-fill-mode: both; + -moz-animation-fill-mode: both; + -ms-animation-fill-mode: both; + -o-animation-fill-mode: both; + animation-fill-mode: both; + -webkit-animation-duration: 1s; + -moz-animation-duration: 1s; + -ms-animation-duration: 1s; + -o-animation-duration: 1s; + animation-duration: 1s; +} + +@-moz-keyframes flash { + 0%, 50%, 100% { + opacity: 1; + } + + 25%, 75% { + opacity: 0; + } +} + +@-o-keyframes flash { + 0%, 50%, 100% { + opacity: 1; + } + + 25%, 75% { + opacity: 0; + } +} + +@keyframes flash { + 0%, 50%, 100% { + opacity: 1; + } + + 25%, 75% { + opacity: 0; + } +} + +.flash { + -webkit-animation-name: flash; + -moz-animation-name: flash; + -o-animation-name: flash; + animation-name: flash; +} + +@-webkit-keyframes shake { + 0%, 100% { + -webkit-transform: translateX(0); + opacity: 1; + } + + 10%, 30%, 50%, 70%, 90% { + -webkit-transform: translateX(-10px); + } + + 20%, 40%, 60%, 80% { + -webkit-transform: translateX(10px); + } +} + +@-moz-keyframes shake { + 0%, 100% { + -moz-transform: translateX(0); + opacity: 1; + } + + 10%, 30%, 50%, 70%, 90% { + -moz-transform: translateX(-10px); + } + + 20%, 40%, 60%, 80% { + -moz-transform: translateX(10px); + } +} + +@-o-keyframes shake { + 0%, 100% { + -o-transform: translateX(0); + opacity: 1; + } + + 10%, 30%, 50%, 70%, 90% { + -o-transform: translateX(-10px); + } + + 20%, 40%, 60%, 80% { + -o-transform: translateX(10px); + } +} + +@keyframes shake { + 0%, 100% { + transform: translateX(0); + opacity: 1; + } + + 10%, 30%, 50%, 70%, 90% { + transform: translateX(-10px); + } + + 20%, 40%, 60%, 80% { + transform: translateX(10px); + } +} + +.shake { + -webkit-animation-name: shake; + -moz-animation-name: shake; + -o-animation-name: shake; + animation-name: shake; +} + +@-webkit-keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + -webkit-transform: translateY(0); + opacity: 1; + } + + 40% { + -webkit-transform: translateY(-30px); + } + + 60% { + -webkit-transform: translateY(-15px); + } +} + +@-moz-keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + -moz-transform: translateY(0); + opacity: 1; + } + + 40% { + -moz-transform: translateY(-30px); + } + + 60% { + -moz-transform: translateY(-15px); + } +} + +@-o-keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + -o-transform: translateY(0); + opacity: 1; + } + + 40% { + -o-transform: translateY(-30px); + } + + 60% { + -o-transform: translateY(-15px); + } +} + +@keyframes bounce { + 0%, 20%, 50%, 80%, 100% { + transform: translateY(0); + opacity: 1; + } + + 40% { + transform: translateY(-30px); + } + + 60% { + transform: translateY(-15px); + } +} + +.bounce { + -webkit-animation-name: bounce; + -moz-animation-name: bounce; + -o-animation-name: bounce; + animation-name: bounce; +} + +@-webkit-keyframes tada { + 0% { + -webkit-transform: scale(1); + } + + 10%, 20% { + -webkit-transform: scale(0.9) rotate(-3deg); + } + + 30%, 50%, 70%, 90% { + -webkit-transform: scale(1.1) rotate(3deg); + } + + 40%, 60%, 80% { + -webkit-transform: scale(1.1) rotate(-3deg); + } + + 100% { + -webkit-transform: scale(1) rotate(0); + opacity: 1; + } +} + +@-moz-keyframes tada { + 0% { + -moz-transform: scale(1); + } + + 10%, 20% { + -moz-transform: scale(0.9) rotate(-3deg); + } + + 30%, 50%, 70%, 90% { + -moz-transform: scale(1.1) rotate(3deg); + } + + 40%, 60%, 80% { + -moz-transform: scale(1.1) rotate(-3deg); + } + + 100% { + -moz-transform: scale(1) rotate(0); + opacity: 1; + } +} + +@-o-keyframes tada { + 0% { + -o-transform: scale(1); + } + + 10%, 20% { + -o-transform: scale(0.9) rotate(-3deg); + } + + 30%, 50%, 70%, 90% { + -o-transform: scale(1.1) rotate(3deg); + } + + 40%, 60%, 80% { + -o-transform: scale(1.1) rotate(-3deg); + } + + 100% { + -o-transform: scale(1) rotate(0); + opacity: 1; + } +} + +@keyframes tada { + 0% { + transform: scale(1); + } + + 10%, 20% { + transform: scale(0.9) rotate(-3deg); + } + + 30%, 50%, 70%, 90% { + transform: scale(1.1) rotate(3deg); + } + + 40%, 60%, 80% { + transform: scale(1.1) rotate(-3deg); + } + + 100% { + transform: scale(1) rotate(0); + opacity: 1; + } +} + +.tada { + -webkit-animation-name: tada; + -moz-animation-name: tada; + -o-animation-name: tada; + animation-name: tada; +} + +@-webkit-keyframes swing { + 20%, 40%, 60%, 80%, 100% { + -webkit-transform-origin: top center; + } + + 20% { + -webkit-transform: rotate(15deg); + } + + 40% { + -webkit-transform: rotate(-10deg); + } + + 60% { + -webkit-transform: rotate(5deg); + } + + 80% { + -webkit-transform: rotate(-5deg); + } + + 100% { + -webkit-transform: rotate(0deg); + opacity: 1; + } +} + +@-moz-keyframes swing { + 20% { + -moz-transform: rotate(15deg); + } + + 40% { + -moz-transform: rotate(-10deg); + } + + 60% { + -moz-transform: rotate(5deg); + } + + 80% { + -moz-transform: rotate(-5deg); + } + + 100% { + -moz-transform: rotate(0deg); + opacity: 1; + } +} + +@-o-keyframes swing { + 20% { + -o-transform: rotate(15deg); + } + + 40% { + -o-transform: rotate(-10deg); + } + + 60% { + -o-transform: rotate(5deg); + } + + 80% { + -o-transform: rotate(-5deg); + } + + 100% { + -o-transform: rotate(0deg); + opacity: 1; + } +} + +@keyframes swing { + 20% { + transform: rotate(15deg); + } + + 40% { + transform: rotate(-10deg); + } + + 60% { + transform: rotate(5deg); + } + + 80% { + transform: rotate(-5deg); + } + + 100% { + transform: rotate(0deg); + opacity: 1; + } +} + +.swing { + -webkit-transform-origin: top center; + -moz-transform-origin: top center; + -o-transform-origin: top center; + transform-origin: top center; + -webkit-animation-name: swing; + -moz-animation-name: swing; + -o-animation-name: swing; + animation-name: swing; +} + +/* originally authored by Nick Pettit - https: //github.com/nickpettit/glide */ +@-webkit-keyframes wobble { + 0% { + -webkit-transform: translateX(0%); + } + + 15% { + -webkit-transform: translateX(-25%) rotate(-5deg); + } + + 30% { + -webkit-transform: translateX(20%) rotate(3deg); + } + + 45% { + -webkit-transform: translateX(-15%) rotate(-3deg); + } + + 60% { + -webkit-transform: translateX(10%) rotate(2deg); + } + + 75% { + -webkit-transform: translateX(-5%) rotate(-1deg); + } + + 100% { + -webkit-transform: translateX(0%); + opacity: 1; + } +} + +@-moz-keyframes wobble { + 0% { + -moz-transform: translateX(0%); + } + + 15% { + -moz-transform: translateX(-25%) rotate(-5deg); + } + + 30% { + -moz-transform: translateX(20%) rotate(3deg); + } + + 45% { + -moz-transform: translateX(-15%) rotate(-3deg); + } + + 60% { + -moz-transform: translateX(10%) rotate(2deg); + } + + 75% { + -moz-transform: translateX(-5%) rotate(-1deg); + } + + 100% { + -moz-transform: translateX(0%); + opacity: 1; + } +} + +@-o-keyframes wobble { + 0% { + -o-transform: translateX(0%); + } + + 15% { + -o-transform: translateX(-25%) rotate(-5deg); + } + + 30% { + -o-transform: translateX(20%) rotate(3deg); + } + + 45% { + -o-transform: translateX(-15%) rotate(-3deg); + } + + 60% { + -o-transform: translateX(10%) rotate(2deg); + } + + 75% { + -o-transform: translateX(-5%) rotate(-1deg); + } + + 100% { + -o-transform: translateX(0%); + opacity: 1; + } +} + +@keyframes wobble { + 0% { + transform: translateX(0%); + } + + 15% { + transform: translateX(-25%) rotate(-5deg); + } + + 30% { + transform: translateX(20%) rotate(3deg); + } + + 45% { + transform: translateX(-15%) rotate(-3deg); + } + + 60% { + transform: translateX(10%) rotate(2deg); + } + + 75% { + transform: translateX(-5%) rotate(-1deg); + } + + 100% { + transform: translateX(0%); + opacity: 1; + } +} + +.wobble { + -webkit-animation-name: wobble; + -moz-animation-name: wobble; + -o-animation-name: wobble; + animation-name: wobble; +} + +@-webkit-keyframes wiggle { + 0% { + -webkit-transform: skewX(9deg); + } + + 10% { + -webkit-transform: skewX(-8deg); + } + + 20% { + -webkit-transform: skewX(7deg); + } + + 30% { + -webkit-transform: skewX(-6deg); + } + + 40% { + -webkit-transform: skewX(5deg); + } + + 50% { + -webkit-transform: skewX(-4deg); + } + + 60% { + -webkit-transform: skewX(3deg); + } + + 70% { + -webkit-transform: skewX(-2deg); + } + + 80% { + -webkit-transform: skewX(1deg); + } + + 90% { + -webkit-transform: skewX(0deg); + } + + 100% { + -webkit-transform: skewX(0deg); + opacity: 1; + } +} + +@-moz-keyframes wiggle { + 0% { + -moz-transform: skewX(9deg); + } + + 10% { + -moz-transform: skewX(-8deg); + } + + 20% { + -moz-transform: skewX(7deg); + } + + 30% { + -moz-transform: skewX(-6deg); + } + + 40% { + -moz-transform: skewX(5deg); + } + + 50% { + -moz-transform: skewX(-4deg); + } + + 60% { + -moz-transform: skewX(3deg); + } + + 70% { + -moz-transform: skewX(-2deg); + } + + 80% { + -moz-transform: skewX(1deg); + } + + 90% { + -moz-transform: skewX(0deg); + } + + 100% { + -moz-transform: skewX(0deg); + opacity: 1; + } +} + +@-o-keyframes wiggle { + 0% { + -o-transform: skewX(9deg); + } + + 10% { + -o-transform: skewX(-8deg); + } + + 20% { + -o-transform: skewX(7deg); + } + + 30% { + -o-transform: skewX(-6deg); + } + + 40% { + -o-transform: skewX(5deg); + } + + 50% { + -o-transform: skewX(-4deg); + } + + 60% { + -o-transform: skewX(3deg); + } + + 70% { + -o-transform: skewX(-2deg); + } + + 80% { + -o-transform: skewX(1deg); + } + + 90% { + -o-transform: skewX(0deg); + } + + 100% { + -o-transform: skewX(0deg); + opacity: 1; + } +} + +@keyframes wiggle { + 0% { + transform: skewX(9deg); + } + + 10% { + transform: skewX(-8deg); + } + + 20% { + transform: skewX(7deg); + } + + 30% { + transform: skewX(-6deg); + } + + 40% { + transform: skewX(5deg); + } + + 50% { + transform: skewX(-4deg); + } + + 60% { + transform: skewX(3deg); + } + + 70% { + transform: skewX(-2deg); + } + + 80% { + transform: skewX(1deg); + } + + 90% { + transform: skewX(0deg); + } + + 100% { + transform: skewX(0deg); + opacity: 1; + } +} + +.wiggle { + -webkit-animation-name: wiggle; + -moz-animation-name: wiggle; + -o-animation-name: wiggle; + animation-name: wiggle; + -webkit-animation-timing-function: ease-in; + -moz-animation-timing-function: ease-in; + -o-animation-timing-function: ease-in; + animation-timing-function: ease-in; +} + +/* originally authored by Nick Pettit - https: //github.com/nickpettit/glide */ +@-webkit-keyframes pulse { + 0% { + -webkit-transform: scale(1); + } + + 50% { + -webkit-transform: scale(1.1); + } + + 100% { + -webkit-transform: scale(1); + opacity: 1; + } +} + +@-moz-keyframes pulse { + 0% { + -moz-transform: scale(1); + } + + 50% { + -moz-transform: scale(1.1); + } + + 100% { + -moz-transform: scale(1); + opacity: 1; + } +} + +@-o-keyframes pulse { + 0% { + -o-transform: scale(1); + } + + 50% { + -o-transform: scale(1.1); + } + + 100% { + -o-transform: scale(1); + opacity: 1; + } +} + +@keyframes pulse { + 0% { + transform: scale(1); + } + + 50% { + transform: scale(1.1); + } + + 100% { + transform: scale(1); + opacity: 1; + } +} + +.pulse { + -webkit-animation-name: pulse; + -moz-animation-name: pulse; + -o-animation-name: pulse; + animation-name: pulse; +} + +@-webkit-keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-moz-keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@-o-keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +@keyframes fadeIn { + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } +} + +.fadeIn { + -webkit-animation-name: fadeIn; + -moz-animation-name: fadeIn; + -o-animation-name: fadeIn; + animation-name: fadeIn; +} + +@-webkit-keyframes fadeInUp { + 0% { + opacity: 0; + -webkit-transform: translateY(20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes fadeInUp { + 0% { + opacity: 0; + -moz-transform: translateY(20px); + } + + 100% { + opacity: 1; + -moz-transform: translateY(0); + } +} + +@-o-keyframes fadeInUp { + 0% { + opacity: 0; + -o-transform: translateY(20px); + } + + 100% { + opacity: 1; + -o-transform: translateY(0); + } +} + +@keyframes fadeInUp { + 0% { + opacity: 0; + transform: translateY(20px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.fadeInUp { + -webkit-animation-name: fadeInUp; + -moz-animation-name: fadeInUp; + -o-animation-name: fadeInUp; + animation-name: fadeInUp; +} + +@-webkit-keyframes fadeInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes fadeInDown { + 0% { + opacity: 0; + -moz-transform: translateY(-20px); + } + + 100% { + opacity: 1; + -moz-transform: translateY(0); + } +} + +@-o-keyframes fadeInDown { + 0% { + opacity: 0; + -o-transform: translateY(-20px); + } + + 100% { + opacity: 1; + -o-transform: translateY(0); + } +} + +@keyframes fadeInDown { + 0% { + opacity: 0; + transform: translateY(-20px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.fadeInDown { + -webkit-animation-name: fadeInDown; + -moz-animation-name: fadeInDown; + -o-animation-name: fadeInDown; + animation-name: fadeInDown; +} + +@-webkit-keyframes fadeInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes fadeInLeft { + 0% { + opacity: 0; + -moz-transform: translateX(-20px); + } + + 100% { + opacity: 1; + -moz-transform: translateX(0); + } +} + +@-o-keyframes fadeInLeft { + 0% { + opacity: 0; + -o-transform: translateX(-20px); + } + + 100% { + opacity: 1; + -o-transform: translateX(0); + } +} + +@keyframes fadeInLeft { + 0% { + opacity: 0; + transform: translateX(-20px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +.fadeInLeft { + -webkit-animation-name: fadeInLeft; + -moz-animation-name: fadeInLeft; + -o-animation-name: fadeInLeft; + animation-name: fadeInLeft; +} + +@-webkit-keyframes fadeInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(20px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes fadeInRight { + 0% { + opacity: 0; + -moz-transform: translateX(20px); + } + + 100% { + opacity: 1; + -moz-transform: translateX(0); + } +} + +@-o-keyframes fadeInRight { + 0% { + opacity: 0; + -o-transform: translateX(20px); + } + + 100% { + opacity: 1; + -o-transform: translateX(0); + } +} + +@keyframes fadeInRight { + 0% { + opacity: 0; + transform: translateX(20px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +.fadeInRight { + -webkit-animation-name: fadeInRight; + -moz-animation-name: fadeInRight; + -o-animation-name: fadeInRight; + animation-name: fadeInRight; +} + +@-webkit-keyframes fadeInUpBig { + 0% { + opacity: 0; + -webkit-transform: translateY(2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes fadeInUpBig { + 0% { + opacity: 0; + -moz-transform: translateY(2000px); + } + + 100% { + opacity: 1; + -moz-transform: translateY(0); + } +} + +@-o-keyframes fadeInUpBig { + 0% { + opacity: 0; + -o-transform: translateY(2000px); + } + + 100% { + opacity: 1; + -o-transform: translateY(0); + } +} + +@keyframes fadeInUpBig { + 0% { + opacity: 0; + transform: translateY(2000px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.fadeInUpBig { + -webkit-animation-name: fadeInUpBig; + -moz-animation-name: fadeInUpBig; + -o-animation-name: fadeInUpBig; + animation-name: fadeInUpBig; +} + +@-webkit-keyframes fadeInDownBig { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateY(0); + } +} + +@-moz-keyframes fadeInDownBig { + 0% { + opacity: 0; + -moz-transform: translateY(-2000px); + } + + 100% { + opacity: 1; + -moz-transform: translateY(0); + } +} + +@-o-keyframes fadeInDownBig { + 0% { + opacity: 0; + -o-transform: translateY(-2000px); + } + + 100% { + opacity: 1; + -o-transform: translateY(0); + } +} + +@keyframes fadeInDownBig { + 0% { + opacity: 0; + transform: translateY(-2000px); + } + + 100% { + opacity: 1; + transform: translateY(0); + } +} + +.fadeInDownBig { + -webkit-animation-name: fadeInDownBig; + -moz-animation-name: fadeInDownBig; + -o-animation-name: fadeInDownBig; + animation-name: fadeInDownBig; +} + +@-webkit-keyframes fadeInLeftBig { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes fadeInLeftBig { + 0% { + opacity: 0; + -moz-transform: translateX(-2000px); + } + + 100% { + opacity: 1; + -moz-transform: translateX(0); + } +} + +@-o-keyframes fadeInLeftBig { + 0% { + opacity: 0; + -o-transform: translateX(-2000px); + } + + 100% { + opacity: 1; + -o-transform: translateX(0); + } +} + +@keyframes fadeInLeftBig { + 0% { + opacity: 0; + transform: translateX(-2000px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +.fadeInLeftBig { + -webkit-animation-name: fadeInLeftBig; + -moz-animation-name: fadeInLeftBig; + -o-animation-name: fadeInLeftBig; + animation-name: fadeInLeftBig; +} + +@-webkit-keyframes fadeInRightBig { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + } + + 100% { + opacity: 1; + -webkit-transform: translateX(0); + } +} + +@-moz-keyframes fadeInRightBig { + 0% { + opacity: 0; + -moz-transform: translateX(2000px); + } + + 100% { + opacity: 1; + -moz-transform: translateX(0); + } +} + +@-o-keyframes fadeInRightBig { + 0% { + opacity: 0; + -o-transform: translateX(2000px); + } + + 100% { + opacity: 1; + -o-transform: translateX(0); + } +} + +@keyframes fadeInRightBig { + 0% { + opacity: 0; + transform: translateX(2000px); + } + + 100% { + opacity: 1; + transform: translateX(0); + } +} + +.fadeInRightBig { + -webkit-animation-name: fadeInRightBig; + -moz-animation-name: fadeInRightBig; + -o-animation-name: fadeInRightBig; + animation-name: fadeInRightBig; +} + +@-webkit-keyframes bounceIn { + 0% { + opacity: 0; + -webkit-transform: scale(0.3); + } + + 50% { + opacity: 1; + -webkit-transform: scale(1.05); + } + + 70% { + -webkit-transform: scale(0.9); + } + + 100% { + -webkit-transform: scale(1); + opacity: 1; + } +} + +@-moz-keyframes bounceIn { + 0% { + opacity: 0; + -moz-transform: scale(0.3); + } + + 50% { + opacity: 1; + -moz-transform: scale(1.05); + } + + 70% { + -moz-transform: scale(0.9); + } + + 100% { + -moz-transform: scale(1); + opacity: 1; + } +} + +@-o-keyframes bounceIn { + 0% { + opacity: 0; + -o-transform: scale(0.3); + } + + 50% { + opacity: 1; + -o-transform: scale(1.05); + } + + 70% { + -o-transform: scale(0.9); + } + + 100% { + -o-transform: scale(1); + opacity: 1; + } +} + +@keyframes bounceIn { + 0% { + opacity: 0; + transform: scale(0.3); + } + + 50% { + opacity: 1; + transform: scale(1.05); + } + + 70% { + transform: scale(0.9); + } + + 100% { + transform: scale(1); + opacity: 1; + } +} + +.bounceIn { + -webkit-animation-name: bounceIn; + -moz-animation-name: bounceIn; + -o-animation-name: bounceIn; + animation-name: bounceIn; +} + +@-webkit-keyframes bounceInUp { + 0% { + opacity: 0; + -webkit-transform: translateY(2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateY(-30px); + } + + 80% { + -webkit-transform: translateY(10px); + } + + 100% { + -webkit-transform: translateY(0); + opacity: 1; + } +} + +@-moz-keyframes bounceInUp { + 0% { + opacity: 0; + -moz-transform: translateY(2000px); + } + + 60% { + opacity: 1; + -moz-transform: translateY(-30px); + } + + 80% { + -moz-transform: translateY(10px); + } + + 100% { + -moz-transform: translateY(0); + opacity: 1; + } +} + +@-o-keyframes bounceInUp { + 0% { + opacity: 0; + -o-transform: translateY(2000px); + } + + 60% { + opacity: 1; + -o-transform: translateY(-30px); + } + + 80% { + -o-transform: translateY(10px); + } + + 100% { + -o-transform: translateY(0); + opacity: 1; + } +} + +@keyframes bounceInUp { + 0% { + opacity: 0; + transform: translateY(2000px); + } + + 60% { + opacity: 1; + transform: translateY(-30px); + } + + 80% { + transform: translateY(10px); + } + + 100% { + transform: translateY(0); + opacity: 1; + } +} + +.bounceInUp { + -webkit-animation-name: bounceInUp; + -moz-animation-name: bounceInUp; + -o-animation-name: bounceInUp; + animation-name: bounceInUp; +} + +@-webkit-keyframes bounceInDown { + 0% { + opacity: 0; + -webkit-transform: translateY(-2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateY(30px); + } + + 80% { + -webkit-transform: translateY(-10px); + } + + 100% { + -webkit-transform: translateY(0); + opacity: 1; + } +} + +@-moz-keyframes bounceInDown { + 0% { + opacity: 0; + -moz-transform: translateY(-2000px); + } + + 60% { + opacity: 1; + -moz-transform: translateY(30px); + } + + 80% { + -moz-transform: translateY(-10px); + } + + 100% { + -moz-transform: translateY(0); + opacity: 1; + } +} + +@-o-keyframes bounceInDown { + 0% { + opacity: 0; + -o-transform: translateY(-2000px); + } + + 60% { + opacity: 1; + -o-transform: translateY(30px); + } + + 80% { + -o-transform: translateY(-10px); + } + + 100% { + -o-transform: translateY(0); + opacity: 1; + } +} + +@keyframes bounceInDown { + 0% { + opacity: 0; + transform: translateY(-2000px); + } + + 60% { + opacity: 1; + transform: translateY(30px); + } + + 80% { + transform: translateY(-10px); + } + + 100% { + transform: translateY(0); + opacity: 1; + } +} + +.bounceInDown { + -webkit-animation-name: bounceInDown; + -moz-animation-name: bounceInDown; + -o-animation-name: bounceInDown; + animation-name: bounceInDown; +} + +@-webkit-keyframes bounceInLeft { + 0% { + opacity: 0; + -webkit-transform: translateX(-2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateX(30px); + } + + 80% { + -webkit-transform: translateX(-10px); + } + + 100% { + -webkit-transform: translateX(0); + opacity: 1; + } +} + +@-moz-keyframes bounceInLeft { + 0% { + opacity: 0; + -moz-transform: translateX(-2000px); + } + + 60% { + opacity: 1; + -moz-transform: translateX(30px); + } + + 80% { + -moz-transform: translateX(-10px); + } + + 100% { + -moz-transform: translateX(0); + opacity: 1; + } +} + +@-o-keyframes bounceInLeft { + 0% { + opacity: 0; + -o-transform: translateX(-2000px); + } + + 60% { + opacity: 1; + -o-transform: translateX(30px); + } + + 80% { + -o-transform: translateX(-10px); + } + + 100% { + -o-transform: translateX(0); + opacity: 1; + } +} + +@keyframes bounceInLeft { + 0% { + opacity: 0; + transform: translateX(-2000px); + } + + 60% { + opacity: 1; + transform: translateX(30px); + } + + 80% { + transform: translateX(-10px); + } + + 100% { + transform: translateX(0); + opacity: 1; + } +} + +.bounceInLeft { + -webkit-animation-name: bounceInLeft; + -moz-animation-name: bounceInLeft; + -o-animation-name: bounceInLeft; + animation-name: bounceInLeft; +} + +@-webkit-keyframes bounceInRight { + 0% { + opacity: 0; + -webkit-transform: translateX(2000px); + } + + 60% { + opacity: 1; + -webkit-transform: translateX(-30px); + } + + 80% { + -webkit-transform: translateX(10px); + } + + 100% { + -webkit-transform: translateX(0); + opacity: 1; + } +} + +@-moz-keyframes bounceInRight { + 0% { + opacity: 0; + -moz-transform: translateX(2000px); + } + + 60% { + opacity: 1; + -moz-transform: translateX(-30px); + } + + 80% { + -moz-transform: translateX(10px); + } + + 100% { + -moz-transform: translateX(0); + opacity: 1; + } +} + +@-o-keyframes bounceInRight { + 0% { + opacity: 0; + -o-transform: translateX(2000px); + } + + 60% { + opacity: 1; + -o-transform: translateX(-30px); + } + + 80% { + -o-transform: translateX(10px); + } + + 100% { + -o-transform: translateX(0); + opacity: 1; + } +} + +@keyframes bounceInRight { + 0% { + opacity: 0; + transform: translateX(2000px); + } + + 60% { + opacity: 1; + transform: translateX(-30px); + } + + 80% { + transform: translateX(10px); + } + + 100% { + transform: translateX(0); + opacity: 1; + } +} + +.bounceInRight { + -webkit-animation-name: bounceInRight; + -moz-animation-name: bounceInRight; + -o-animation-name: bounceInRight; + animation-name: bounceInRight; +} + +@-webkit-keyframes rotateIn { + 0% { + -webkit-transform-origin: center center; + -webkit-transform: rotate(-200deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: center center; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateIn { + 0% { + -moz-transform-origin: center center; + -moz-transform: rotate(-200deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: center center; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateIn { + 0% { + -o-transform-origin: center center; + -o-transform: rotate(-200deg); + opacity: 0; + } + + 100% { + -o-transform-origin: center center; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateIn { + 0% { + transform-origin: center center; + transform: rotate(-200deg); + opacity: 0; + } + + 100% { + transform-origin: center center; + transform: rotate(0); + opacity: 1; + } +} + +.rotateIn { + -webkit-animation-name: rotateIn; + -moz-animation-name: rotateIn; + -o-animation-name: rotateIn; + animation-name: rotateIn; +} + +@-webkit-keyframes rotateInUpLeft { + 0% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateInUpLeft { + 0% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateInUpLeft { + 0% { + -o-transform-origin: left bottom; + -o-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -o-transform-origin: left bottom; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInUpLeft { + 0% { + transform-origin: left bottom; + transform: rotate(90deg); + opacity: 0; + } + + 100% { + transform-origin: left bottom; + transform: rotate(0); + opacity: 1; + } +} + +.rotateInUpLeft { + -webkit-animation-name: rotateInUpLeft; + -moz-animation-name: rotateInUpLeft; + -o-animation-name: rotateInUpLeft; + animation-name: rotateInUpLeft; +} + +@-webkit-keyframes rotateInDownLeft { + 0% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: left bottom; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateInDownLeft { + 0% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: left bottom; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateInDownLeft { + 0% { + -o-transform-origin: left bottom; + -o-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -o-transform-origin: left bottom; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInDownLeft { + 0% { + transform-origin: left bottom; + transform: rotate(-90deg); + opacity: 0; + } + + 100% { + transform-origin: left bottom; + transform: rotate(0); + opacity: 1; + } +} + +.rotateInDownLeft { + -webkit-animation-name: rotateInDownLeft; + -moz-animation-name: rotateInDownLeft; + -o-animation-name: rotateInDownLeft; + animation-name: rotateInDownLeft; +} + +@-webkit-keyframes rotateInUpRight { + 0% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateInUpRight { + 0% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateInUpRight { + 0% { + -o-transform-origin: right bottom; + -o-transform: rotate(-90deg); + opacity: 0; + } + + 100% { + -o-transform-origin: right bottom; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInUpRight { + 0% { + transform-origin: right bottom; + transform: rotate(-90deg); + opacity: 0; + } + + 100% { + transform-origin: right bottom; + transform: rotate(0); + opacity: 1; + } +} + +.rotateInUpRight { + -webkit-animation-name: rotateInUpRight; + -moz-animation-name: rotateInUpRight; + -o-animation-name: rotateInUpRight; + animation-name: rotateInUpRight; +} + +@-webkit-keyframes rotateInDownRight { + 0% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -webkit-transform-origin: right bottom; + -webkit-transform: rotate(0); + opacity: 1; + } +} + +@-moz-keyframes rotateInDownRight { + 0% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -moz-transform-origin: right bottom; + -moz-transform: rotate(0); + opacity: 1; + } +} + +@-o-keyframes rotateInDownRight { + 0% { + -o-transform-origin: right bottom; + -o-transform: rotate(90deg); + opacity: 0; + } + + 100% { + -o-transform-origin: right bottom; + -o-transform: rotate(0); + opacity: 1; + } +} + +@keyframes rotateInDownRight { + 0% { + transform-origin: right bottom; + transform: rotate(90deg); + opacity: 0; + } + + 100% { + transform-origin: right bottom; + transform: rotate(0); + opacity: 1; + } +} + +.rotateInDownRight { + -webkit-animation-name: rotateInDownRight; + -moz-animation-name: rotateInDownRight; + -o-animation-name: rotateInDownRight; + animation-name: rotateInDownRight; +} + +.thumb-info { + position: relative; +} + +.thumb-info .thumb-info-title { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + transition: all 0.3s; + background: rgba(36, 27, 28, 0.9); + bottom: 10%; + color: #FFF; + font-size: 18px; + font-weight: 700; + left: 0; + letter-spacing: -1px; + padding: 9px 11px 9px; + position: absolute; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + text-transform: uppercase; + z-index: 1; +} + +.thumb-info .thumb-info-inner { + -webkit-transition: all 0.3s; + -moz-transition: all 0.3s; + transition: all 0.3s; + display: block; + white-space: nowrap; +} + +.thumb-info .thumb-info-type { + background-color: #cccccc; + border-radius: 2px; + display: inline-block; + float: left; + font-size: 12px; + font-weight: 400; + letter-spacing: 0; + margin: 8px -2px -15px -2px; + padding: 2px 9px; + text-transform: none; +} + +/* Widget - Widget Toggle/Expand */ +.widget-toggle-expand .widget-header { + position: relative; + margin: 0; + padding: 5px 0; +} + +.widget-toggle-expand .widget-header h6 { + font-size: 13px; + font-size: 1.3rem; + margin: 0; + padding: 0; +} + +.widget-toggle-expand .widget-header .widget-toggle { + font-size: 21px; + font-size: 2.1rem; + line-height: 21px; + line-height: 2.1rem; + position: absolute; + right: 0; + top: 0; + cursor: pointer; + text-align: center; + color: #b4b4b4; + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + -webkit-transition-property: -webkit-transform; + -moz-transition-property: -moz-transform; + transition-property: transform; + -webkit-transition-duration: 0.2s; + -moz-transition-duration: 0.2s; + transition-duration: 0.2s; + -webkit-transition-timing-function: linear; + -moz-transition-timing-function: linear; + transition-timing-function: linear; +} + +.widget-toggle-expand.widget-collapsed .widget-content-expanded { + display: none; +} + +.widget-toggle-expand.widget-collapsed .widget-header .widget-toggle { + -webkit-transform: none; + -moz-transform: none; + -ms-transform: none; + -o-transform: none; + transform: none; +} + +/* Widget - Simple User List */ +ul.simple-user-list { + list-style: none; + padding: 0; +} + +ul.simple-user-list li { + margin: 0 0 20px; +} + +ul.simple-user-list li .image { + float: left; + margin: 0 10px 0 0; +} + +ul.simple-user-list li .title { + color: #000011; + display: block; + line-height: 1.334; +} + +ul.simple-user-list li .message { + display: block; + font-size: 11px; + font-size: 1.1rem; + line-height: 1.334; +} + +/* Widget - Simple Post List */ +ul.simple-post-list { + list-style: none; + margin: 0; + padding: 0; +} + +ul.simple-post-list li { + border-bottom: 1px dotted #E2E2E2; + padding: 15px 0; +} + +ul.simple-post-list li:after { + content: ""; + display: table; + clear: both; +} + +ul.simple-post-list li::last-child { + border-bottom: 0; +} + +ul.simple-post-list li .post-image { + float: left; + margin-right: 12px; +} + +ul.simple-post-list li .post-meta { + color: #888; + font-size: 0.8em; +} + +ul.simple-post-list li:last-child { + border-bottom: none; +} + +/* Widget - Simple Todo List */ +ul.simple-todo-list { + list-style: none; + padding: 0; + margin: 0; +} + +ul.simple-todo-list li { + position: relative; + padding: 0 0 0 20px; +} + +ul.simple-todo-list li.completed { + color: #A7A7A7; +} + +ul.simple-todo-list li.completed:before { + position: absolute; + top: 3px; + left: 0; + font-family: FontAwesome; + content: "\f00c"; + z-index: 1; +} + +/* Widget - Social Icons */ +.social-icons-list { + display: block; + margin: 0; + padding: 0; +} + +.social-icons-list a { + background: #cccccc; + border-radius: 25px; + display: inline-block; + height: 30px; + line-height: 30px; + text-align: center; + width: 30px; +} + +.social-icons-list a:hover { + text-decoration: none; +} + +.social-icons-list a span { + display: none; +} + +.social-icons-list a i { + font-size: 13.5px; + font-size: 1.35rem; + color: #FFF; + font-weight: normal; +} + +/* Widget - Simple Compose Box */ +.simple-compose-box { + border: 1px solid #d1d1d1; + -webkit-border-radius: 3px; + border-radius: 3px; + background-color: #fff; +} + +.simple-compose-box textarea { + background-color: transparent; + display: block; + width: 100%; + padding: 10px 10px 5px; + border: 0; + resize: none; + -webkit-border-radius: 3px; + border-radius: 3px; +} + +.simple-compose-box textarea:focus { + border: 0 none; + outline: none; +} + +.simple-compose-box .compose-box-footer { + background-color: #F6F7F8; + -webkit-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; +} + +.simple-compose-box .compose-box-footer:after { + content: ""; + display: table; + clear: both; +} + +.simple-compose-box .compose-box-footer .compose-toolbar { + list-style: none; + margin: 0; + padding: 0 3px; + float: left; +} + +.simple-compose-box .compose-box-footer .compose-toolbar li { + display: inline-block; +} + +.simple-compose-box .compose-box-footer .compose-toolbar li a { + display: block; + text-align: center; + font-size: 16px; + line-height: 30px; + width: 30px; + color: #B3B7BD; +} + +.simple-compose-box .compose-box-footer .compose-toolbar li a:hover { + background-color: #e8eaed; +} + +.simple-compose-box .compose-box-footer .compose-btn { + list-style: none; + margin: 0; + padding: 3px; + float: right; +} + +/* Widget - Simple Card List */ +ul.simple-card-list { + list-style: none; + padding: 0; +} + +ul.simple-card-list li { + padding: 10px 15px; + margin: 15px 0; + -webkit-border-radius: 7px; + border-radius: 7px; +} + +ul.simple-card-list li h3 { + font-size: 26px; + font-size: 2.6rem; + font-weight: 600; + margin: 0; +} + +ul.simple-card-list li p { + margin: 0; + opacity: .7; +} + +.simple-card-list li.primary { + background: #cccccc; + color: white; +} + +.simple-card-list li.success { + background: #47a447; + color: white; +} + +.simple-card-list li.warning { + background: #ed9c28; + color: white; +} + +.simple-card-list li.danger { + background: #d2322d; + color: white; +} + +.simple-card-list li.info { + background: #5bc0de; + color: white; +} + +.simple-card-list li.dark { + background: #171717; + color: white; +} + +div.simple-card-list { + display: table; + width: 100%; +} + +div.simple-card-list .card { + display: table-cell; +} + +div.simple-card-list .card .card-content { + background-color: rgba(0, 0, 0, 0.1); + -webkit-border-radius: 3px; + border-radius: 3px; + margin: 0 7px; + padding: 5px; +} + +div.simple-card-list .card h3 { + font-size: 26px; + font-size: 2.6rem; + font-weight: 600; + margin: 0; +} + +div.simple-card-list .card p { + margin: 0; + opacity: .7; +} + +/* Widget - Simple Button List */ +ul.simple-bullet-list { + list-style: none; + padding: 0; +} + +ul.simple-bullet-list li { + position: relative; + padding: 0 0 0 20px; + margin: 0 0 10px; +} + +ul.simple-bullet-list li:before { + border: 6px solid #cccccc; + border-radius: 100px; + content: ''; + display: inline-block; + left: 0; + margin: 0; + position: absolute; + top: 5px; + z-index: 2; +} + +ul.simple-bullet-list li .title { + display: block; + font-weight: 700; + font-size: 14px; + font-size: 1.4rem; + line-height: 1.4; + color: #171717; +} + +ul.simple-bullet-list li .description { + display: block; + color: #999999; + font-size: 11px; + font-size: 1.1rem; + line-height: 1.334; +} + +ul.simple-bullet-list li.red:before { + border-color: #d64b4b; +} + +ul.simple-bullet-list li.green:before { + border-color: #4dd79c; +} + +ul.simple-bullet-list li.blue:before { + border-color: #0090d9; +} + +ul.simple-bullet-list li.orange:before { + border-color: #E2A917; +} + +/* Widget - Summary */ +.widget-summary { + display: table; + width: 100%; +} + +.widget-summary:after { + content: ""; + display: table; + clear: both; +} + +.widget-summary .widget-summary-col { + display: table-cell; + vertical-align: top; + width: 100%; +} + +.widget-summary .widget-summary-col.widget-summary-col-icon { + width: 1%; +} + +.widget-summary .summary-icon { + margin-right: 15px; + font-size: 42px; + font-size: 4.2rem; + width: 90px; + height: 90px; + line-height: 90px; + text-align: center; + color: #fff; + -webkit-border-radius: 55px; + border-radius: 55px; +} + +.widget-summary .summary { + min-height: 65px; + word-break: break-all; +} + +.widget-summary .summary .title { + margin: 0; + font-size: 16px; + font-size: 1.6rem; + line-height: 22px; + line-height: 2.2rem; + color: #333333; + font-weight: 500; +} + +.widget-summary .summary .info { + font-size: 14px; + font-size: 1.4rem; + line-height: 30px; + line-height: 3rem; +} + +.widget-summary .summary .info span { + vertical-align: middle; +} + +.widget-summary .summary .amount { + margin-right: .2em; + font-size: 24px; + font-size: 2.4rem; + font-weight: 600; + color: #333333; + vertical-align: middle; +} + +.widget-summary .summary-footer { + padding: 5px 0 0; + border-top: 1px dotted #ddd; + text-align: right; +} + +.bg-primary .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-primary .widget-summary .summary .title, +.bg-primary .widget-summary .summary .amount { + color: white; +} + +.bg-primary .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-primary .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +.bg-secondary .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-secondary .widget-summary .summary .title, +.bg-secondary .widget-summary .summary .amount { + color: white; +} + +.bg-secondary .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-secondary .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +.bg-tertiary .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-tertiary .widget-summary .summary .title, +.bg-tertiary .widget-summary .summary .amount { + color: white; +} + +.bg-tertiary .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-tertiary .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +.bg-quartenary .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-quartenary .widget-summary .summary .title, +.bg-quartenary .widget-summary .summary .amount { + color: white; +} + +.bg-quartenary .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-quartenary .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +.bg-success .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-success .widget-summary .summary .title, +.bg-success .widget-summary .summary .amount { + color: white; +} + +.bg-success .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-success .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +.bg-warning .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-warning .widget-summary .summary .title, +.bg-warning .widget-summary .summary .amount { + color: white; +} + +.bg-warning .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-warning .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +.bg-danger .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-danger .widget-summary .summary .title, +.bg-danger .widget-summary .summary .amount { + color: white; +} + +.bg-danger .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-danger .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +.bg-info .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-info .widget-summary .summary .title, +.bg-info .widget-summary .summary .amount { + color: white; +} + +.bg-info .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-info .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +.bg-dark .widget-summary .summary-icon { + background-color: rgba(0, 0, 0, 0.1); +} + +.bg-dark .widget-summary .summary .title, +.bg-dark .widget-summary .summary .amount { + color: white; +} + +.bg-dark .widget-summary .summary-footer { + border-top: 1px solid #fff; + border-top-color: rgba(255, 255, 255, 0.2); +} + +.bg-dark .widget-summary .summary-footer a { + color: white; + opacity: 0.6; +} + +@media only screen and (min-width: 480px) { + .widget-summary.widget-summary-xlg { + padding: 5px 0; + } + + .widget-summary.widget-summary-xlg .summary-icon { + width: 110px; + height: 110px; + line-height: 110px; + font-size: 48px; + font-size: 4.8rem; + } + + .widget-summary.widget-summary-xlg .summary { + min-height: 80px; + } + + .widget-summary.widget-summary-xlg .summary .title { + font-size: 20px; + font-size: 2rem; + line-height: 28px; + line-height: 2.8rem; + } + + .widget-summary.widget-summary-xlg .summary .info { + font-size: 16px; + font-size: 1.6rem; + line-height: 30px; + line-height: 3rem; + } + + .widget-summary.widget-summary-xlg .summary .amount { + font-size: 28px; + font-size: 2.8rem; + } +} + +.widget-summary.widget-summary-lg { + padding: 0; +} + +.widget-summary.widget-summary-lg .summary-icon { + width: 90px; + height: 90px; + line-height: 90px; + font-size: 42px; + font-size: 4.2rem; +} + +.widget-summary.widget-summary-lg .summary { + min-height: 65px; +} + +.widget-summary.widget-summary-lg .summary .title { + font-size: 16px; + font-size: 1.6rem; + line-height: 22px; + line-height: 2.2rem; +} + +.widget-summary.widget-summary-lg .summary .info { + font-size: 14px; + font-size: 1.4rem; + line-height: 30px; + line-height: 3rem; +} + +.widget-summary.widget-summary-lg .summary .amount { + font-size: 24px; + font-size: 2.4rem; +} + +.widget-summary.widget-summary-md { + padding: 0; +} + +.widget-summary.widget-summary-md .summary-icon { + width: 70px; + height: 70px; + line-height: 70px; + font-size: 32px; + font-size: 3.2rem; +} + +.widget-summary.widget-summary-md .summary { + min-height: 0; + margin-top: 12px; +} + +.widget-summary.widget-summary-md .summary .title { + font-size: 12px; + font-size: 1.2rem; + line-height: 18px; + line-height: 1.8rem; +} + +.widget-summary.widget-summary-md .summary .info { + font-size: 11px; + font-size: 1.1rem; + line-height: 22px; + line-height: 2.2rem; +} + +.widget-summary.widget-summary-md .summary .amount { + font-size: 18px; + font-size: 1.8rem; + font-weight: 700; +} + +.widget-summary.widget-summary-md .summary-footer { + display: none; +} + +.widget-summary.widget-summary-sm { + padding: 0; +} + +.widget-summary.widget-summary-sm .summary-icon { + width: 50px; + height: 50px; + line-height: 50px; + font-size: 22px; + font-size: 2.2rem; +} + +.widget-summary.widget-summary-sm .summary { + min-height: 0; + margin-top: 4px; +} + +.widget-summary.widget-summary-sm .summary .title { + font-size: 12px; + font-size: 1.2rem; + line-height: 18px; + line-height: 1.8rem; +} + +.widget-summary.widget-summary-sm .summary .info { + font-size: 11px; + font-size: 1.1rem; + line-height: 18px; + line-height: 1.8rem; +} + +.widget-summary.widget-summary-sm .summary .amount { + font-size: 16px; + font-size: 1.6rem; + font-weight: 700; +} + +.widget-summary.widget-summary-sm .summary-footer { + display: none; +} + +.widget-summary.widget-summary-xs { + padding: 0; +} + +.widget-summary.widget-summary-xs .summary-icon { + width: 40px; + height: 40px; + line-height: 40px; + font-size: 18px; + font-size: 1.8rem; +} + +.widget-summary.widget-summary-xs .summary { + min-height: 0; +} + +.widget-summary.widget-summary-xs .summary .title { + font-size: 12px; + font-size: 1.2rem; + line-height: 40px; +} + +.widget-summary.widget-summary-xs .summary .info { + display: none; +} + +.widget-summary.widget-summary-xs .summary-footer { + display: none; +} + +/* Widget - Todo List */ +ul.widget-todo-list { + list-style: none; + padding: 0; + margin: 0; + position: relative; +} + +ul.widget-todo-list li { + border-bottom: 1px dotted #ddd; + padding: 15px 15px 15px 0; + position: relative; +} + +ul.widget-todo-list li label.line-through span { + text-decoration: line-through; +} + +ul.widget-todo-list li .checkbox-custom { + margin-bottom: 0; +} + +ul.widget-todo-list li .checkbox-custom label { + padding-left: 10px; +} + +ul.widget-todo-list li .todo-actions { + position: absolute; + top: 14px; + right: 0; + bottom: 14px; +} + +ul.widget-todo-list li .todo-actions .todo-remove { + font-size: 10px; + vertical-align: middle; + color: #999999; +} + +ul.widget-todo-list li:last-child { + border-bottom: 0 none; +} + +/* Widget - Profile Info */ +.widget-profile-info { + display: table; + width: 100%; +} + +.widget-profile-info .profile-picture { + display: table-cell; + vertical-align: middle; + width: 1%; +} + +.widget-profile-info .profile-picture img { + display: block; + width: 100px; + height: 100px; + margin-right: 15px; + border: 4px solid #fff; + -webkit-border-radius: 50px; + border-radius: 50px; +} + +.widget-profile-info .profile-info { + display: table-cell; + vertical-align: bottom; + width: 100%; +} + +.widget-profile-info .profile-info .profile-footer { + padding: 5px 0 0; + border-top: 1px solid rgba(255, 255, 255, 0.6); + text-align: right; +} + +.widget-profile-info .profile-info .profile-footer a { + color: #fff; + opacity: 0.6; +} + +/* Widget - Twitter Profile */ +.widget-twitter-profile { + background-color: #cccccc; + border-radius: 5px; + color: #fff; +} + +.widget-twitter-profile .top-image img { + width: 100%; + border-radius: 5px 5px 0 0; +} + +.widget-twitter-profile .profile-info { + padding: 15px; + min-height: 75px; +} + +.widget-twitter-profile .profile-info:after { + content: ""; + display: table; + clear: both; +} + +.widget-twitter-profile .profile-info .profile-picture { + float: left; + margin-right: 15px; + position: relative; +} + +.widget-twitter-profile .profile-info .profile-picture img { + display: block; + width: 100px; + height: 100px; + margin: -25px 0; + border: 4px solid #fff; + -webkit-border-radius: 50px; + border-radius: 50px; +} + +.widget-twitter-profile .profile-info .profile-account { + float: left; +} + +.widget-twitter-profile .profile-info .profile-account .name { + margin: 0; +} + +.widget-twitter-profile .profile-info .profile-account .account { + color: white; + margin: 0; + line-height: 1.4; +} + +.widget-twitter-profile .profile-info .profile-stats { + float: right; + list-style: none; + padding: 5px 0; + margin: 0; +} + +.widget-twitter-profile .profile-info .profile-stats li { + float: left; + padding: 0 10px; +} + +.widget-twitter-profile .profile-info .profile-stats li .stat { + font-size: 10px; + font-size: 1rem; + margin: 0; +} + +.widget-twitter-profile .profile-info .profile-stats li .count { + display: block; + margin: 0; + line-height: 1.4; + font-weight: 600; +} + +.widget-twitter-profile .profile-quote { + background-color: #d6d6d6; + border-radius: 0 0 5px 5px; + padding: 15px 10px 15px 150px; +} + +.widget-twitter-profile .profile-quote blockquote { + padding: 0; + margin: 0; + border: 0; +} + +.widget-twitter-profile .profile-quote blockquote p { + position: relative; + font-style: italic; + font-size: 18px; + font-size: 1.8rem; + line-height: 1.6; + padding: 15px 0; + margin: 0 0 10px; + font-family: Georgia, serif; +} + +.widget-twitter-profile .profile-quote blockquote p:before { + position: absolute; + top: 0; + left: -45px; + content: '\201C'; + font-size: 80px; + font-size: 8rem; + line-height: 1; + font-family: Georgia, serif; + font-style: normal; +} + +.widget-twitter-profile .profile-quote .quote-footer { + border-top: 1px solid #e6e6e6; + padding: 5px 0; + text-align: right; + color: white; +} + +.widget-twitter-profile .profile-quote .quote-footer a { + color: white; +} + +/* Widget - Twitter Profile Responsive */ +@media only screen and (max-width: 479px) { + .widget-twitter-profile .profile-info .profile-stats { + clear: both; + float: none; + padding: 45px 0 0; + text-align: center; + } + + .widget-twitter-profile .profile-info .profile-stats li { + display: inline-block; + float: none; + } +} + +@media only screen and (max-width: 767px) { + .widget-twitter-profile .profile-quote { + padding-left: 10px; + } + + .widget-twitter-profile .profile-quote blockquote { + padding-left: 45px; + } +} + +html.dark { + /* Widget Summary */ + /* Panel Footer - Button Group */ + /* To-do List */ + /* Simple Post List */ + /* Simple User List */ + /* Simple Bullet List */ + /* Simple Compose Box */; +} + +html.dark .widget-summary .summary .title, +html.dark .widget-summary .summary .amount { + color: #EEE; +} + +html.dark .widget-summary .summary-footer { + border-color: #4C4C4C; +} + +html.dark .panel-footer-btn-group a { + background-color: #282d36; + border-color: #21262d; +} + +html.dark .panel-footer-btn-group a:hover { + background-color: #2e353e; +} + +html.dark ul.widget-todo-list li { + border-color: #242830; +} + +html.dark ul.simple-post-list li { + border-color: #4c4c4c; +} + +html.dark ul.simple-user-list li .title { + color: #EEE; +} + +html.dark ul.simple-bullet-list li .title { + color: #EEE; +} + +html.dark .simple-compose-box { + background-color: #282d36; + border-color: #282d36; +} + +html.dark .simple-compose-box .compose-box-footer { + background-color: #21262d; +} + +/* Buttons - States */ +.nav-pills-primary > li a:hover, +.nav-pills-primary > li a:focus { + color: #cccccc; + background-color: white; +} + +.nav-pills-primary > li.active > a, .nav-pills-primary > li.active > a:hover, .nav-pills-primary > li.active > a:active, .nav-pills-primary > li.active > a:focus { + background-color: #cccccc; +} + +.nav-pills-success > li a:hover, +.nav-pills-success > li a:focus { + color: #47a447; + background-color: #bfe2bc; +} + +.nav-pills-success > li.active > a, .nav-pills-success > li.active > a:hover, .nav-pills-success > li.active > a:active, .nav-pills-success > li.active > a:focus { + background-color: #47a447; +} + +.nav-pills-warning > li a:hover, +.nav-pills-warning > li a:focus { + color: #ed9c28; + background-color: #fbe4cd; +} + +.nav-pills-warning > li.active > a, .nav-pills-warning > li.active > a:hover, .nav-pills-warning > li.active > a:active, .nav-pills-warning > li.active > a:focus { + background-color: #ed9c28; +} + +.nav-pills-danger > li a:hover, +.nav-pills-danger > li a:focus { + color: #d2322d; + background-color: #f2c0c3; +} + +.nav-pills-danger > li.active > a, .nav-pills-danger > li.active > a:hover, .nav-pills-danger > li.active > a:active, .nav-pills-danger > li.active > a:focus { + background-color: #d2322d; +} + +.nav-pills-info > li a:hover, +.nav-pills-info > li a:focus { + color: #5bc0de; + background-color: #f0fafc; +} + +.nav-pills-info > li.active > a, .nav-pills-info > li.active > a:hover, .nav-pills-info > li.active > a:active, .nav-pills-info > li.active > a:focus { + background-color: #5bc0de; +} + +.nav-pills-dark > li a:hover, +.nav-pills-dark > li a:focus { + color: #171717; + background-color: #707070; +} + +.nav-pills-dark > li.active > a, .nav-pills-dark > li.active > a:hover, .nav-pills-dark > li.active > a:active, .nav-pills-dark > li.active > a:focus { + background-color: #171717; +} + +.portlet-handler { + cursor: move; +} + +.portlet-placeholder { + margin-bottom: 15px; + padding: 0; + border: 1px dashed #dddddd; + background: #fafafa; + color: #444444; +} + +/* Make clicks pass-through */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: #cccccc; + position: fixed; + z-index: 1031; + top: 0; + left: 0; + width: 100%; + height: 2px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px #cccccc, 0 0 5px #cccccc; + opacity: 1.0; + -webkit-transform: rotate(3deg) translate(0px, -4px); + -moz-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + -o-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + border: solid 2px transparent; + border-top-color: #29d; + border-left-color: #29d; + border-radius: 50%; + -webkit-animation: nprogress-spinner 400ms linear infinite; + -moz-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { + -webkit-transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(360deg); + } +} + +@-moz-keyframes nprogress-spinner { + 0% { + -moz-transform: rotate(0); + } + + 100% { + -moz-transform: rotate(360deg); + } +} + +@keyframes nprogress-spinner { + 0% { + -webkit-transform: rotate(0); + -moz-transform: rotate(0); + -ms-transform: rotate(0); + -o-transform: rotate(0); + transform: rotate(0); + } + + 100% { + -webkit-transform: rotate(360deg); + -moz-transform: rotate(360deg); + -ms-transform: rotate(360deg); + -o-transform: rotate(360deg); + transform: rotate(360deg); + } +} +/* Tables - Basic */ +.table { + width: 100%; +} + +.table .table { + background: transparent; +} + +/* Bootstrap uses important, we need to force it here */ +.table.mb-none { + margin-bottom: 0 !important; +} + +/* In case you dont want a border in some row */ +.table .b-top-none td { + border-top: none; +} + +/* Tables - Actions */ +.table .actions, +.table .actions-hover { + vertical-align: middle; +} + +.table .actions a, +.table .actions-hover a { + display: inline-block; + margin-right: 5px; + color: #666; +} + +.table .actions a:last-child, +.table .actions-hover a:last-child { + margin-right: 0; +} + +.table .actions a:hover, +.table .actions-hover a:hover { + color: #333; +} + +.table .actions-hover a { + opacity: 0; +} + +.table tr:hover .actions-hover a { + opacity: 1; +} + +.table .actions-fade a { + -webkit-transition: all 0.2s linear; + -moz-transition: all 0.2s linear; + transition: all 0.2s linear; +} + +/* Tables - No More Tables technique (991px is the bootstrap SM max-width) */ +@media only screen and (max-width: 991px) { + .table.table-no-more, + .table.table-no-more thead, + .table.table-no-more tbody, + .table.table-no-more tr, + .table.table-no-more th, + .table.table-no-more td { + display: block; + } + + .table.table-no-more thead tr { + left: -9999px; + position: absolute; + top: -9999px; + } + + .table.table-no-more tr { + border-bottom: 1px solid #DDD; + } + + .table.table-no-more td { + border: none; + position: relative; + padding-left: 50%; + text-align: left; + white-space: normal; + } + + .table.table-no-more td:before { + content: attr(data-title); + font-weight: bold; + left: 6px; + padding-right: 10px; + position: absolute; + text-align: left; + top: 8px; + white-space: nowrap; + width: 45%; + } + + .table.table-no-more.table-bordered td { + border-bottom: 1px solid #EFEFEF; + } + + .table.table-no-more.table-condensed td:before { + top: 5px; + } +} +/* Dark - Tables */ +html.dark .table > thead > tr > th, +html.dark .table > tbody > tr > th, +html.dark .table > tfoot > tr > th, +html.dark .table > thead > tr > td, +html.dark .table > tbody > tr > td, +html.dark .table > tfoot > tr > td, +html.dark .table-bordered { + border-color: #262b33; +} + +html.dark .table-striped > tbody > tr:nth-child(2n+1) > td, +html.dark .table-striped > tbody > tr:nth-child(2n+1) > th { + background-color: #282d36; +} + +html.dark .table-hover > tbody > tr:hover > td, +html.dark .table-hover > tbody > tr:hover > th { + background-color: #272c34; +} + +html.dark .table .actions a, +html.dark .table .actions-hover a { + color: #808697; +} + +@media screen and (max-width: 991px) { + html.dark .table-responsive { + border-color: #262b33; + } +} + +@media only screen and (max-width: 991px) { + html.dark .table.table-no-more tr, + html.dark .table.table-no-more.table-bordered td { + border-bottom-color: #262b33; + } +} +/* Tables - States */ +.table > thead > tr > td.primary, +.table > tbody > tr > td.primary, +.table > tfoot > tr > td.primary, +.table > thead > tr > th.primary, +.table > tbody > tr > th.primary, +.table > tfoot > tr > th.primary, +.table > thead > tr.primary > td, +.table > tbody > tr.primary > td, +.table > tfoot > tr.primary > td, +.table > thead > tr.primary > th, +.table > tbody > tr.primary > th, +.table > tfoot > tr.primary > th { + color: #FFF; + background-color: #cccccc; +} + +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + color: #FFF; + background-color: #47a447; +} + +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + color: #FFF; + background-color: #ed9c28; +} + +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + color: #FFF; + background-color: #d2322d; +} + +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + color: #FFF; + background-color: #5bc0de; +} + +.table > thead > tr > td.dark, +.table > tbody > tr > td.dark, +.table > tfoot > tr > td.dark, +.table > thead > tr > th.dark, +.table > tbody > tr > th.dark, +.table > tfoot > tr > th.dark, +.table > thead > tr.dark > td, +.table > tbody > tr.dark > td, +.table > tfoot > tr.dark > td, +.table > thead > tr.dark > th, +.table > tbody > tr.dark > th, +.table > tfoot > tr.dark > th { + color: #FFF; + background-color: #171717; +} + +.table > thead > tr > td.dark, +.table > tbody > tr > td.dark, +.table > tfoot > tr > td.dark, +.table > thead > tr > th.dark, +.table > tbody > tr > th.dark, +.table > tfoot > tr > th.dark, +.table > thead > tr.dark > td, +.table > tbody > tr.dark > td, +.table > tfoot > tr.dark > td, +.table > thead > tr.dark > th, +.table > tbody > tr.dark > th, +.table > tfoot > tr.dark > th { + background-color: #4a4a4a; + color: white; +} + +/* Common Fixes */ +.dataTables_wrapper { + position: relative; +} + +.dataTables_wrapper .DTTT.btn-group { + display: inline-block !important; +} + +.dataTables_wrapper .datatables-header { + margin-bottom: 15px; +} + +.dataTables_wrapper .datatables-header label { + font-weight: normal; + margin: 0; +} + +.dataTables_wrapper table thead th { + padding-right: 21px !important; +} + +.dataTables_wrapper .dataTables_length .select2-container { + margin-right: 10px; + width: 75px; +} + +@media only screen and (max-width: 991px) { + .dataTables_wrapper .dataTables_length { + margin-bottom: 15px; + } + + .dataTables_wrapper .dataTables_length label { + float: none; + width: 100%; + } +} +/* Filter */ +.dataTables_wrapper .dataTables_filter label { + width: 50%; +} + +.dataTables_wrapper .dataTables_filter input { + width: 100%; +} + +@media only screen and (max-width: 991px) { + .dataTables_wrapper .dataTables_filter label { + width: 100%; + } +} +/* Footer */ +.dataTables_wrapper .datatables-footer { + margin-top: 15px; +} + +.dataTables_wrapper .datatables-footer .dataTables_info { + font-size: 11px; + padding-top: 0; + margin-top: 6px; +} + +.dataTables_wrapper .datatables-footer .dataTables_paginate .pagination { + display: block; + margin: 0; +} + +@media only screen and (max-width: 991px) { + .dataTables_wrapper .datatables-footer .dataTables_info { + margin-bottom: 15px; + text-align: center; + } + + .dataTables_wrapper .datatables-footer .dataTables_paginate { + float: none; + text-align: center; + } + + .dataTables_wrapper .datatables-footer .dataTables_paginate .pagination { + display: inline-block; + } +} +/* Empty Row */ +.dataTables_wrapper .dataTables_empty { + padding: 50px 0; + text-align: center; +} + +.dataTables_processing { + background: #cccccc; + border-radius: 100px; + box-shadow: 0 1px 1px -1px rgba(0, 0, 0, 0.3); + color: #FFF; + left: 50%; + margin-left: -36px; + padding: 5px 10px; + position: absolute; + top: 3px; +} + +@media only screen and (max-width: 991px) { + .dataTables_processing { + left: auto; + margin-left: 0; + right: 0; + } +} + +.DTTT_Print, +.DTTT_Print .inner-wrapper, +.DTTT_Print .content-body, +.DTTT_Print .panel { + background: #FFF !important; + margin: 0 !important; + padding: 0 !important; + top: 0 !important; +} + +.DTTT_Print .dataTables_wrapper .DTTT.btn-group { + display: none !important; +} + +.DTTT_Print .DTTT_print_info { + background: rgba(255, 255, 255, 0.9); + display: block; + left: 0; + height: 100px; + line-height: 100px; + position: fixed; + font-size: 14px; + text-align: center; + top: 0; + width: 100%; +} + +/* Dark Fixes */ +html.dark div.DTTT .btn { + color: #EEE !important; +} + +.pricing-table { + margin: 25px 0; + padding-left: 0; + text-align: center; +} + +.pricing-table ul { + list-style: none; + margin: 20px 0 0 0; + padding: 0; +} + +.pricing-table li { + border-top: 1px solid #ddd; + padding: 10px 0; +} + +.pricing-table h3 { + background-color: #eee; + border-radius: 2px 2px 0 0; + font-size: 20px; + font-weight: normal; + margin: -20px -20px 50px -20px; + padding: 20px; +} + +.pricing-table h3 span { + background: #FFF; + border: 5px solid #FFF; + border-radius: 100px; + box-shadow: 0 5px 20px #ddd inset, 0 3px 0 #999 inset; + color: #cccccc; + display: block; + font: bold 25px / 100px Georgia, Serif; + height: 100px; + margin: 20px auto -65px; + width: 100px; +} + +.pricing-table .most-popular { + border: 3px solid #CCC; + box-shadow: 11px 0 10px -10px rgba(0, 0, 0, 0.1), -11px 0 10px -10px rgba(0, 0, 0, 0.1); + padding: 30px 20px; + top: -10px; + z-index: 2; +} + +.pricing-table .most-popular h3 { + background-color: #cccccc; + color: #FFF; + padding-top: 30px; +} + +.pricing-table .plan-ribbon-wrapper { + height: 88px; + overflow: hidden; + position: absolute; + right: -5px; + top: -5px; + width: 85px; +} + +.pricing-table .plan-ribbon { + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + background-image: -webkit-linear-gradient(top, #bfdc7a, #8ebf45); + background-image: linear-gradient(to bottom, #bfdc7a, #8ebf45); + background-color: #bfdc7a; + box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); + color: #333; + font-size: 14px; + left: -5px; + padding: 7px 0; + position: relative; + text-align: center; + top: 15px; + width: 120px; +} + +.pricing-table .plan-ribbon:before { + left: 0; + border-left: 3px solid transparent; + border-right: 3px solid transparent; + bottom: -3px; + content: ""; + position: absolute; +} + +.pricing-table .plan-ribbon:after { + border-left: 3px solid transparent; + border-right: 3px solid transparent; + bottom: -3px; + content: ""; + position: absolute; + right: 0; +} + +.pricing-table .plan { + background: #FFF; + border: 1px solid #ddd; + border-radius: 5px; + color: #333; + margin-bottom: 35px; + margin-right: 0; + padding: 20px; + position: relative; +} + +.pricing-table .btn { + margin-top: 5px; +} + +/* dark */ +html.dark .pricing-table li { + border-top-color: #21262d; +} + +html.dark .pricing-table h3 { + background-color: #21262d; + text-shadow: none; +} + +html.dark .pricing-table h3 span { + background: #2e353e; + border-color: #242830; + box-shadow: 0 5px 20px #242830 inset, 0 3px 0 #282d36 inset; + color: #ebebeb; +} + +html.dark .pricing-table .most-popular { + border-color: #282d36; +} + +html.dark .pricing-table .most-popular h3 { + background-color: #282d36; + color: #808697; + text-shadow: none; +} + +html.dark .pricing-table .plan-ribbon { + background-color: #282d36; +} + +html.dark .pricing-table .plan { + background: #282d36; + border: 1px solid #282d36; + color: #808697; + text-shadow: none; +} + +.fileupload .uneditable-input .fa { + position: absolute; + top: 12px; +} + +.fileupload .uneditable-input .fileupload-preview { + display: inline-block; + float: left; + overflow: hidden; + padding: 0 0 0 17px; + text-overflow: ellipsis; + width: 100%; +} + +.fileupload .btn { + border-radius: 0; +} + +@media only screen and (max-width: 479px) { + .fileupload .uneditable-input { + width: 170px; + } +} +/* Datepicker - Input Group Addon */ +.input-daterange .input-group-addon { + min-width: 36px; +} + +/* Datepicker - Base */ +.datepicker { + padding: 10px; + margin: 0 auto; + line-height: 1.1em; +} + +.datepicker.datepicker-inline { + line-height: 1.7em; + width: 100%; +} + +.datepicker table { + width: 100%; +} + +.datepicker table tr td { + border-radius: 0; +} + +.datepicker table thead tr th { + cursor: pointer; + font-size: 13px; + font-size: 1.3rem; + text-align: center; + font-weight: normal; +} + +.datepicker table thead tr th.prev { + content: '\f0d9'; + font-family: FontAwesome; +} + +.datepicker table thead tr th.next { + content: '\f0da'; + font-family: FontAwesome; +} + +.datepicker table td { + text-align: center; + font-size: 12px; + font-size: 1.2rem; +} + +.datepicker table td.day { + -webkit-transition: background-color 0.1s ease-in 0.1s, color 0.1s ease-in 0.1s; + -moz-transition: background-color 0.1s ease-in 0.1s, color 0.1s ease-in 0.1s; + transition: background-color 0.1s ease-in 0.1s, color 0.1s ease-in 0.1s; + cursor: pointer; +} + +/* Datepicker - Skin Default */ +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr th:hover, +.datepicker table tr td span:hover { + background: #cccccc; + color: white; +} + +.datepicker table tbody tr td span.old, +.datepicker table tbody tr td span.new { + color: #CCC; +} + +.datepicker table tbody tr td span.old:hover, +.datepicker table tbody tr td span.new:hover { + color: white; +} + +.datepicker table tbody tr td.day:hover { + background: #cccccc; + color: white; +} + +.datepicker table tbody tr td.day.active { + background: #b3b3b3; + color: white; +} + +.datepicker table tbody tr td.day.new { + color: #777777; +} + +.datepicker table tbody tr td.day.new:hover { + color: white; +} + +/* Datepicker - Skin Dark */ +.datepicker.datepicker-dark { + background: #33363F; +} + +.datepicker.datepicker-dark table thead tr th.datepicker-switch { + color: white; +} + +.datepicker.datepicker-dark table thead tr th.dow { + color: #777777; +} + +.datepicker.datepicker-dark table tbody tr td span.old, +.datepicker.datepicker-dark table tbody tr td span.new { + color: #444; +} + +.datepicker.datepicker-dark table tbody tr td span.old:hover, +.datepicker.datepicker-dark table tbody tr td span.new:hover { + color: white; +} + +.datepicker.datepicker-dark table tbody tr td.day { + color: white; +} + +.datepicker.datepicker-dark table tbody tr td.day:hover { + background: #cccccc; + color: white; +} + +.datepicker.datepicker-dark table tbody tr td.day.active { + background: #b3b3b3; + color: white; +} + +.datepicker.datepicker-dark table tbody tr td.day.new { + color: #777777; +} + +.datepicker.datepicker-dark table tbody tr td.day.new:hover { + color: white; +} + +/* Datepicker - Skin Primary */ +.datepicker.datepicker-primary { + min-width: 255px; +} + +.datepicker.datepicker-primary.datepicker-inline { + background: #fff; + border: 1px solid #eee; +} + +.datepicker.datepicker-primary table thead tr:first-child { + background-color: #cccccc; + color: white; +} + +.datepicker.datepicker-primary table thead tr:first-child th:hover { + background-color: #b3b3b3; +} + +.datepicker.datepicker-primary table thead tr:first-child th:first-child { + border-radius: 4px 0 0 0; +} + +.datepicker.datepicker-primary table thead tr:first-child th:last-child { + border-radius: 0 4px 0 0; +} + +.datepicker.datepicker-primary table thead tr:last-child { + background-color: #d9d9d9; + color: white; +} + +.datepicker.datepicker-primary table thead tr:last-child th:hover { + background-color: #cccccc; +} + +.datepicker.datepicker-primary table thead tr th { + border-radius: 0; +} + +html.dark .input-daterange .input-group-addon { + text-shadow: none; +} + +html.dark .datepicker-dropdown { + color: #EEE; + background-color: #282d36; +} + +html.dark .datepicker-dropdown:after { + border-bottom-color: #282d36; +} + +html.dark .datepicker-dropdown.datepicker-orient-bottom:before { + border-top-color: rgba(0, 0, 0, 0.2); +} + +html.dark .datepicker-dropdown.datepicker-orient-bottom:after { + border-top-color: #282d36; +} + +html.dark .datepicker.datepicker-primary { + border-color: #282d36; + background: #282d36; +} + +.select2-container.form-control { + background: transparent; + border: none; + display: block; + margin: 0; + padding: 0; +} + +.select2-container .select2-choices .select2-search-field input, +.select2-container .select2-choice, +.select2-container .select2-choices { + background: none; + border-radius: 4px; + color: #555; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + background-color: #FFF; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + border-color: #ccc; + padding: 0; +} + +.select2-search input { + border-radius: 4px; + color: #555; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + background-color: #FFF; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + border-color: #ccc; +} + +.select2-container .select2-choices .select2-search-field input { + -webkit-box-shadow: none; + box-shadow: none; +} + +.select2-container .select2-choice { + height: 34px; + line-height: 1.42857; +} + +.select2-container.select2-container-multi.form-control { + height: auto; +} + +.select2-container.input-sm .select2-choice { + height: 30px; + line-height: 1.5; + border-radius: 3px; +} + +.input-group-sm .select2-container .select2-choice { + height: 30px; + line-height: 1.5; + border-radius: 3px; +} + +.select2-container.input-lg .select2-choice, +.input-group-lg .select2-container .select2-choice { + height: 45px; + line-height: 1.33; + border-radius: 6px; +} + +.select2-container-multi .select2-choices .select2-search-field input { + height: 32px; + margin: 0; +} + +.select2-container-multi.input-sm .select2-choices .select2-search-field input { + height: 28px; +} + +.input-group-sm .select2-container-multi .select2-choices .select2-search-field input { + height: 28px; +} + +.select2-container-multi.input-lg .select2-choices .select2-search-field input, +.input-group-lg .select2-container-multi .select2-choices .select2-search-field input { + height: 43px; +} + +.select2-chosen, +.select2-choice > span:first-child, +.select2-container .select2-choices .select2-search-field input { + padding: 6px 12px; +} + +.input-sm .select2-chosen, +.input-group-sm .select2-chosen, +.input-sm .select2-choice > span:first-child, +.input-group-sm .select2-choice > span:first-child, +.input-sm .select2-choices .select2-search-field input, +.input-group-sm .select2-choices .select2-search-field input { + padding: 5px 10px; +} + +.input-lg .select2-chosen, +.input-group-lg .select2-chosen, +.input-lg .select2-choice > span:first-child, +.input-group-lg .select2-choice > span:first-child, +.input-lg .select2-choices .select2-search-field input, +.input-group-lg .select2-choices .select2-search-field input { + padding: 10px 16px; +} + +.select2-container-multi .select2-choices .select2-search-choice { + margin-top: 5px; + margin-bottom: 3px; + color: #fff; + background: #cccccc; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: none; + box-shadow: none; + border: 0 none; + font-size: 75%; + font-weight: bold; +} + +.select2-container-multi.input-sm .select2-choices .select2-search-choice { + margin-top: 3px; + margin-bottom: 2px; +} + +.input-group-sm .select2-container-multi .select2-choices .select2-search-choice { + margin-top: 3px; + margin-bottom: 2px; +} + +.select2-container-multi.input-lg .select2-choices .select2-search-choice, +.input-group-lg .select2-container-multi .select2-choices .select2-search-choice { + line-height: 24px; +} + +.select2-container .select2-choice .select2-arrow, .select2-container .select2-choice div { + border-left: 1px solid #ccc; + background: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.select2-dropdown-open .select2-choice .select2-arrow, .select2-dropdown-open .select2-choice div { + border-left-color: transparent; + background: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.select2-container .select2-choice .select2-arrow b, .select2-container .select2-choice div b { + background-position: 0 3px; +} + +.select2-dropdown-open .select2-choice .select2-arrow b, .select2-dropdown-open .select2-choice div b { + background-position: -18px 3px; +} + +.select2-container.input-sm .select2-choice .select2-arrow b, +.input-group-sm .select2-container .select2-choice .select2-arrow b, +.select2-container.input-sm .select2-choice div b, +.input-group-sm .select2-container .select2-choice div b { + background-position: 0 1px; +} + +.select2-dropdown-open.input-sm .select2-choice .select2-arrow b, +.input-group-sm .select2-dropdown-open .select2-choice .select2-arrow b, +.select2-dropdown-open.input-sm .select2-choice div b, +.input-group-sm .select2-dropdown-open .select2-choice div b { + background-position: -18px 1px; +} + +.select2-container.input-lg .select2-choice .select2-arrow b, +.input-group-lg .select2-container .select2-choice .select2-arrow b, +.select2-container.input-lg .select2-choice div b, +.input-group-lg .select2-container .select2-choice div b { + background-position: 0 9px; +} + +.select2-dropdown-open.input-lg .select2-choice .select2-arrow b, +.input-group-lg .select2-dropdown-open .select2-choice .select2-arrow b, +.select2-dropdown-open.input-lg .select2-choice div b, +.input-group-lg .select2-dropdown-open .select2-choice div b { + background-position: -18px 9px; +} + +.has-warning .select2-choice, +.has-warning .select2-choices { + border-color: #c09853; +} + +.has-warning .select2-container-active .select2-choice, +.has-warning .select2-container-multi.select2-container-active .select2-choices { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + border-color: #a47e3c; +} + +.has-warning.select2-drop-active { + border-color: #a47e3c; +} + +.has-warning.select2-drop-active.select2-drop.select2-drop-above { + border-top-color: #a47e3c; +} + +.has-error .select2-choice, +.has-error .select2-choices { + border-color: #b94a48; +} + +.has-error .select2-container-active .select2-choice, +.has-error .select2-container-multi.select2-container-active .select2-choices { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + border-color: #953b39; +} + +.has-error.select2-drop-active { + border-color: #953b39; +} + +.has-error.select2-drop-active.select2-drop.select2-drop-above { + border-top-color: #953b39; +} + +.has-success .select2-choice, +.has-success .select2-choices { + border-color: #468847; +} + +.has-success .select2-container-active .select2-choice, +.has-success .select2-container-multi.select2-container-active .select2-choices { + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + border-color: #356635; +} + +.has-success.select2-drop-active { + border-color: #356635; +} + +.has-success.select2-drop-active.select2-drop.select2-drop-above { + border-top-color: #356635; +} + +.select2-container-active .select2-choice, +.select2-container-multi.select2-container-active .select2-choices { + outline: none; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -webkit-transition: border-color ease-in-out .15s box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s box-shadow ease-in-out .15s; + border-color: #66afe9; +} + +.select2-drop-active { + border-color: #66afe9; +} + +.select2-drop-auto-width, +.select2-drop.select2-drop-above.select2-drop-active { + border-top-color: #66afe9; +} + +.input-group.select2-bootstrap-prepend [class^=select2-choice] { + border-bottom-left-radius: 0 !important; + border-top-left-radius: 0 !important; +} + +.input-group.select2-bootstrap-append [class^=select2-choice] { + border-bottom-right-radius: 0 !important; + border-top-right-radius: 0 !important; +} + +.select2-dropdown-open [class^=select2-choice] { + border-bottom-right-radius: 0 !important; + border-bottom-left-radius: 0 !important; +} + +.select2-dropdown-open.select2-drop-above [class^=select2-choice] { + border-top-right-radius: 0 !important; + border-top-left-radius: 0 !important; +} + +.select2-dropdown-open.select2-drop-above .select2-choice, +.select2-dropdown-open.select2-drop-above .select2-choices { + background: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +.select2-results .select2-highlighted { + color: #FFF; + background-color: #428bca; +} + +.select2-bootstrap-append .select2-container-multiple, +.select2-bootstrap-prepend .select2-container-multiple { + vertical-align: top; +} + +.select2-bootstrap-append .input-group-btn, +.select2-bootstrap-prepend .input-group-btn { + vertical-align: top; +} + +.select2-bootstrap-append .input-group-btn .btn, +.select2-bootstrap-prepend .input-group-btn .btn { + vertical-align: top; +} + +.select2-container-multi .select2-choices .select2-search-choice-focus { + background: #ebebeb; + color: #333; + -webkit-box-shadow: none; + box-shadow: none; + border-color: #adadad; +} + +.select2-search-choice-close { + background: none; + margin-top: -8px; + top: 50%; +} + +.select2-search-choice-close:after { + content: 'x'; + font-size: 10px; + color: #fff; + padding: 0 4px; + font-weight: bold; +} + +.select2-container .select2-choice abbr { + top: 50%; +} + +.select2-results .select2-no-results, +.select2-results .select2-searching, +.select2-results .select2-selection-limit { + background-color: #fcf8e3; + color: #c09853; +} + +.select2-container.select2-container-disabled .select2-choice, +.select2-container.select2-container-disabled .select2-choices { + cursor: not-allowed; + background-color: #eee; + border-color: #ccc; +} + +.select2-container.select2-container-disabled .select2-choice .select2-arrow, .select2-container.select2-container-disabled .select2-choice div { + background-color: transparent; + border-left: 1px solid transparent; +} + +.select2-container.select2-container-disabled .select2-choices .select2-arrow, .select2-container.select2-container-disabled .select2-choices div { + background-color: transparent; + border-left: 1px solid transparent; +} + +.select2-search input.select2-active, +.select2-container-multi .select2-choices .select2-search-field input.select2-active, +.select2-more-results.select2-active { + background-position: right 4px center; +} + +html.dark .select2-container .select2-choices .select2-search-field input, +html.dark .select2-container .select2-choice, +html.dark .select2-container .select2-choices { + color: #EEE; + background-color: #282d36; + border-color: #282d36; +} + +html.dark .select2-search { + position: relative; +} + +html.dark .select2-search input { + color: #EEE; + background: #2e353e; + border-color: #242830; +} + +html.dark .select2-search input.select2-active { + background: #2e353e; +} + +html.dark .select2-search:before { + font-family: 'FontAwesome'; + content: "\f002"; + position: absolute; + right: 15px; + top: 50%; + color: #EEE; + font-size: 12px; + margin: -11px 0 0; +} + +html.dark .select2-drop { + background-color: #282d36; + border-color: #21262d; +} + +html.dark .select2-container-multi .select2-choices .select2-search-choice { + color: #EEE; +} + +html.dark .select2-container .select2-choice .select2-arrow, +html.dark .select2-container .select2-choice div { + border-color: #282d36; +} + +html.dark .select2-results .select2-result-label { + color: #EEE; +} + +.panel-body .wizard-tabs { + margin: -15px -15px 15px; +} + +.panel-body-nopadding .wizard-tabs { + margin: 0; +} + +.wizard-tabs ul { + display: table; + width: 100%; + padding: 0; + margin: 0; + list-style: none; +} + +.wizard-tabs ul > li { + display: table-cell; + border-bottom: 1px solid #eeeeee; +} + +.wizard-tabs ul > li.active { + border-bottom-color: transparent; +} + +.wizard-tabs ul > li.active > a, .wizard-tabs ul > li.active > a:hover, .wizard-tabs ul > li.active > a:focus { + background: white; + color: #555555; +} + +.wizard-tabs ul > li.active > a:after { + border-left-color: white; +} + +.wizard-tabs ul > li.active .badge { + background-color: #cccccc; +} + +.wizard-tabs ul > li.disabled > a, .wizard-tabs ul > li.disabled > a:hover, .wizard-tabs ul > li.disabled > a:focus { + color: #cccccc; +} + +.wizard-tabs ul > li.disabled .badge { + background-color: #cccccc; +} + +.wizard-tabs ul > li > a { + position: relative; + display: block; + padding: 5px; + font-size: 13px; + font-size: 1.3rem; + text-decoration: none; + color: #555555; +} + +.wizard-tabs ul > li > a, .wizard-tabs ul > li > a:hover { + background: #f4f4f4; + color: #555555; +} + +.wizard-tabs ul > li > a:hover { + box-shadow: none; +} + +.wizard-tabs ul > li > a:active, .wizard-tabs ul > li > a:focus { + border-bottom: 0; +} + +.wizard-tabs ul > li > a:before, .wizard-tabs ul > li > a:after { + display: block; + content: ''; + position: absolute; + top: 0; + right: -10px; + z-index: 1; + border: 17px solid transparent; + border-right: 0; + border-left: 10px solid transparent; + width: 0; + height: 0; +} + +.wizard-tabs ul > li > a:before { + z-index: 1; + right: -11px; + border-left-color: #e0e0e0; +} + +.wizard-tabs ul > li > a:after { + z-index: 2; + border-left-color: #f4f4f4; +} + +.wizard-tabs ul > li:last-child > a:before, .wizard-tabs ul > li:last-child > a:after { + display: none; +} + +html.dark .wizard-tabs ul > li { + border-color: #282d36; +} + +html.dark .wizard-tabs ul > li.active { + border-color: #2e353e; +} + +html.dark .wizard-tabs ul > li.active a, html.dark .wizard-tabs ul > li.active a:hover, html.dark .wizard-tabs ul > li.active a:active { + background: #2e353e; + color: #EEE; +} + +html.dark .wizard-tabs ul > li.active a:before { + border-left-color: #21262d; +} + +html.dark .wizard-tabs ul > li.active a:after { + border-left-color: #2e353e; +} + +html.dark .wizard-tabs ul > li a, html.dark .wizard-tabs ul > li a:hover { + background: #282d36; + color: #EEE; +} + +html.dark .wizard-tabs ul > li a:before { + border-left-color: #21262d; +} + +html.dark .wizard-tabs ul > li a:after { + border-left-color: #282d36; +} + +html .wizard-progress, +html.dark .wizard-progress { + margin: 0 15px; +} + +html .wizard-progress .steps-progress, +html.dark .wizard-progress .steps-progress { + height: 2px; + margin: 0 38px; + position: relative; + top: 15px; + background: #cccccc; +} + +html .wizard-progress .steps-progress .progress-indicator, +html.dark .wizard-progress .steps-progress .progress-indicator { + height: 100%; + width: 0; + background: #cccccc; + -webkit-transition: width 0.2s ease-in; + -moz-transition: width 0.2s ease-in; + transition: width 0.2s ease-in; +} + +html .wizard-progress .wizard-steps, +html.dark .wizard-progress .wizard-steps { + list-style: none; + margin: 0; + padding: 15px 0 0; + display: inline-block; + width: 100%; + font-size: 0; + text-align: justify; + -ms-text-justify: distribute-all-lines; + /* IE8+ */; +} + +html .wizard-progress .wizard-steps:after, +html.dark .wizard-progress .wizard-steps:after { + /* + * We don't need IE6 and IE7 inline-block hack support here + * since they don't support :after anyways (the text-justify + * properties for them are above)... IE8 and above have native + * inline-block support so for IE8+, both the text-justify and + * :after will take effect but it doesn't have any negative + * effects since this element is invisible + */ + display: inline-block; + width: 100%; + content: '.'; + font-size: 0; + height: 0; + line-height: 0; + visibility: hidden; +} +html .wizard-progress .wizard-steps li, +html.dark .wizard-progress .wizard-steps li { + display: inline-block; + vertical-align: top; + min-width: 50px; + max-width: 100px; +} +html .wizard-progress .wizard-steps li a, +html.dark .wizard-progress .wizard-steps li a { + position: relative; + display: block; + padding: 25px 8px 0; + font-size: 11px; + color: #33333f; + font-weight: bold; + line-height: 1; + text-align: center; + text-decoration: none; + word-break: break-all; +} +html .wizard-progress .wizard-steps li a span, +html.dark .wizard-progress .wizard-steps li a span { + position: absolute; + top: 0; + left: 50%; + display: block; + background: #cccccc; + color: white; + line-height: 26px; + text-align: center; + margin-top: -15px; + margin-left: -15px; + width: 30px; + height: 30px; + border-radius: 35px; + font-size: 13px; + text-indent: -1px; + border: 2px solid #cccccc; + -webkit-transition: all 0.2s ease-in; + -moz-transition: all 0.2s ease-in; + transition: all 0.2s ease-in; +} +html .wizard-progress .wizard-steps li.completed a span, +html.dark .wizard-progress .wizard-steps li.completed a span { + background: #cccccc; + color: white; +} +html .wizard-progress .wizard-steps li.active a span, +html.dark .wizard-progress .wizard-steps li.active a span { + background: white; + color: #cccccc; + border-color: #cccccc; +} +html .wizard-progress .wizard-steps li.completed.active a span, +html.dark .wizard-progress .wizard-steps li.completed.active a span { + color: #FFF; +} +html .wizard-progress.wizard-progress-lg, +html.dark .wizard-progress.wizard-progress-lg { + margin: 0 auto 30px; + width: 80%; +} +html .wizard-progress.wizard-progress-lg .steps-progress, +html.dark .wizard-progress.wizard-progress-lg .steps-progress { + margin: 0 52px; + height: 4px; + top: 34px; +} +html .wizard-progress.wizard-progress-lg .wizard-steps, +html.dark .wizard-progress.wizard-progress-lg .wizard-steps { + padding-top: 30px; +} +html .wizard-progress.wizard-progress-lg ul li, +html.dark .wizard-progress.wizard-progress-lg ul li { + max-width: 135px; +} +html .wizard-progress.wizard-progress-lg ul li a, +html.dark .wizard-progress.wizard-progress-lg ul li a { + padding-top: 40px; + font-size: 14px; +} +html .wizard-progress.wizard-progress-lg ul li a span, +html.dark .wizard-progress.wizard-progress-lg ul li a span { + width: 60px; + height: 60px; + margin-top: -30px; + margin-left: -30px; + border-radius: 60px; + line-height: 52px; + font-size: 22px; + border-width: 4px; +} + +html.dark .wizard-progress .wizard-steps li a { + color: #808697; +} +html.dark .wizard-progress.wizard-progress ul li a span { + background: #242830; + border-color: #242830; +} +html.dark .wizard-progress .wizard-steps li.active a span { + background: #242830; +} +html.dark .wizard-progress .steps-progress { + background: #242830; +} + +@media only screen and (max-width: 991px) { + html .wizard-progress, html .wizard-progress.wizard-progress-lg, html.dark .wizard-progress, html.dark .wizard-progress.wizard-progress-lg { + width: auto; + margin-bottom: 0; + margin-left: -15px; + margin-right: -15px; + } + html .wizard-progress .steps-progress, html.dark .wizard-progress .steps-progress { + display: none; + } + html .wizard-progress .wizard-steps, html.dark .wizard-progress .wizard-steps { + display: block; + font-size: 0; + overflow: hidden; + white-space: nowrap; + text-align: left; + width: 100%; + } + html .wizard-progress .wizard-steps li, html.dark .wizard-progress .wizard-steps li { + -webkit-transition: margin 0.5s linear; + -moz-transition: margin 0.5s linear; + transition: margin 0.5s linear; + display: inline-block; + float: none; + position: relative; + width: 100%; + min-width: 0; + max-width: none; + } + html .wizard-progress .wizard-steps li a, html.dark .wizard-progress .wizard-steps li a { + position: relative; + z-index: 2; + } + html .wizard-progress .wizard-steps li:before, html .wizard-progress .wizard-steps li:after, html.dark .wizard-progress .wizard-steps li:before, html.dark .wizard-progress .wizard-steps li:after { + content: ''; + display: block; + height: 2px; + position: absolute; + top: 0; + width: 50%; + } + html .wizard-progress .wizard-steps li:before, html.dark .wizard-progress .wizard-steps li:before { + background: #cccccc; + left: 0; + } + html .wizard-progress .wizard-steps li:after, html.dark .wizard-progress .wizard-steps li:after { + background: #cccccc; + right: 0; + } + html .wizard-progress .wizard-steps li.active, html.dark .wizard-progress .wizard-steps li.active { + margin-left: 0; + } + html .wizard-progress .wizard-steps li.completed, html.dark .wizard-progress .wizard-steps li.completed { + margin-left: -100%; + } + html .wizard-progress .wizard-steps li.completed:after, html.dark .wizard-progress .wizard-steps li.completed:after { + background: #cccccc; + } + html .wizard-progress .wizard-steps li.completed.active, html.dark .wizard-progress .wizard-steps li.completed.active { + margin-left: 0; + } + html .wizard-progress .wizard-steps li:first-child:before, html.dark .wizard-progress .wizard-steps li:first-child:before { + display: none; + } + html .wizard-progress .wizard-steps li:last-child:after, html.dark .wizard-progress .wizard-steps li:last-child:after { + display: none; + } + html .wizard-progress.wizard-progress-lg .wizard-steps li, html.dark .wizard-progress.wizard-progress-lg .wizard-steps li { + min-width: 0; + max-width: none; + } + html .wizard-progress.wizard-progress-lg .wizard-steps li:before, html .wizard-progress.wizard-progress-lg .wizard-steps li:after, html.dark .wizard-progress.wizard-progress-lg .wizard-steps li:before, html.dark .wizard-progress.wizard-progress-lg .wizard-steps li:after { + height: 4px; + } +} +.form-wizard { + margin-bottom: 20px; +} +.form-wizard .tabs { + margin-bottom: 0; +} +.form-wizard .tab-content { + background: white; + border: 0 none; + box-shadow: none; +} +.form-wizard ul.pager .next a, +.form-wizard ul.pager .previous a, +.form-wizard ul.pager .first a, +.form-wizard ul.pager .last a, +.form-wizard ul.pager .finish a { + cursor: pointer; +} +.form-wizard ul.pager .disabled a { + cursor: not-allowed; +} + +html.dark .form-wizard .pager li > a, +html.dark .form-wizard .pager li > a:hover, +html.dark .form-wizard .pager li > a:focus, +html.dark .form-wizard .pager li > span { + background: #2e353e; + border-color: #282d36; + color: #EEE; +} +html.dark .form-wizard .pager .disabled > a, html.dark .form-wizard .pager .disabled > a:hover, html.dark .form-wizard .pager .disabled > a:focus, html.dark .form-wizard .pager .disabled > span { + background: #282d36; + border-color: #282d36; + color: #EEE; +} + +.switch { + display: inline-block; + vertical-align: middle; + cursor: pointer; + margin: 3px 0; +} +.switch .ios-switch { + height: 35px; + width: 65px; +} +.switch .ios-switch .handle { + height: 31px; + width: 31px; +} +.switch.switch-primary .ios-switch .on-background { + background: #cccccc; +} +.switch.switch-success .ios-switch .on-background { + background: #47a447; +} +.switch.switch-warning .ios-switch .on-background { + background: #ed9c28; +} +.switch.switch-danger .ios-switch .on-background { + background: #d2322d; +} +.switch.switch-info .ios-switch .on-background { + background: #5bc0de; +} +.switch.switch-dark .ios-switch .on-background { + background: #171717; +} +.switch.switch-lg .ios-switch { + height: 45px; + width: 75px; +} +.switch.switch-lg .ios-switch .handle { + height: 41px; + width: 41px; +} +.switch.switch-sm .ios-switch { + height: 25px; + width: 55px; +} +.switch.switch-sm .ios-switch .handle { + height: 21px; + width: 21px; +} + +.ios-switch { + height: 45px; + width: 75px; + position: relative; + background-color: #E5E5E5; + border-radius: 100px; + -webkit-backface-visibility: hidden; + -moz-backface-visibility: hidden; + backface-visibility: hidden; +} + +.ios-switch .background-fill { + width: 100%; + height: 100%; + border-radius: 100px; + position: absolute; + left: 0; + top: 0; +} + +.ios-switch .on-background { + background-image: -o-linear-gradient(#00e459, #00e158); + background-image: -ms-linear-gradient(#00e459, #00e158); + background-image: -moz-linear-gradient(#00e459, #00e158); + background-image: -webkit-linear-gradient(#00e459, #00e158); + background-image: linear-gradient(#00e459, #00e158); + opacity: 0; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0); + filter: alpha(opacity=0); + z-index: 1; + -o-transition: .3s 0.2s; + -ms-transition: .3s 0.2s; + -moz-transition: .3s 0.2s; + -webkit-transition: .3s 0.2s; + transition: .3s 0.2s; +} + +.ios-switch .state-background { + border-radius: 100px; + z-index: 2; + background-image: -o-linear-gradient(white, #fdfdfd); + background-image: -ms-linear-gradient(white, #fdfdfd); + background-image: -moz-linear-gradient(white, #fdfdfd); + background-image: -webkit-linear-gradient(white, #fdfdfd); + background-image: linear-gradient(white, #fdfdfd); + border: 2px solid #E5E5E5; + -o-box-sizing: border-box; + -ms-box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + -o-transform: scale(1); + -ms-transform: scale(1); + -moz-transform: scale(1); + -webkit-transform: scale(1); + transform: scale(1); + -o-transition: .4s; + -ms-transition: .4s; + -moz-transition: .4s; + -webkit-transition: .4s; + transition: .4s; +} + +.ios-switch .handle { + width: 41px; + height: 41px; + background-color: white; + top: 2px; + left: 2px; + position: absolute; + border-radius: 20px; + box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.075), 0 3px 5px rgba(0, 0, 0, 0.15), 1px 2px 2px rgba(0, 0, 0, 0.05); + z-index: 3; + -o-transition: -o-transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + -ms-transition: -ms-transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + -moz-transition: -moz-transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + -webkit-transition: -webkit-transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + -o-transition: transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + -ms-transition: transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + -moz-transition: transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + -webkit-transition: transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + transition: transform 0.3s 0.25s cubic-bezier(0.455, 0.03, 0.215, 1.33); + -o-box-sizing: content-box; + -ms-box-sizing: content-box; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} + +.ios-switch.off .handle { + -o-animation: expand-off .3s 0.2s; + -ms-animation: expand-off .3s 0.2s; + -moz-animation: expand-off .3s 0.2s; + -webkit-animation: expand-off .3s 0.2s; + animation: expand-off .3s 0.2s; + -o-transform: translate(0px, 0); + -ms-transform: translate(0px, 0); + -moz-transform: translate(0px, 0); + -webkit-transform: translate(0px, 0); + transform: translate(0px, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -webkit-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); +} + +.ios-switch.off .on-background { + -o-transition: .3s 0s; + -ms-transition: .3s 0s; + -moz-transition: .3s 0s; + -webkit-transition: .3s 0s; + transition: .3s 0s; +} + +.ios-switch.off .state-background { + -o-transition: .4s 0.25s; + -ms-transition: .4s 0.25s; + -moz-transition: .4s 0.25s; + -webkit-transition: .4s 0.25s; + transition: .4s 0.25s; +} + +.ios-switch.on .handle { + -o-animation: expand-on .3s 0.2s; + -ms-animation: expand-on .3s 0.2s; + -moz-animation: expand-on .3s 0.2s; + -webkit-animation: expand-on .3s 0.2s; + animation: expand-on .3s 0.2s; + -o-transform: translate(30px, 0); + -ms-transform: translate(30px, 0); + -moz-transform: translate(30px, 0); + -webkit-transform: translate(30px, 0); + transform: translate(30px, 0); + -o-transform: translate3d(30px, 0, 0); + -ms-transform: translate3d(30px, 0, 0); + -moz-transform: translate3d(30px, 0, 0); + -webkit-transform: translate3d(30px, 0, 0); + transform: translate3d(30px, 0, 0); +} + +.ios-switch.on .on-background { + opacity: 1; + -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100); + filter: alpha(opacity=100); +} + +.ios-switch.on .state-background { + -o-transform: scale(0); + -ms-transform: scale(0); + -moz-transform: scale(0); + -webkit-transform: scale(0); + transform: scale(0); +} + +@keyframes expand-on { + 0% { + padding-right: 0; + } + + 40% { + padding-right: 9px; + } + + 100% { + padding-right: 0; + } +} +@keyframes expand-off { + 0% { + padding-right: 0; + left: 2px; + } + + 40% { + padding-right: 9px; + left: -7px; + } + + 100% { + padding-right: 0; + left: 2px; + } +} +@-o-keyframes expand-on { + 0% { + padding-right: 0; + } + + 40% { + padding-right: 9px; + } + + 100% { + padding-right: 0; + } +} +@-ms-keyframes expand-on { + 0% { + padding-right: 0; + } + + 40% { + padding-right: 9px; + } + + 100% { + padding-right: 0; + } +} +@-moz-keyframes expand-on { + 0% { + padding-right: 0; + } + + 40% { + padding-right: 9px; + } + + 100% { + padding-right: 0; + } +} +@-webkit-keyframes expand-on { + 0% { + padding-right: 0; + } + + 40% { + padding-right: 9px; + } + + 100% { + padding-right: 0; + } +} +@-o-keyframes expand-off { + 0% { + padding-right: 0; + left: 2px; + } + + 40% { + padding-right: 9px; + left: -7px; + } + + 100% { + padding-right: 0; + left: 2px; + } +} +@-ms-keyframes expand-off { + 0% { + padding-right: 0; + left: 2px; + } + + 40% { + padding-right: 9px; + left: -7px; + } + + 100% { + padding-right: 0; + left: 2px; + } +} +@-moz-keyframes expand-off { + 0% { + padding-right: 0; + left: 2px; + } + + 40% { + padding-right: 9px; + left: -7px; + } + + 100% { + padding-right: 0; + left: 2px; + } +} +@-webkit-keyframes expand-off { + 0% { + padding-right: 0; + left: 2px; + } + + 40% { + padding-right: 9px; + left: -7px; + } + + 100% { + padding-right: 0; + left: 2px; + } +} +/* Summernote */ +.note-editor { + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + -moz-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} +.note-editor.active { + border-color: #66afe9; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.note-editor .note-title { + padding-top: 0 !important; +} +.note-editor .note-toolbar { + background-color: #FFF; + border-bottom: 1px dashed #ddd; + border-left: none; + border-right: none; + border-top: none; + border-radius: 4px 4px 0 0; + padding: 6px 4px 0; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.note-editor .note-toolbar i { + margin: 0; +} +.note-editor .note-toolbar i:before { + margin: 0; +} +.note-editor .note-toolbar .btn-group { + float: none !important; + margin: 0 0 6px 5px; +} +@media only screen and (max-width: 767px) { + .note-editor .note-toolbar { + text-align: center; + } +} +.note-editor .note-editable { + clear: both; + background: #FFF; + border: none; + border-radius: 0 0 4px 4px; + font-family: Arial, Helvetica, Sans-serif; +} +.note-editor .note-statusbar { + background: #FFF; + border-radius: 0 0 4px 4px; +} +.note-editor .note-statusbar .note-resizebar { + border-color: #DDD; + display: block; +} + +html.dark .note-editor { + border-color: #282d36; + color: #EEE; +} +html.dark .note-editor .note-toolbar, +html.dark .note-editor .note-statusbar { + background: #242830; + border-color: #1d2127; +} +html.dark .note-editor .note-editable { + background: #282d36; + border-color: #1d2127; +} +html.dark .note-editor .note-statusbar .note-resizebar { + border-color: #1d2127; +} +html.dark .note-editor .note-statusbar .note-resizebar .note-icon-bar { + border-color: #444; +} +html.dark .note-editor .caret { + border-color: #FFF transparent transparent; +} + +/* Bootstrap Markdown */ +.md-editor { + border-radius: 4px; + -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + -moz-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; + transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; +} +.md-editor > .md-header { + border-radius: 4px 4px 0 0; + padding: 6px 4px 0; +} +.md-editor > .md-preview, +.md-editor > textarea { + background: #FFF; + border-bottom: none; + border-radius: 0 0 4px 4px; + padding: 10px; + outline: none; + width: 100% !important; +} +.md-editor .btn-group { + margin-bottom: 6px; +} + +html.dark .md-editor { + border-color: #282d36; +} +html.dark .md-editor > .md-header, +html.dark .md-editor .md-footer { + background: #242830; +} +html.dark .md-editor > .md-preview, +html.dark .md-editor > textarea { + background: #282d36; +} +html.dark .md-editor > textarea { + color: #EEE; + border-color: #1d2127; +} + +@media only screen and (max-width: 767px) { + .bootstrap-maxlength.bottom-left { + margin-left: 40px; + } +} +.bootstrap-tagsinput { + width: 100%; +} + +.form-group-invisible .bootstrap-tagsinput { + border: 0 none; + box-shadow: none; + background-color: transparent; +} + +html.dark .bootstrap-tagsinput { + background: #282d36; + border-color: #282d36; +} + +html.dark .bootstrap-timepicker-widget { + background-color: #282d36; +} +html.dark .bootstrap-timepicker-widget:before { + border-bottom-color: #1d2127; +} +html.dark .bootstrap-timepicker-widget:after { + border-bottom-color: #282d36; +} +html.dark .bootstrap-timepicker-widget.timepicker-orient-bottom:before { + border-top-color: #1d2127; +} +html.dark .bootstrap-timepicker-widget.timepicker-orient-bottom:after { + border-top-color: #282d36; +} +html.dark .bootstrap-timepicker-widget table td a { + color: #FFF; +} +html.dark .bootstrap-timepicker-widget table td a:hover { + border-color: #282d36; +} +html.dark .bootstrap-timepicker-widget table td input { + background-color: #21262d; + border-color: #282d36; + color: #EEE; +} + +html.dark .colorpicker { + background-color: #282d36; +} +html.dark .colorpicker:before { + border-bottom-color: #1d2127; +} +html.dark .colorpicker:after { + border-bottom-color: #282d36; +} + +html.dark .multiselect-container { + background-color: #282d36; +} +html.dark .multiselect-container > li > a { + color: #EEE; +} +html.dark .multiselect-container > li > a:hover, html.dark .multiselect-container > li > a:focus { + background-color: #1d2127; + color: #FFF; +} + +.spinner-buttons.btn-group-vertical .btn { + height: 18px; + margin: 0 0 0 -1px; + padding-left: 6px; + padding-right: 6px; + text-align: center; + width: 22px; + line-height: 14px; +} +.spinner-buttons.btn-group-vertical .btn i { + margin-top: -2px; +} +.spinner-buttons.btn-group-vertical .btn:first-child { + border-radius: 0 4px 0 0 !important; + -webkit-border-radius: 0 4px 0 0 !important; +} +.spinner-buttons.btn-group-vertical .btn:last-child { + border-radius: 0 0 4px !important; + -webkit-border-radius: 0 0 4px !important; + margin-top: -1px; + height: 17px; +} + +/* Form Group Invisible */ +.form-group-invisible { + position: relative; +} +.form-group-invisible.focus .control-label-invisible { + color: #0088cc; +} +.form-group-invisible .control-label-invisible { + bottom: 0; + display: block; + float: none; + left: 0; + line-height: 64px; + margin: 0; + padding-left: 50px; + position: absolute; + right: 0; + top: -15px; + -webkit-transition: color ease-in-out 0.15s; + -moz-transition: color ease-in-out 0.15s; + transition: color ease-in-out 0.15s; + width: auto; +} +.form-group-invisible .form-control-invisible, .form-group-invisible .form-control-invisible:focus, .form-group-invisible .form-control-invisible:active, .form-group-invisible .form-control-invisible + .bootstrap-tagsinput { + background: transparent !important; + border-color: transparent !important; + box-shadow: none !important; +} +.form-group-invisible .form-control-invisible + .bootstrap-tagsinput { + margin-bottom: 4px; +} + +@media only screen and (max-width: 767px) { + .form-group-invisible { + padding-top: 30px; + } + .form-group-invisible .control-label-invisible { + padding-left: 27px; + } +} +html.dark .CodeMirror pre { + background: transparent; + border: none; +} + +@media only screen and (max-width: 767px) { + #gmap { + margin: -40px -15px 0 -15px; + } + + html.mobile-device #gmap { + min-height: 100px; + } +} +@media only screen and (min-width: 768px) { + #gmap { + bottom: 0; + height: auto !important; + left: 0; + position: absolute !important; + right: 0; + top: 0; + min-height: 0; + } +} +/* List Containing Markers */ +.list-markers { + border-bottom: 1px solid #21262d; + padding-bottom: 10px; +} +.list-markers li { + position: relative; +} +.list-markers p { + margin: 0 0 2px 0; + padding: 3px 55px 3px 0; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + width: 100%; +} +.list-markers .location-action { + position: absolute; + right: 0; + top: 2px; +} +.list-markers .location-action.location-edit { + right: 15px; + top: 3px; +} +.list-markers .location-action.location-center { + right: 37px; +} + +/* Modal Add/Edit Markers */ +.marker-modal .modal-dialog { + max-width: 450px; +} + +.jqvmap-zoomin, +.jqvmap-zoomout { + background: #cccccc; + border-radius: 2px; + color: white; + height: 20px; + line-height: 20px; + padding: 0; + width: 20px; + text-align: center; +} +.jqvmap-zoomin:hover, +.jqvmap-zoomout:hover { + background: #bfbfbf; +} + +.jqvmap-zoomout { + top: 35px; +} + +.mailbox .content-with-menu-container { + background: #FFF; +} +.mailbox .mailbox-bullets .ball { + border: 5px solid red; + border-radius: 100px; + display: block; + float: right; + margin-top: 6px; +} +.mailbox .mailbox-bullets .ball.pink { + border-color: #EA4C89; +} +.mailbox .mailbox-bullets .ball.green { + border-color: #9AE14F; +} +.mailbox .mailbox-bullets .ball.blue { + border-color: #1BC3E1; +} +.mailbox .mailbox-bullets .ball.orange { + border-color: #E2A917; +} + +.mailbox .mailbox-folder { + height: auto !important; + padding: 0 0 40px; +} + +/* mailbox - main header */ +.mailbox .mailbox-folder .mailbox-header { + padding: 38px 40px 43px; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-folder .mailbox-header { + padding: 20px; + } +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-folder .mailbox-header .mailbox-title { + margin-bottom: 10px !important; + } +} +.mailbox .mailbox-folder .mailbox-header .search { + float: right; + margin-top: 3px; + max-width: 100px; +} +.mailbox .mailbox-folder .mailbox-header .search input[type="text"] { + -webkit-transition-property: width, margin; + -moz-transition-property: width, margin; + transition-property: width, margin; + -webkit-transition-duration: 0.3s; + -moz-transition-duration: 0.3s; + transition-duration: 0.3s; + -webkit-transition-timing-function: cubic-bezier(0.05, 0.91, 0.25, 0.99); + -moz-transition-timing-function: cubic-bezier(0.05, 0.91, 0.25, 0.99); + transition-timing-function: cubic-bezier(0.05, 0.91, 0.25, 0.99); +} +.mailbox .mailbox-folder .mailbox-header .search input[type="text"]:focus { + margin-left: -150%; + width: 250%; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-folder .mailbox-header .search input[type="text"]:focus { + margin-left: 0; + width: 100%; + } +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-folder .mailbox-header .search { + max-width: none; + } +} + +/* mailbox - actions */ +.mailbox .mailbox-actions { + border-top: 1px solid #efefef; + padding-left: 40px; + padding-right: 40px; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-actions { + padding-left: 20px; + padding-right: 20px; + text-align: center; + } +} +.mailbox .mailbox-actions ul a.item-action { + background: #FFF; + border-radius: 100px; + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.2); + color: #B4BBC1; + display: inline-block; + font-size: 14px; + font-size: 1.4rem; + height: 30px; + line-height: 30px; + line-height: 3rem; + position: relative; + width: 30px; + text-align: center; + -webkit-transition-property: color; + -moz-transition-property: color; + transition-property: color; + -webkit-transition-duration: 0.3s; + -moz-transition-duration: 0.3s; + transition-duration: 0.3s; + -webkit-transition-timing-function: cubic-bezier(0.2, 0.6, 0.25, 1); + -moz-transition-timing-function: cubic-bezier(0.2, 0.6, 0.25, 1); + transition-timing-function: cubic-bezier(0.2, 0.6, 0.25, 1); + -webkit-transition-delay: 0.1s; + -moz-transition-delay: 0.1s; + transition-delay: 0.1s; +} +.mailbox .mailbox-actions ul a.item-action:hover { + color: #57636C; + text-decoration: none; +} +.mailbox .mailbox-actions ul a.item-action.text-primary:hover { + color: #b3b3b3 !important; +} +.mailbox .mailbox-actions ul a.item-action.text-success:hover { + color: #388038 !important; +} +.mailbox .mailbox-actions ul a.item-action.text-warning:hover { + color: #d18211 !important; +} +.mailbox .mailbox-actions ul a.item-action.text-danger:hover { + color: #a82824 !important; +} +.mailbox .mailbox-actions ul a.item-action.text-info:hover { + color: #31b0d5 !important; +} +.mailbox .mailbox-actions ul a.item-action.text-dark:hover { + color: black !important; +} + +/* mailbox - mail list */ +.mailbox .mailbox-email-list { + border-top: 1px solid #f7f7f7; + font-size: 15px; + font-size: 1.5rem; + font-weight: 300; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list { + position: static !important; + } +} +.mailbox .mailbox-email-list li { + border-bottom: 1px solid #f7f7f7; + height: 50px; + line-height: 50px; + padding: 0 40px; + position: relative; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list li { + height: 75px; + padding: 0 20px; + } +} +.mailbox .mailbox-email-list li a { + color: #777; +} +.mailbox .mailbox-email-list li:hover { + background: #FAFAFA; +} +.mailbox .mailbox-email-list li.unread a { + color: #555; + font-weight: 500; +} +.mailbox .mailbox-email-list li.active { + background: #cccccc; +} +.mailbox .mailbox-email-list li.active a { + color: white; +} +.mailbox .mailbox-email-list .mail-label { + border: 4px solid transparent; + border-radius: 10px; + display: inline-block; + left: 16px; + position: absolute; + top: 21px; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list .mail-label { + border-radius: 0; + border-width: 1px; + bottom: 0; + left: 0; + top: 0; + } +} +.mailbox .mailbox-email-list .col-sender { + float: left; + overflow: hidden; + text-overflow: ellipsis; + width: 250px; + white-space: nowrap; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list .col-sender { + width: 100%; + } +} +.mailbox .mailbox-email-list .col-sender p { + left: 80px; + overflow: hidden; + position: absolute; + right: 0; + text-overflow: ellipsis; + top: 0; + white-space: nowrap; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list .col-sender p { + left: 60px; + } +} +.mailbox .mailbox-email-list .col-mail { + bottom: 0; + left: 290px; + position: absolute; + right: 40px; + top: 0; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list .col-mail { + left: 60px; + right: 20px; + } +} +.mailbox .mailbox-email-list .col-mail .mail-content, +.mailbox .mailbox-email-list .col-mail .mail-date, +.mailbox .mailbox-email-list .col-mail .mail-attachment { + position: absolute; + top: 0; +} +.mailbox .mailbox-email-list .col-mail .mail-content { + left: 0; + right: 140px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list .col-mail .mail-content { + right: 0; + top: 25px; + } +} +.mailbox .mailbox-email-list .col-mail .mail-attachment { + color: #BBB; + right: 100px; + line-height: 50px; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list .col-mail .mail-attachment { + font-size: 11px; + font-size: 1.1rem; + line-height: 14px; + line-height: 1.4rem; + right: 55px; + top: 6px; + } +} +.mailbox .mailbox-email-list .col-mail .mail-date { + padding-left: 80px; + right: 0; + width: 150px; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list .col-mail .mail-date { + font-size: 10px; + font-size: 1rem; + line-height: 14px; + line-height: 1.4rem; + padding-left: 0; + text-align: right; + top: 5px; + width: 130px; + } +} + +/* Mailbox Mail List - Unstyle nano for non fixed layouts and responsive */ +html.scroll .mailbox .mailbox-email-list .nano, +html.boxed .mailbox .mailbox-email-list .nano { + position: static; + height: auto; + overflow: visible; + width: auto; +} +html.scroll .mailbox .mailbox-email-list .nano .nano-content, +html.boxed .mailbox .mailbox-email-list .nano .nano-content { + position: static; + overflow: visible; +} + +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email-list .nano { + position: static; + height: auto; + overflow: visible; + width: auto; + } + .mailbox .mailbox-email-list .nano .nano-content { + position: static; + overflow: visible; + } +} +/* Mailbox Mail List + Fixed Layout */ +@media only screen and (min-width: 768px) { + html.fixed .mailbox .mailbox-email-list { + bottom: 0; + left: 0; + position: absolute; + right: 0; + overflow: hidden; + top: 191px; + } +} +/* Mailbox - Email */ +.mailbox .mailbox-email { + background: #FAFAFA; +} +.mailbox .mailbox-email .mailbox-email-header { + background: #FFF; + box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.2); + margin: -40px -40px 0 -40px; + padding: 30px; +} +@media only screen and (max-width: 767px) { + .mailbox .mailbox-email .mailbox-email-header { + margin-left: -15px; + margin-right: -15px; + } +} +.mailbox .mailbox-email .mailbox-close-mail { + color: #cccccc; + cursor: pointer; + font-weight: 300; + float: left; +} +.mailbox .mailbox-email .mailbox-close-mail:hover { + color: #d9d9d9; +} +.mailbox .mailbox-email .mailbox-close-mail, .mailbox .mailbox-email .mailbox-close-mail:focus { + text-decoration: none; +} +.mailbox .mailbox-email .panel .panel-heading { + background: #FFF; + border-bottom-color: #EFEFEF; +} +.mailbox .mailbox-email .panel .panel-heading .panel-actions { + top: 17px; +} +.mailbox .mailbox-email .panel .panel-heading .panel-actions a:hover { + background: #FFF; + color: #cccccc; +} +.mailbox .mailbox-email .panel .panel-footer { + background: #FFF; + border-top-color: #EFEFEF; + color: #BBB; +} + +/* Mailbox - Showing Menu Toggle */ +@media only screen and (min-width: 768px) and (max-width: 1365px) { + .mailbox .mailbox-folder .mailbox-header .mailbox-title { + position: relative; + top: 28px; + } + + .mailbox .mailbox-email .mailbox-email-header { + padding-top: 80px; + } + + html.inner-menu-opened .mailbox .mailbox-folder .mailbox-header .mailbox-title { + position: static; + } + html.inner-menu-opened .mailbox .mailbox-email .mailbox-email-header { + padding-top: 30px; + } +} +/* Mailbox Compose */ +.mailbox-compose { + margin: -20px -40px 0 -40px; + padding: 0 15px; +} +.mailbox-compose .compose { + margin: 0 40px; +} +.mailbox-compose .compose .note-editable { + min-height: 250px; +} +.mailbox-compose .compose .note-editor, +.mailbox-compose .compose .note-toolbar { + border: none; +} +.mailbox-compose .compose .note-resizebar { + display: none; +} + +@media only screen and (max-width: 767px) { + .mailbox-compose { + margin: -20px -15px 0 -15px; + } + .mailbox-compose .compose { + margin-left: 5px; + margin-right: 5px; + } +} +/* dark */ +html.dark .mailbox .mailbox-email, +html.dark .mailbox .content-with-menu-container { + background: #1d2127; +} +html.dark .mailbox .mailbox-folder .mailbox-header .input-search .btn-default { + background: transparent; +} +html.dark .mailbox .mailbox-actions { + border-top-color: #282d36; +} +html.dark .mailbox .mailbox-actions ul a.item-action { + background: #2e353e; +} +html.dark .mailbox .mailbox-email-list { + border-top-color: #282d36; +} +html.dark .mailbox .mailbox-email-list li { + border-bottom-color: #242830; +} +html.dark .mailbox .mailbox-email-list li:hover { + background: #161a1e; +} +html.dark .mailbox .mailbox-email-list li a { + color: #808697; +} +html.dark .mailbox .mailbox-email-list li.unread a { + color: #9ca1ae; +} +html.dark .mailbox .mailbox-email .mailbox-email-header { + background: #21262d; +} +html.dark .mailbox .mailbox-email .panel .panel-heading, +html.dark .mailbox .mailbox-email .panel .panel-footer { + background-color: #282d36; + border-color: #21262d; + color: #808697; +} +html.dark .mailbox .mailbox-email .panel .panel-heading .panel-title, +html.dark .mailbox .mailbox-email .panel .panel-footer .panel-title { + color: #808697; +} +html.dark .mailbox .mailbox-email .panel .panel-heading .panel-actions a:hover { + background: #1d2127; +} +html.dark .mailbox .mailbox-compose .note-editor .note-toolbar, +html.dark .mailbox .mailbox-compose .note-editor .note-statusbar, +html.dark .mailbox .mailbox-compose .note-editor .note-editable { + background: #1d2127; +} +html.dark .mailbox .mailbox-compose .note-editor .note-editable { + color: #808697; +} + +/* Invoice */ +.invoice { + padding: 0 15px 15px; +} + +/* Invoice Address Tag */ +.invoice address { + color: #7F8597; + line-height: 1.5em; +} + +/* Invoice header */ +.invoice header { + border-bottom: 1px solid #DADADA; + margin-bottom: 15px; +} +.invoice header .h2, +.invoice header .h4 { + letter-spacing: 0; +} + +/* Invoice Billing Information */ +.invoice .bill-to, +.invoice .bill-data { + padding: 15px 0; +} +.invoice .bill-data .value { + display: inline-block; + margin-left: 10px; + width: 90px; +} + +/* Invoice table */ +.invoice table.table { + table-layout: fixed; +} +.invoice table.table > thead:first-child > tr > th { + background-color: #F8F8F8; + border-bottom: 1px solid #DADADA; + border-top: 1px solid #DADADA; +} +.invoice table.table > tbody tr > td { + border-color: #DADADA; +} + +/* Invoice table items */ +.invoice .invoice-items > tbody tr:last-child > td { + border-bottom: 1px solid #DADADA; +} +.invoice .invoice-items #cell-id { + width: 10%; +} +.invoice .invoice-items #cell-item { + width: 20%; +} +.invoice .invoice-items #cell-desc { + width: 20%; +} +.invoice .invoice-items #cell-price { + width: 10%; +} +.invoice .invoice-items #cell-qty { + width: 10%; +} +.invoice .invoice-items #cell-total { + width: 10%; +} + +/* Invoice summary */ +.invoice-summary .col-sm-4 { + padding-left: 0; +} + +/* Invoice Responsiveness */ +@media only screen and (max-width: 991px) { + .invoice .table-responsive > table.table { + table-layout: auto; + } + + .invoice-summary .col-sm-4 { + padding-left: 15px; + } +} +/* Invoice Print */ +@media print { + .invoice .table-responsive { + border: none !important; + overflow: visible !important; + width: auto !important; + } + .invoice table.table.invoice-items { + table-layout: auto; + } + .invoice header .col-sm-6:first-child, + .invoice header .col-sm-6:last-child, + .invoice .bill-info .col-md-6 { + float: left !important; + } + .invoice header .col-sm-6:first-child { + width: 25% !important; + } + .invoice header .col-sm-6:last-child { + width: 75% !important; + } + .invoice .bill-info .col-md-6 { + width: 50% !important; + } + .invoice .invoice-summary .col-sm-4 { + float: right; + padding: 0; + width: 40%; + } +} +/* dark */ +html.dark .invoice header { + border-bottom-color: #282d36; +} +html.dark .invoice table.table > thead:first-child > tr > th { + background-color: #282d36; + border-bottom-color: #282d36; + border-top-color: #282d36; +} +html.dark .invoice table.table > tbody tr > td { + border-color: #282d36; +} + +/* Error Pages - wrappers */ +.body-error { + margin: 0 auto; + max-width: 900px; + width: 100%; +} +.body-error.error-outside { + display: table; + height: 100vh; +} +.body-error.error-outside .center-error { + display: table-cell; + vertical-align: middle; +} +.body-error.error-inside { + margin-top: 150px; +} + +/* Error Pages - header */ +.body-error .error-header { + border-bottom: 1px solid #DADADA; + margin-bottom: 50px; + padding-bottom: 15px; +} +.body-error .error-header .form { + margin-top: 12px; +} + +/* Error Pages - typo */ +.body-error .error-code { + font-size: 140px; + font-size: 14rem; + line-height: 140px; + line-height: 14rem; + letter-spacing: -10px; +} +.body-error .error-explanation { + font-size: 20px; + font-size: 2rem; + line-height: 36px; + line-height: 3.6rem; +} + +/* Error Pages - Responsive */ +@media only screen and (max-width: 1150px) { + .body-error.error-inside { + margin-top: 50px; + padding-bottom: 50px; + } +} +@media only screen and (min-width: 768px) and (max-width: 1150px) { + .body-error.error-inside .error-code { + font-size: 100px; + font-size: 10rem; + line-height: 100px; + line-height: 10rem; + letter-spacing: -7px; + } + .body-error.error-inside .error-explanation { + font-size: 18px; + font-size: 1.8rem; + line-height: 32px; + line-height: 3.2rem; + } +} +@media only screen and (max-width: 767px) { + .body-error .error-code { + font-size: 90px; + font-size: 9rem; + line-height: 90px; + line-height: 9rem; + letter-spacing: -7px; + } + .body-error .error-explanation { + font-size: 16px; + font-size: 1.6rem; + line-height: 28px; + line-height: 2.8rem; + } + + .body-error.error-outside { + height: auto; + padding: 20px; + } +} +/* Sign Screens - Wrappers */ +.body-sign { + display: table; + height: 100vh; + margin: 0 auto; + max-width: 500px; + padding: 0 15px; + width: 100%; +} +.body-sign .center-sign { + display: table-cell; + padding-top: 20px; + vertical-align: middle; +} +.body-sign .panel-sign { + background: transparent; +} +.body-sign .panel-sign .panel-title-sign .title { + background-color: #cccccc; + border-radius: 5px 5px 0 0; + color: #FFF; + display: inline-block; + font-size: 12px; + font-size: 1.2rem; + line-height: 20px; + line-height: 2rem; + padding: 13px 17px; + vertical-align: bottom; +} +.body-sign .panel-sign .panel-body { + background: #FFF; + border-top: 5px solid #cccccc; + border-radius: 5px 0 5px 5px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + padding: 33px 33px 15px; +} + +/* Sign Screens - Elements */ +.body-sign .input-group-icon .input-group-addon i { + width: 14px; +} +.body-sign .checkbox-custom { + margin-top: 8px; +} +.body-sign .line-thru { + display: block; + font-size: 12px; + font-size: 1.2rem; + position: relative; +} +.body-sign .line-thru span { + color: #CCC; + position: relative; + z-index: 3; +} +.body-sign .line-thru:before { + background-color: #FFF; + content: ''; + height: 10px; + left: 50%; + position: absolute; + margin: -5px 0 0 -20px; + top: 50%; + width: 40px; + z-index: 2; +} +.body-sign .line-thru:after { + border-bottom: 1px solid #DADADA; + content: ''; + display: block; + left: 10%; + position: absolute; + top: 47%; + width: 81%; + z-index: 1; +} + +/* Lock Screen */ +.body-locked { + background: url(../images/patterns/noisy_net.png) repeat; + max-width: none; + min-height: 400px; +} +.body-locked.body-locked-inline { + background: none; + bottom: 0; + height: 100%; + left: 0; + min-height: 0; + position: fixed; + right: 0; + top: 0; + z-index: 9999; +} +.body-locked .panel-sign { + margin: 0 auto; + max-width: 400px; + padding-top: 40px; +} +.body-locked .panel-sign .panel-body { + border-radius: 5px; + position: relative; +} +.body-locked .current-user { + margin-top: 60px; + margin-bottom: 35px; +} +.body-locked .current-user .user-image { + border: 5px solid #cccccc; + border-radius: 150px; + height: 150px; + left: 50%; + position: absolute; + margin-left: -75px; + top: -75px; + width: 150px; +} +.body-locked .current-user .user-name { + font-size: 30px; + font-size: 3rem; + line-height: 36px; + line-height: 3.6rem; +} +.body-locked .current-user .user-email { + font-size: 11px; + font-size: 1.1rem; + line-height: 14px; + line-height: 1.4rem; +} + +/* Locked Screen - Responsive Landscape */ +@media only screen and (max-width: 767px) and (orientation: landscape) { + .body-locked .panel-sign, .body-locked.body-locked-inline .panel-sign { + padding-top: 0; + } + .body-locked .center-sign, .body-locked.body-locked-inline .center-sign { + padding-top: 0; + } + .body-locked .center-sign .current-user, .body-locked.body-locked-inline .center-sign .current-user { + margin-bottom: 45px; + margin-left: 100px; + margin-top: 10px; + } + .body-locked .center-sign .current-user .user-image, .body-locked.body-locked-inline .center-sign .current-user .user-image { + height: 100px; + left: 35px; + margin-left: 0; + margin-top: 0; + top: 15px; + width: 100px; + } +} +/* Lock Screen - Modal */ +.mfp-lock-screen.mfp-bg { + background: black url(../images/patterns/noisy_net.png) repeat; + opacity: 0.99; + z-index: 9998; +} +.mfp-lock-screen.mfp-wrap { + background: none; + z-index: 9999; +} + +/* dark */ +html.dark .body-sign .panel-sign .panel-body { + background-color: #2e353e; +} +html.dark .body-sign .line-thru:before { + background-color: #2e353e; +} +html.dark .body-sign .line-thru:after { + border-bottom-color: #282d36; +} + +.fc { + direction: ltr; + text-align: left; +} + +.fc table { + border-collapse: collapse; + border-spacing: 0; +} + +.fc .btn { + line-height: 1.2em; +} + +html .fc { + font-size: 1em; +} + +.fc table { + font-size: 1em; +} + +.fc td, .fc th { + padding: 1px; + vertical-align: top; +} + +.fc-header td { + white-space: nowrap; + vertical-align: middle; +} + +.fc-header-left { + width: 1%; + text-align: left; +} + +.fc-header-center { + text-align: center; +} + +.fc-header-right { + width: 99%; + text-align: right; +} + +.fc-header td.fc-header-right { + white-space: normal; +} + +.fc-header-title { + display: inline-block; + vertical-align: top; +} + +.fc-header-title h2 { + margin: 0 0 10px; + white-space: nowrap; +} + +.fc .fc-header-space { + padding-left: 10px; +} + +.fc-header .fc-button { + margin-bottom: 1em; + vertical-align: top; + margin-right: -1px; +} + +.fc-header .fc-corner-right { + margin-right: 1px; +} + +.fc-header .ui-corner-right { + margin-right: 0; +} + +.fc-header .fc-state-hover, .fc-header .ui-state-hover { + z-index: 2; +} + +.fc-header .fc-state-down { + z-index: 3; +} + +.fc-header .fc-state-active, .fc-header .ui-state-active, .fc-header .ui-state-down { + z-index: 4; + background-color: #e6e6e6; + background-color: #d9d9d9; + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.fc-content { + clear: both; +} + +.fc-view { + width: 100%; +} + +.fc .ui-widget-header { + border-color: #dddddd; + padding: 4px 0; +} + +thead th.fc-first { + border-top-left-radius: 5px; + -moz-border-top-left-radius: 5px; + -webkit-border-top-left-radius: 5px; +} + +thead th.fc-last { + border-top-right-radius: 5px; + -moz-border-top-right-radius: 5px; + -webkit-border-top-right-radius: 5px; +} + +.ui-state-highlight.fc-today { + background: #f4f4f4; + margin: 2px !important; + border: 0; + border-left: 1px solid #dddddd; + border-top: 1px solid #dddddd; + border-radius: 0; + -moz-border-radius: 0; + -webkit-border-radius: 0; +} + +.fc-button { + position: relative; + display: inline-block; + cursor: pointer; +} + +.fc-button-inner { + position: relative; + float: left; + overflow: hidden; +} + +.fc-button-content { + position: relative; + float: left; + height: 1.9em; + line-height: 1.9em; + padding: 0 0.6em; + white-space: nowrap; +} + +.fc-button-content .fc-icon-wrap { + position: relative; + float: left; + top: 50%; +} + +.fc-button-content .ui-icon { + position: relative; + float: left; + margin-top: -50%; + *margin-top: 0; + *top: -50%; +} + +.fc-state-default { + border-style: solid; + border-color: #cccccc #bbbbbb #aaaaaa; + background: #f3f3f3; + color: black; +} + +.fc-state-default .fc-button-effect { + position: absolute; + top: 50%; + left: 0; +} + +.fc-state-default .fc-button-effect span { + position: absolute; + top: -100px; + left: 0; + width: 500px; + height: 100px; + border-width: 100px 0 0 1px; + border-style: solid; + border-color: white; + background: #444444; + opacity: 0.09; + filter: alpha(opacity=9); +} + +.fc-state-default .fc-button-inner { + border-style: solid; + border-color: #cccccc #bbbbbb #aaaaaa; + background: #f3f3f3; + color: black; +} + +.fc-state-hover { + border-color: #999999; +} + +.fc-state-hover .fc-button-inner { + border-color: #999999; +} + +.fc-state-down { + border-color: #555555; + background: #777777; +} + +.fc-state-down .fc-button-inner { + border-color: #555555; + background: #777777; +} + +.fc-state-active { + border-color: #555555; + background: #777777; + color: white; +} + +.fc-state-active .fc-button-inner { + border-color: #555555; + background: #777777; + color: white; +} + +.fc-state-disabled { + color: #999999; + border-color: #dddddd; + cursor: default; +} + +.fc-state-disabled .fc-button-inner { + color: #999999; + border-color: #dddddd; +} + +.fc-state-disabled .fc-button-effect { + display: none; +} + +.fc-event { + border-style: solid; + border-width: 0; + font-size: 0.85em; + cursor: default; +} + +a.fc-event, .fc-event-draggable { + cursor: pointer; +} + +a.fc-event { + text-decoration: none; +} + +.fc-rtl .fc-event { + text-align: right; +} + +.fc-event-skin { + border: 0; +} + +.fc-event-inner { + position: relative; + width: 100%; + height: 100%; + border-style: solid; + border-width: 0; + overflow: hidden; +} + +.fc-event-time, .fc-event-title { + padding: 0 1px; +} + +.fc-event-hori { + border-width: 1px 0; + margin-bottom: 1px; +} + +.fc-event-hori .ui-resizable-e { + top: 0 !important; +} + +table.fc-border-separate { + border-collapse: separate; +} + +.fc-border-separate th, .fc-border-separate td { + border-width: 1px 0 0 1px; +} + +.fc-border-separate th.fc-last, .fc-border-separate td.fc-last { + border-right-width: 1px; +} + +.fc-border-separate tr.fc-last th, .fc-border-separate tr.fc-last td { + border-bottom-width: 1px; +} + +.fc-border-separate tbody tr.fc-first td, .fc-border-separate tbody tr.fc-first th { + border-top-width: 0; +} + +.fc-grid th { + text-align: center; +} + +.fc-grid .fc-day-number { + float: right; + padding: 0 2px; +} + +.fc-grid .fc-other-month .fc-day-number { + opacity: 0.3; + filter: alpha(opacity=30); +} + +.fc-rtl .fc-grid .fc-day-number { + float: left; +} + +.fc-rtl .fc-grid .fc-event-time { + float: right; +} + +.fc-agenda table { + border-collapse: separate; +} + +.fc-agenda-days th { + text-align: center; +} + +.fc-agenda .fc-agenda-axis { + width: 50px; + padding: 0 4px; + vertical-align: middle; + text-align: right; + white-space: nowrap; + font-weight: normal; +} + +.fc-agenda .fc-day-content { + padding: 2px 2px 1px; +} + +.fc-agenda-days .fc-agenda-axis { + border-right-width: 1px; +} + +.fc-agenda-days .fc-col0 { + border-left-width: 0; +} + +.fc-agenda-allday th { + border-width: 0 1px; +} + +.fc-agenda-allday .fc-day-content { + min-height: 34px; +} + +.fc-agenda-divider-inner { + height: 2px; + overflow: hidden; +} + +.fc-widget-header .fc-agenda-divider-inner { + background: #eeeeee; +} + +.fc-agenda-slots th { + border-width: 1px 1px 0; +} + +.fc-agenda-slots td { + border-width: 1px 0 0; + background: none; +} + +.fc-agenda-slots td div { + height: 20px; +} + +.fc-agenda-slots tr.fc-slot0 th, .fc-agenda-slots tr.fc-slot0 td { + border-top-width: 0; +} + +.fc-agenda-slots tr.fc-minor th, .fc-agenda-slots tr.fc-minor td { + border-top-style: dotted; +} + +.fc-agenda-slots tr.fc-minor th.ui-widget-header { + *border-top-style: solid; +} + +.fc-event-vert { + border-width: 0 1px; +} + +.fc-event-vert .fc-event-head, .fc-event-vert .fc-event-content { + position: relative; + z-index: 2; + width: 100%; + overflow: hidden; +} + +.fc-event-vert .fc-event-time { + white-space: nowrap; + font-size: 10px; +} + +.fc .ui-draggable-dragging .fc-event-bg, .fc-select-helper .fc-event-bg { + display: none; +} + +.fc-event-vert .ui-resizable-s { + bottom: 0 !important; +} + +/* Fullcalendar - header */ +.fc .fc-header-center { + display: none; +} +.fc .fc-widget-header { + background: #cccccc; + border-color: #cccccc; + color: white; + font-size: 13px; + font-size: 1.3rem; + font-weight: 500; + padding: 10px 0; + text-transform: uppercase; +} +.fc .fc-header-title h2 { + color: #171717; + font-size: 24px; + font-size: 2.4rem; + font-weight: normal; +} +.fc .fc-header-title h2:before { + color: #cccccc; + content: "\f073"; + display: inline-block; + font-family: FontAwesome; + font-size: 30px; + font-size: 3rem; + font-style: normal; + font-weight: normal; + line-height: 1; + margin-right: 10px; + -webkit-font-smoothing: antialiased; +} + +/* Fullcalendar - Borders */ +.fc-widget-content { + border-color: #DDD; +} + +/* Fullcalendar - Border Radius */ +.fc-content thead .fc-last .fc-first { + border-top-left-radius: 4px; +} +.fc-content thead .fc-last .fc-last { + border-top-right-radius: 4px; +} +.fc-content tbody .fc-last .fc-first { + border-bottom-left-radius: 4px; +} +.fc-content tbody .fc-last .fc-last { + border-bottom-right-radius: 4px; +} + +/* Fullcalendar - Today */ +.fc-content .fc-widget-content.fc-today { + background: #F7F7F7; +} + +/* Fullcalendar - Event Basics */ +.fc-event { + background: #cccccc; + border-color: #cccccc; +} +.fc-event .fc-event-inner { + padding: 2px 5px; +} + +/* Fullcalendar - Link Event */ +a.fc-event:hover .fc-event-inner { + color: #FFF; + text-decoration: underline; +} + +/* Fullcalendar - Event Time Format */ +.fc-grid .fc-event-time { + font-weight: 500; +} +.fc-grid .fc-event-time:after { + content: ' /'; +} +.fc-grid .fc-event-title { + font-weight: 300; +} + +/* Fullcalendar - Event States */ +/* Buttons - States */ +.fc-event.fc-event-default { + background: #ebebeb; + border-color: #ebebeb; +} +.fc-event.fc-event-default .fc-event-inner { + color: #777777; +} + +a.fc-event.fc-event-default:hover { + color: #777777; +} + +.fc-event.fc-event-primary { + background: #cccccc; + border-color: #cccccc; +} +.fc-event.fc-event-primary .fc-event-inner { + color: white; +} + +a.fc-event.fc-event-primary:hover { + color: white; +} + +.fc-event.fc-event-success { + background: #47a447; + border-color: #47a447; +} +.fc-event.fc-event-success .fc-event-inner { + color: white; +} + +a.fc-event.fc-event-success:hover { + color: white; +} + +.fc-event.fc-event-warning { + background: #ed9c28; + border-color: #ed9c28; +} +.fc-event.fc-event-warning .fc-event-inner { + color: white; +} + +a.fc-event.fc-event-warning:hover { + color: white; +} + +.fc-event.fc-event-danger { + background: #d2322d; + border-color: #d2322d; +} +.fc-event.fc-event-danger .fc-event-inner { + color: white; +} + +a.fc-event.fc-event-danger:hover { + color: white; +} + +.fc-event.fc-event-info { + background: #5bc0de; + border-color: #5bc0de; +} +.fc-event.fc-event-info .fc-event-inner { + color: white; +} + +a.fc-event.fc-event-info:hover { + color: white; +} + +.fc-event.fc-event-dark { + background: #171717; + border-color: #171717; +} +.fc-event.fc-event-dark .fc-event-inner { + color: white; +} + +a.fc-event.fc-event-dark:hover { + color: white; +} + +/* Fullcalendar - External Events */ +.external-event { + cursor: move; + display: inline-block; + font-size: 12px; + font-size: 1.2rem; + font-weight: normal; + margin: 5px; + padding: 10px; + text-align: left; +} + +@media only screen and (max-width: 400px) { + .fc .fc-header-right .btn-group { + margin: 10px 0; + } + .fc .fc-header-right br.hidden { + display: block !important; + } +} +@media only screen and (max-width: 480px) { + .fc .fc-header-left, + .fc .fc-header-right { + display: block; + width: 100%; + } + .fc .fc-header-right { + padding: 0 0 15px; + text-align: center; + } +} +@media only screen and (max-width: 991px) { + .fc { + margin-bottom: 30px; + } +} +/* dark */ +html.dark .fc .fc-header-title h2 { + color: #FFF; +} +html.dark .ui-state-highlight.fc-today, +html.dark .fc .ui-widget-header, +html.dark .fc-widget-content, +html.dark .fc-state-disabled, +html.dark .fc-state-disabled .fc-button-inner { + border-color: rgba(0, 0, 0, 0.3); +} +html.dark .fc-content .fc-widget-content.fc-today { + background: #21262d; +} + +.timeline .tm-body { + position: relative; + padding: 30px 0; +} +.timeline .tm-body:after { + background: #505050; + background: -moz-linear-gradient(top, rgba(80, 80, 80, 0) 0%, #505050 8%, #505050 92%, rgba(80, 80, 80, 0) 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1e5799), color-stop(100%, #7db9e8)); + background: -webkit-linear-gradient(top, rgba(80, 80, 80, 0) 0%, #505050 8%, #505050 92%, rgba(80, 80, 80, 0) 100%); + background: -o-linear-gradient(top, rgba(80, 80, 80, 0) 0%, #505050 8%, #505050 92%, rgba(80, 80, 80, 0) 100%); + background: -ms-linear-gradient(top, rgba(80, 80, 80, 0) 0%, #505050 8%, #505050 92%, rgba(80, 80, 80, 0) 100%); + background: linear, to bottom, rgba(80, 80, 80, 0) 0%, #505050 8%, #505050 92%, rgba(80, 80, 80, 0) 100%; + content: ''; + display: block; + height: 100%; + left: 140px; + margin-left: -2px; + position: absolute; + top: 0; + width: 3px; + z-index: 0; + filter: alpha(opacity=35); + opacity: 0.35; +} +.timeline .tm-title { + position: relative; + display: inline-block; + text-align: center; + min-width: 200px; + background-color: #fff; + padding: 4px 5px; + margin: 0 40px; + z-index: 1; + -webkit-border-radius: 3px; + border-radius: 3px; +} +.timeline .tm-items { + list-style: none; + padding: 0; + margin: 0; +} +.timeline .tm-items > li { + position: relative; + margin: 30px 0; + padding: 0 0 0 190px; + min-height: 65px; + z-index: 1; +} +.timeline .tm-items > li .tm-datetime { + position: absolute; + top: 50%; + left: 0; + width: 100px; + height: 48px; + margin-top: -24px; + text-align: right; + z-index: 3; +} +.timeline .tm-items > li .tm-datetime .tm-datetime-time { + color: #cccccc; + font-size: 24px; + font-size: 2.4rem; + font-weight: 700; + margin: 0; + white-space: nowrap; +} +.timeline .tm-items > li .tm-icon { + position: absolute; + top: 50%; + left: 140px; + background-color: #ecedf0; + border: 3px solid #cccccc; + color: #cccccc; + font-size: 28px; + padding: 10px; + width: 55px; + height: 55px; + text-align: center; + line-height: 29px; + margin-top: -28px; + margin-left: -28px; + z-index: 2; + -webkit-border-radius: 28px; + border-radius: 28px; +} +.timeline .tm-items > li .tm-box { + position: relative; + background: #fff; + min-height: 65px; + padding: 10px 20px; + border: 1px solid #e9e9e9; + -webkit-border-radius: 6px; + border-radius: 6px; +} +.timeline .tm-items > li .tm-box:after { + right: 100%; + border: solid transparent; + content: ' '; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-right-color: #fff; + border-width: 8px; + top: 50%; + margin-top: -8px; + z-index: 2; +} +.timeline .tm-items > li .tm-box p:last-child { + margin-bottom: 0; +} +.timeline .tm-items > li .tm-box .tm-meta { + margin: 10px 0 0; +} +.timeline .tm-items > li .tm-box .tm-meta span { + display: inline-block; + padding-right: 8px; +} +.timeline .tm-items > li .tm-box .tm-meta span:last-child, .timeline .tm-items > li .tm-box .tm-meta span:last-of-type { + padding-right: 0; +} +.timeline.timeline-simple .tm-body:after { + left: 30px; +} +.timeline.timeline-simple .tm-body .tm-title { + border: 1px solid #e9e9e9; + margin: 0 10px; +} +.timeline.timeline-simple .tm-body .tm-items > li { + padding: 0 0 0 55px; +} +.timeline.timeline-simple .tm-body .tm-items > li:before { + display: block; + position: absolute; + content: ' '; + background: none repeat scroll 0 0 #cccccc; + border-radius: 50%; + box-shadow: 0 0 0 3px white, 0 0 0 6px #cccccc; + height: 7px; + left: 30px; + top: 50%; + width: 8px; + margin-left: -4px; + margin-top: -4px; +} +.timeline.timeline-simple .tm-body .tm-items > li .tm-box:before { + left: -17px; + border: solid transparent; + content: ' '; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-right-color: #e9e9e9; + border-width: 8px; + top: 50%; + margin-top: -8px; + z-index: 1; +} + +@media only screen and (max-width: 991px) { + .timeline .tm-body:after { + left: 20px; + } + .timeline .tm-title { + margin: 0; + } + .timeline .tm-items > li { + padding-left: 50px; + } + .timeline .tm-items > li .tm-info { + margin: 0 0 15px; + } + .timeline .tm-items > li .tm-info:after { + content: ""; + display: table; + clear: both; + } + .timeline .tm-items > li .tm-icon { + border-width: 2px; + float: left; + font-size: 22px; + height: 40px; + line-height: 36px; + margin: 0 15px 0 0; + padding: 0; + position: static; + width: 40px; + } + .timeline .tm-items > li .tm-datetime { + margin: 0; + position: static; + text-align: left; + } + .timeline .tm-items > li .tm-datetime .tm-datetime-date { + font-size: 12px; + font-size: 1.2rem; + line-height: 1.3; + } + .timeline .tm-items > li .tm-datetime .tm-datetime-time { + font-size: 18px; + font-size: 1.8rem; + line-height: 1.3; + } +} +@media only screen and (max-width: 767px) { + .timeline .tm-items > li .tm-box .tm-meta span { + display: block; + } +} +html.dark .timeline .tm-items > li .tm-box { + background: #282d36; + border-color: #21262d; +} +html.dark .timeline .tm-items > li .tm-box:after { + border-right-color: #282d36; +} +html.dark .timeline .tm-items > li .tm-box:before { + border-right-color: #21262d; +} +html.dark .timeline .tm-items > li .tm-icon { + background-color: #1d2127; +} +html.dark .timeline .tm-title { + background-color: #282d36; + border-color: #21262d; +} +html.dark .timeline.timeline-simple .tm-body .tm-title { + background-color: #282d36; + border-color: #21262d; +} +html.dark .timeline.timeline-simple .tm-body .tm-items > li:before { + box-shadow: 0 0 0 3px #2e353e, 0 0 0 6px #cccccc; +} +html.dark .timeline.timeline-simple .tm-body .tm-items > li .tm-box:after { + border-right-color: #282d36; +} +html.dark .timeline.timeline-simple .tm-body .tm-items > li .tm-box:before { + border-right-color: #21262d; +} + +.media-gallery ul.mg-folders { + list-style: none; + padding: 0; + margin: 0; +} +.media-gallery ul.mg-folders > li { + display: block; + position: relative; +} +.media-gallery ul.mg-folders > li a.menu-item { + white-space: nowrap; + text-overflow: ellipsis; + padding-right: 80px; +} +.media-gallery ul.mg-folders > li a.menu-item i { + margin-right: 5px; + width: 16px; +} +.media-gallery ul.mg-folders > li .item-options { + position: absolute; + padding: 10px 0; + right: 0; + top: 0; + opacity: 0; + -webkit-transition: opacity 0.1s ease-in; + -moz-transition: opacity 0.1s ease-in; + transition: opacity 0.1s ease-in; +} +.media-gallery ul.mg-folders > li .item-options a:hover { + text-decoration: none; +} +.media-gallery ul.mg-folders > li:hover .item-options { + opacity: 1; +} +.media-gallery ul.mg-tags { + list-style: none; + padding: 0; + margin: 10px 0 0; +} +.media-gallery ul.mg-tags:after { + content: ""; + display: table; + clear: both; +} +.media-gallery ul.mg-tags > li { + float: left; + margin-right: 5px; + margin-bottom: 5px; +} +.media-gallery ul.mg-tags > li a { + display: block; + padding: 2px 7px; + font-size: 11px; + background-color: #171717; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + color: #666; +} +.media-gallery ul.mg-tags > li a:hover { + color: #fff; + text-decoration: none; + background-color: #cccccc; +} +.media-gallery .mg-files { + padding: 5px 0 30px; +} +.media-gallery .mg-files .thumbnail { + padding: 10px; + border-radius: 5px; + margin-bottom: 30px; + -webkit-transform: translate3d(0, 0, 0); + -moz-transform: translate3d(0, 0, 0); + -ms-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.media-gallery .mg-files .thumbnail .thumb-preview { + position: relative; + z-index: 2; +} +.media-gallery .mg-files .thumbnail .thumb-preview .thumb-image { + display: block; + overflow: hidden; +} +.media-gallery .mg-files .thumbnail .thumb-preview img { + width: 100%; + -webkit-transition: all 0.1s linear; + -moz-transition: all 0.1s linear; + transition: all 0.1s linear; + border-radius: 5px; +} +.media-gallery .mg-files .thumbnail .thumb-preview .mg-thumb-options { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.7); + visibility: hidden; + overflow: hidden; +} +.media-gallery .mg-files .thumbnail .thumb-preview .mg-thumb-options .mg-zoom { + position: absolute; + top: 0; + right: 0; + padding: 5px 15px 10px; + font-size: 22px; + font-size: 2.2rem; + color: #fff; + background-color: #cccccc; + border-radius: 0 0 0 15px; + cursor: pointer; + -webkit-transition: -webkit-transform 0.1s linear 0.1s; + -moz-transition: -moz-transform 0.1s linear 0.1s; + -ms-transition: -ms-transform 0.1s linear 0.1s; + transition: transform 0.1s linear 0.1s; + -webkit-transform: translate(100%, 0); + -moz-transform: translate(100%, 0); + -ms-transform: translate(100%, 0); + transform: translate(100%, 0); +} +.media-gallery .mg-files .thumbnail .thumb-preview .mg-thumb-options .mg-toolbar { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background-color: #cccccc; + color: #fff; + padding: 6px 10px; + -webkit-transition: -webkit-transform 0.1s linear 0.1s; + -moz-transition: -moz-transform 0.1s linear 0.1s; + -ms-transition: -ms-transform 0.1s linear 0.1s; + transition: transform 0.1s linear 0.1s; + -webkit-transform: translate(0, 100%); + -moz-transform: translate(0, 100%); + -ms-transform: translate(0, 100%); + transform: translate(0, 100%); +} +.media-gallery .mg-files .thumbnail .thumb-preview .mg-thumb-options .mg-toolbar:after { + content: ""; + display: table; + clear: both; +} +.media-gallery .mg-files .thumbnail .thumb-preview .mg-thumb-options .mg-toolbar .mg-option { + margin: 0; +} +.media-gallery .mg-files .thumbnail .thumb-preview .mg-thumb-options .mg-toolbar .mg-group > a { + color: #fff; + padding: 0 5px; +} +.media-gallery .mg-files .thumbnail .thumb-preview .mg-thumb-options .mg-toolbar .mg-group .mg-toggle { + color: #fff; + background: none; + border: none; + padding: 2px 2px 2px 10px; + border-left: 1px solid rgba(255, 255, 255, 0.3); +} +.media-gallery .mg-files .thumbnail .mg-title { + margin: 13px 0 2px; + padding-bottom: 2px; + display: inline-block; + font-size: 18px; + font-size: 1.8rem; +} +.media-gallery .mg-files .thumbnail .mg-title small { + position: relative; + top: 0; + left: 0; + color: #9e9e9e; + opacity: 0; + z-index: 1; + font-size: 10px; + font-size: 1rem; +} +.media-gallery .mg-files .thumbnail .mg-description:after { + content: ""; + display: table; + clear: both; +} +.media-gallery .mg-files .thumbnail.thumbnail-selected { + border-color: #FFF; + box-shadow: 0 0 8px -1px #cccccc; +} +.media-gallery .mg-files .thumbnail.thumbnail-selected .mg-title small { + opacity: 1; +} +.media-gallery .mg-files .thumbnail.thumbnail-selected .thumb-preview .mg-thumb-options { + visibility: visible; +} +.media-gallery .mg-files .thumbnail.thumbnail-selected .thumb-preview .mg-thumb-options .mg-toolbar { + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +.media-gallery .mg-files .thumbnail:hover .mg-title small { + opacity: 1; +} +.media-gallery .mg-files .thumbnail:hover .thumb-preview img { + -webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -ms-transform: scale(1.1); + transform: scale(1.1); +} +.media-gallery .mg-files .thumbnail:hover .thumb-preview .mg-thumb-options { + visibility: visible; +} +.media-gallery .mg-files .thumbnail:hover .thumb-preview .mg-thumb-options .mg-zoom { + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} +.media-gallery .mg-files .thumbnail:hover .thumb-preview .mg-thumb-options .mg-toolbar { + -webkit-transform: translate(0, 0); + -moz-transform: translate(0, 0); + -ms-transform: translate(0, 0); + transform: translate(0, 0); +} + +html.dark .media-gallery .mg-files .thumbnail.thumbnail-selected { + border-color: #242830; +} +html.dark .media-gallery .mg-files .thumbnail .mg-title small { + color: #808697; +} + +.log-viewer { + line-height: 26px; + line-height: 2.6rem; + font-family: monospace; + font-size: 14px; + font-size: 1.4rem; +} + +/* Change Content Background Color */ +html.search-results body { + background: #FFF; +} + +/* Search Results Wrapper */ +.search-content { + margin: -40px; +} +.search-content .search-control-wrapper { + background: #f7f7f7; + border-bottom: 1px solid #ebebeb; + margin-top: 3px; + padding: 20px; +} + +/* Search Results Tabs */ +.search-content .search-toolbar { + border-bottom: 1px solid #ebebeb; + margin: 0 0 40px; +} +.search-content .search-toolbar .nav-pills { + margin: 0 40px; +} +.search-content .search-toolbar .nav-pills li { + margin: 0 15px 0 0; +} +.search-content .search-toolbar .nav-pills li:last-child { + margin-right: 0; +} +.search-content .search-toolbar .nav-pills li a { + padding-left: 5px; + padding-right: 5px; +} +.search-content .search-toolbar .nav-pills li a, .search-content .search-toolbar .nav-pills li a:hover, .search-content .search-toolbar .nav-pills li a:focus { + background: none; + border-radius: 0; + border-bottom: 2px solid #FFF; + border-top: 2px solid #FFF; + color: #777; +} +.search-content .search-toolbar .nav-pills li a:hover, .search-content .search-toolbar .nav-pills li a:focus { + background: none; + border-radius: 0; + border-bottom: 2px solid #FFF; + border-top: 2px solid #FFF; + color: #555; +} +.search-content .search-toolbar .nav-pills li.active a { + color: #cccccc; + border-bottom-color: #cccccc; +} +.search-content > .tab-content { + border: none; + box-shadow: none; + padding: 0 40px; +} + +/* Search Result Totals */ +.search-content .total-results { + margin-top: -25px; +} + +/* Search Results List */ +.search-results-list { + max-width: 750px; +} +.search-results-list li { + border-bottom: 1px solid #EEE; + margin-bottom: 15px; + padding-bottom: 15px; + position: relative; +} +.search-results-list li:last-child { + border-bottom: none; + margin-bottom: 0; + padding-bottom: 0; +} +.search-results-list .result-type { + right: 5px; + position: absolute; + top: 5px; +} +.search-results-list a { + border-radius: 4px; + display: block; + padding: 25px; + text-decoration: none; +} +.search-results-list a .title { + margin-top: 0; +} +.search-results-list a .description { + color: #777; +} +.search-results-list a p:last-child { + margin-bottom: 0; +} +.search-results-list a:hover { + background: #f7f7f7; +} +.search-results-list .has-thumb { + display: table; + width: 100%; +} +.search-results-list .has-thumb .result-thumb, +.search-results-list .has-thumb .result-data { + display: table-cell; + vertical-align: top; +} +.search-results-list .result-thumb { + padding-right: 25px; +} +.search-results-list .result-thumb img, +.search-results-list .result-thumb .fa { + height: 75px; + width: 75px; +} +.search-results-list .result-thumb .fa { + background: #cccccc; + color: white; + font-size: 36px; + font-size: 3.6rem; + line-height: 75px; + line-height: 7.5rem; + text-align: center; +} + +/* Search Results Responsive */ +@media only screen and (max-width: 767px) { + .search-content { + margin: -20px; + } +} +@media only screen and (max-width: 480px) { + .search-results-list .has-thumb { + display: block; + } + .search-results-list .has-thumb:after { + content: ""; + display: table; + clear: both; + } + .search-results-list .has-thumb .result-thumb, + .search-results-list .has-thumb .result-data { + display: block; + } + .search-results-list .has-thumb .result-thumb { + float: left; + } + .search-results-list .has-thumb .result-data .title { + margin-top: 3px; + } + .search-results-list .result-thumb img, + .search-results-list .result-thumb .fa { + height: 35px; + width: 35px; + } + .search-results-list .result-thumb .fa { + font-size: 16px; + font-size: 1.6rem; + line-height: 35px; + line-height: 3.5rem; + } +} +/* dark */ +html.dark .search-content .search-control-wrapper { + background: #1d2127; + border-bottom-color: #282d36; +} +html.dark .search-content .tab-content { + background: transparent; +} +html.dark .search-content .search-toolbar { + background: #21262d; + border-bottom-color: #21262d; +} +html.dark .search-content .search-toolbar .nav-pills a, html.dark .search-content .search-toolbar .nav-pills a:hover, html.dark .search-content .search-toolbar .nav-pills a:focus { + border-bottom-color: #21262d; + border-top-color: #21262d; + color: #808697; +} +html.dark .search-content .search-toolbar .nav-pills a:hover, html.dark .search-content .search-toolbar .nav-pills a:focus { + border-bottom-color: #21262d; + border-top-color: #21262d; + color: #555; +} +html.dark .search-content .search-toolbar .nav-pills li.active a, html.dark .search-content .search-toolbar .nav-pills li.active a:hover, html.dark .search-content .search-toolbar .nav-pills li.active a:focus { + color: #cccccc; + border-bottom-color: #cccccc; +} +html.dark .search-content .search-results-list li { + border-bottom-color: #282d36; +} +html.dark .search-content .search-results-list a .description { + color: #808697; +} +html.dark .search-content .search-results-list a:hover { + background: #282d36; +} + +/* Dark - Background */ +html.dark, +html.dark body { + background-color: #1d2127; +} +html.dark.boxed .content-body { + background-color: #1d2127; +} + +html.dark body { + color: #808697; +} + +/* Dark - Titles */ +html.dark h1, +html.dark .h1, +html.dark h2, +html.dark .h2, +html.dark h3, +html.dark .h3, +html.dark h4, +html.dark .h4, +html.dark h5, +html.dark .h5, +html.dark h6, +html.dark .h6 { + color: #FFF; +} + +/* Dark - Alerts */ +html.dark .alert h1, +html.dark .alert .h1, +html.dark .alert h2, +html.dark .alert .h2, +html.dark .alert h3, +html.dark .alert .h3, +html.dark .alert h4, +html.dark .alert .h4, +html.dark .alert h5, +html.dark .alert .h5, +html.dark .alert h6, +html.dark .alert .h6 { + color: #111; +} + +/* Dark - Blockquote */ +html.dark blockquote { + border-color: #282d36; +} + +/* Dark - Helpers */ +html.dark .text-dark { + color: #FFF !important; +} + +html.dark ul.nav-list.primary > li a { + border-bottom-color: #282d36; +} +html.dark ul.nav-list.primary > li a:hover { + background-color: #282d36; +} + +html.dark .pagination > li > a, +html.dark .pagination > li > span { + background-color: #282d36; + border-color: #242830; +} +html.dark .pagination > li.active > a, +html.dark .pagination > li.active > span { + background-color: #cccccc; + border-color: #242830; +} + +html.dark .dropdown-menu { + background-color: #282d36; +} +html.dark .dropdown-menu > li > a { + color: #EEE; +} +html.dark .dropdown-menu > li > a:hover, html.dark .dropdown-menu > li > a:focus { + background-color: #1d2127; + color: #FFF; +} + +html.dark hr.dotted, +html.dark hr.solid { + border-color: #4C4C4C; +} + +html.dark .img-thumbnail, +html.dark .thumbnail { + background-color: #21262d; + border-color: #282d36; +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/css/bootstrap-colorpicker.css b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/css/bootstrap-colorpicker.css new file mode 100644 index 0000000..ca0a303 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/css/bootstrap-colorpicker.css @@ -0,0 +1,217 @@ +/*! + * Bootstrap Colorpicker + * http://mjolnic.github.io/bootstrap-colorpicker/ + * + * Originally written by (c) 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + */ + +.colorpicker-saturation { + float: left; + width: 100px; + height: 100px; + cursor: crosshair; + background-image: url("../img/bootstrap-colorpicker/saturation.png"); +} + +.colorpicker-saturation i { + position: absolute; + top: 0; + left: 0; + display: block; + width: 5px; + height: 5px; + margin: -4px 0 0 -4px; + border: 1px solid #000; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.colorpicker-saturation i b { + display: block; + width: 5px; + height: 5px; + border: 1px solid #fff; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.colorpicker-hue, +.colorpicker-alpha { + float: left; + width: 15px; + height: 100px; + margin-bottom: 4px; + margin-left: 4px; + cursor: row-resize; +} + +.colorpicker-hue i, +.colorpicker-alpha i { + position: absolute; + top: 0; + left: 0; + display: block; + width: 100%; + height: 1px; + margin-top: -1px; + background: #000; + border-top: 1px solid #fff; +} + +.colorpicker-hue { + background-image: url("../img/bootstrap-colorpicker/hue.png"); +} + +.colorpicker-alpha { + display: none; + background-image: url("../img/bootstrap-colorpicker/alpha.png"); +} + +.colorpicker { + top: 0; + left: 0; + z-index: 2500; + min-width: 130px; + padding: 4px; + margin-top: 1px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; +} + +.colorpicker:before, +.colorpicker:after { + display: table; + line-height: 0; + content: ""; +} + +.colorpicker:after { + clear: both; +} + +.colorpicker:before { + position: absolute; + top: -7px; + left: 6px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.colorpicker:after { + position: absolute; + top: -6px; + left: 7px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.colorpicker div { + position: relative; +} + +.colorpicker.colorpicker-with-alpha { + min-width: 140px; +} + +.colorpicker.colorpicker-with-alpha .colorpicker-alpha { + display: block; +} + +.colorpicker-color { + height: 10px; + margin-top: 5px; + clear: both; + background-image: url("../img/bootstrap-colorpicker/alpha.png"); + background-position: 0 100%; +} + +.colorpicker-color div { + height: 10px; +} + +.colorpicker-element .input-group-addon i, +.colorpicker-element .add-on i { + display: inline-block; + width: 16px; + height: 16px; + vertical-align: text-top; + cursor: pointer; +} + +.colorpicker.colorpicker-inline { + position: relative; + z-index: auto; + display: inline-block; + float: none; +} + +.colorpicker.colorpicker-horizontal { + width: 110px; + height: auto; + min-width: 110px; +} + +.colorpicker.colorpicker-horizontal .colorpicker-saturation { + margin-bottom: 4px; +} + +.colorpicker.colorpicker-horizontal .colorpicker-color { + width: 100px; +} + +.colorpicker.colorpicker-horizontal .colorpicker-hue, +.colorpicker.colorpicker-horizontal .colorpicker-alpha { + float: left; + width: 100px; + height: 15px; + margin-bottom: 4px; + margin-left: 0; + cursor: col-resize; +} + +.colorpicker.colorpicker-horizontal .colorpicker-hue i, +.colorpicker.colorpicker-horizontal .colorpicker-alpha i { + position: absolute; + top: 0; + left: 0; + display: block; + width: 1px; + height: 15px; + margin-top: 0; + background: #ffffff; + border: none; +} + +.colorpicker.colorpicker-horizontal .colorpicker-hue { + background-image: url("../img/bootstrap-colorpicker/hue-horizontal.png"); +} + +.colorpicker.colorpicker-horizontal .colorpicker-alpha { + background-image: url("../img/bootstrap-colorpicker/alpha-horizontal.png"); +} + +.colorpicker.colorpicker-hidden { + display: none; +} + +.colorpicker.colorpicker-visible { + display: block; +} + +.colorpicker-inline.colorpicker-visible { + display: inline-block; +} \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png new file mode 100644 index 0000000..d0a65c0 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha-horizontal.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png new file mode 100644 index 0000000..38043f1 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/alpha.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/hue-horizontal.png b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/hue-horizontal.png new file mode 100644 index 0000000..a0d9add Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/hue-horizontal.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png new file mode 100644 index 0000000..d89560e Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/hue.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png new file mode 100644 index 0000000..594ae50 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/img/bootstrap-colorpicker/saturation.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/js/bootstrap-colorpicker.js b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/js/bootstrap-colorpicker.js new file mode 100644 index 0000000..b4f6075 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-colorpicker/js/bootstrap-colorpicker.js @@ -0,0 +1,971 @@ +/*! + * Bootstrap Colorpicker + * http://mjolnic.github.io/bootstrap-colorpicker/ + * + * Originally written by (c) 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + * @todo Update DOCS + */ + +(function(factory) { + "use strict"; + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else if (window.jQuery && !window.jQuery.fn.colorpicker) { + factory(window.jQuery); + } + } + (function($) { + 'use strict'; + + // Color object + var Color = function(val) { + this.value = { + h: 0, + s: 0, + b: 0, + a: 1 + }; + this.origFormat = null; // original string format + if (val) { + if (val.toLowerCase !== undefined) { + this.setColor(val); + } else if (val.h !== undefined) { + this.value = val; + } + } + }; + + Color.prototype = { + constructor: Color, + // 140 predefined colors from the HTML Colors spec + colors: { + "aliceblue": "#f0f8ff", + "antiquewhite": "#faebd7", + "aqua": "#00ffff", + "aquamarine": "#7fffd4", + "azure": "#f0ffff", + "beige": "#f5f5dc", + "bisque": "#ffe4c4", + "black": "#000000", + "blanchedalmond": "#ffebcd", + "blue": "#0000ff", + "blueviolet": "#8a2be2", + "brown": "#a52a2a", + "burlywood": "#deb887", + "cadetblue": "#5f9ea0", + "chartreuse": "#7fff00", + "chocolate": "#d2691e", + "coral": "#ff7f50", + "cornflowerblue": "#6495ed", + "cornsilk": "#fff8dc", + "crimson": "#dc143c", + "cyan": "#00ffff", + "darkblue": "#00008b", + "darkcyan": "#008b8b", + "darkgoldenrod": "#b8860b", + "darkgray": "#a9a9a9", + "darkgreen": "#006400", + "darkkhaki": "#bdb76b", + "darkmagenta": "#8b008b", + "darkolivegreen": "#556b2f", + "darkorange": "#ff8c00", + "darkorchid": "#9932cc", + "darkred": "#8b0000", + "darksalmon": "#e9967a", + "darkseagreen": "#8fbc8f", + "darkslateblue": "#483d8b", + "darkslategray": "#2f4f4f", + "darkturquoise": "#00ced1", + "darkviolet": "#9400d3", + "deeppink": "#ff1493", + "deepskyblue": "#00bfff", + "dimgray": "#696969", + "dodgerblue": "#1e90ff", + "firebrick": "#b22222", + "floralwhite": "#fffaf0", + "forestgreen": "#228b22", + "fuchsia": "#ff00ff", + "gainsboro": "#dcdcdc", + "ghostwhite": "#f8f8ff", + "gold": "#ffd700", + "goldenrod": "#daa520", + "gray": "#808080", + "green": "#008000", + "greenyellow": "#adff2f", + "honeydew": "#f0fff0", + "hotpink": "#ff69b4", + "indianred ": "#cd5c5c", + "indigo ": "#4b0082", + "ivory": "#fffff0", + "khaki": "#f0e68c", + "lavender": "#e6e6fa", + "lavenderblush": "#fff0f5", + "lawngreen": "#7cfc00", + "lemonchiffon": "#fffacd", + "lightblue": "#add8e6", + "lightcoral": "#f08080", + "lightcyan": "#e0ffff", + "lightgoldenrodyellow": "#fafad2", + "lightgrey": "#d3d3d3", + "lightgreen": "#90ee90", + "lightpink": "#ffb6c1", + "lightsalmon": "#ffa07a", + "lightseagreen": "#20b2aa", + "lightskyblue": "#87cefa", + "lightslategray": "#778899", + "lightsteelblue": "#b0c4de", + "lightyellow": "#ffffe0", + "lime": "#00ff00", + "limegreen": "#32cd32", + "linen": "#faf0e6", + "magenta": "#ff00ff", + "maroon": "#800000", + "mediumaquamarine": "#66cdaa", + "mediumblue": "#0000cd", + "mediumorchid": "#ba55d3", + "mediumpurple": "#9370d8", + "mediumseagreen": "#3cb371", + "mediumslateblue": "#7b68ee", + "mediumspringgreen": "#00fa9a", + "mediumturquoise": "#48d1cc", + "mediumvioletred": "#c71585", + "midnightblue": "#191970", + "mintcream": "#f5fffa", + "mistyrose": "#ffe4e1", + "moccasin": "#ffe4b5", + "navajowhite": "#ffdead", + "navy": "#000080", + "oldlace": "#fdf5e6", + "olive": "#808000", + "olivedrab": "#6b8e23", + "orange": "#ffa500", + "orangered": "#ff4500", + "orchid": "#da70d6", + "palegoldenrod": "#eee8aa", + "palegreen": "#98fb98", + "paleturquoise": "#afeeee", + "palevioletred": "#d87093", + "papayawhip": "#ffefd5", + "peachpuff": "#ffdab9", + "peru": "#cd853f", + "pink": "#ffc0cb", + "plum": "#dda0dd", + "powderblue": "#b0e0e6", + "purple": "#800080", + "red": "#ff0000", + "rosybrown": "#bc8f8f", + "royalblue": "#4169e1", + "saddlebrown": "#8b4513", + "salmon": "#fa8072", + "sandybrown": "#f4a460", + "seagreen": "#2e8b57", + "seashell": "#fff5ee", + "sienna": "#a0522d", + "silver": "#c0c0c0", + "skyblue": "#87ceeb", + "slateblue": "#6a5acd", + "slategray": "#708090", + "snow": "#fffafa", + "springgreen": "#00ff7f", + "steelblue": "#4682b4", + "tan": "#d2b48c", + "teal": "#008080", + "thistle": "#d8bfd8", + "tomato": "#ff6347", + "turquoise": "#40e0d0", + "violet": "#ee82ee", + "wheat": "#f5deb3", + "white": "#ffffff", + "whitesmoke": "#f5f5f5", + "yellow": "#ffff00", + "yellowgreen": "#9acd32" + }, + _sanitizeNumber: function(val) { + if (typeof val === 'number') { + return val; + } + if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) { + return 1; + } + if (val.toLowerCase !== undefined) { + return parseFloat(val); + } + return 1; + }, + //parse a string to HSB + setColor: function(strVal) { + strVal = strVal.toLowerCase(); + this.value = this.stringToHSB(strVal) || { + h: 0, + s: 0, + b: 0, + a: 1 + }; + }, + stringToHSB: function(strVal) { + strVal = strVal.toLowerCase(); + var that = this, + result = false; + $.each(this.stringParsers, function(i, parser) { + var match = parser.re.exec(strVal), + values = match && parser.parse.apply(that, [match]), + format = parser.format || 'rgba'; + if (values) { + if (format.match(/hsla?/)) { + result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values)); + } else { + result = that.RGBtoHSB.apply(that, values); + } + that.origFormat = format; + return false; + } + return true; + }); + return result; + }, + setHue: function(h) { + this.value.h = 1 - h; + }, + setSaturation: function(s) { + this.value.s = s; + }, + setBrightness: function(b) { + this.value.b = 1 - b; + }, + setAlpha: function(a) { + this.value.a = parseInt((1 - a) * 100, 10) / 100; + }, + toRGB: function(h, s, v, a) { + h = h || this.value.h; + s = s || this.value.s; + v = v || this.value.b; + a = a || this.value.a; + + var r, g, b, i, f, p, q, t; + if (h && s === undefined && v === undefined) { + s = h.s, v = h.v, h = h.h; + } + i = Math.floor(h * 6); + f = h * 6 - i; + p = v * (1 - s); + q = v * (1 - f * s); + t = v * (1 - (1 - f) * s); + switch (i % 6) { + case 0: + r = v, g = t, b = p; + break; + case 1: + r = q, g = v, b = p; + break; + case 2: + r = p, g = v, b = t; + break; + case 3: + r = p, g = q, b = v; + break; + case 4: + r = t, g = p, b = v; + break; + case 5: + r = v, g = p, b = q; + break; + } + return { + r: Math.floor(r * 255), + g: Math.floor(g * 255), + b: Math.floor(b * 255), + a: a + }; + }, + toHex: function(h, s, b, a) { + var rgb = this.toRGB(h, s, b, a); + return '#' + ((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1); + }, + toHSL: function(h, s, b, a) { + h = h || this.value.h; + s = s || this.value.s; + b = b || this.value.b; + a = a || this.value.a; + + var H = h, + L = (2 - s) * b, + S = s * b; + if (L > 0 && L <= 1) { + S /= L; + } else { + S /= 2 - L; + } + L /= 2; + if (S > 1) { + S = 1; + } + return { + h: isNaN(H) ? 0 : H, + s: isNaN(S) ? 0 : S, + l: isNaN(L) ? 0 : L, + a: isNaN(a) ? 0 : a, + }; + }, + toAlias: function(r, g, b, a) { + var rgb = this.toHex(r, g, b, a); + for (var alias in this.colors) { + if (this.colors[alias] == rgb) { + return alias; + } + } + return false; + }, + RGBtoHSB: function(r, g, b, a) { + r /= 255; + g /= 255; + b /= 255; + + var H, S, V, C; + V = Math.max(r, g, b); + C = V - Math.min(r, g, b); + H = (C === 0 ? null : + V === r ? (g - b) / C : + V === g ? (b - r) / C + 2 : + (r - g) / C + 4 + ); + H = ((H + 360) % 6) * 60 / 360; + S = C === 0 ? 0 : C / V; + return { + h: this._sanitizeNumber(H), + s: S, + b: V, + a: this._sanitizeNumber(a) + }; + }, + HueToRGB: function(p, q, h) { + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + if ((h * 6) < 1) { + return p + (q - p) * h * 6; + } else if ((h * 2) < 1) { + return q; + } else if ((h * 3) < 2) { + return p + (q - p) * ((2 / 3) - h) * 6; + } else { + return p; + } + }, + HSLtoRGB: function(h, s, l, a) { + if (s < 0) { + s = 0; + } + var q; + if (l <= 0.5) { + q = l * (1 + s); + } else { + q = l + s - (l * s); + } + + var p = 2 * l - q; + + var tr = h + (1 / 3); + var tg = h; + var tb = h - (1 / 3); + + var r = Math.round(this.HueToRGB(p, q, tr) * 255); + var g = Math.round(this.HueToRGB(p, q, tg) * 255); + var b = Math.round(this.HueToRGB(p, q, tb) * 255); + return [r, g, b, this._sanitizeNumber(a)]; + }, + toString: function(format) { + format = format || 'rgba'; + switch (format) { + case 'rgb': + { + var rgb = this.toRGB(); + return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')'; + } + break; + case 'rgba': + { + var rgb = this.toRGB(); + return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')'; + } + break; + case 'hsl': + { + var hsl = this.toHSL(); + return 'hsl(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%)'; + } + break; + case 'hsla': + { + var hsl = this.toHSL(); + return 'hsla(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%,' + hsl.a + ')'; + } + break; + case 'hex': + { + return this.toHex(); + } + break; + case 'alias': + return this.toAlias() || this.toHex(); + default: + { + return false; + } + break; + } + }, + // a set of RE's that can match strings and generate color tuples. + // from John Resig color plugin + // https://github.com/jquery/jquery-color/ + stringParsers: [{ + re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, + format: 'hex', + parse: function(execResult) { + return [ + parseInt(execResult[1], 16), + parseInt(execResult[2], 16), + parseInt(execResult[3], 16), + 1 + ]; + } + }, { + re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/, + format: 'hex', + parse: function(execResult) { + return [ + parseInt(execResult[1] + execResult[1], 16), + parseInt(execResult[2] + execResult[2], 16), + parseInt(execResult[3] + execResult[3], 16), + 1 + ]; + } + }, { + re: /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/, + format: 'rgb', + parse: function(execResult) { + return [ + execResult[1], + execResult[2], + execResult[3], + 1 + ]; + } + }, { + re: /rgb\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/, + format: 'rgb', + parse: function(execResult) { + return [ + 2.55 * execResult[1], + 2.55 * execResult[2], + 2.55 * execResult[3], + 1 + ]; + } + }, { + re: /rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, + format: 'rgba', + 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*)?\)/, + format: 'rgba', + parse: function(execResult) { + return [ + 2.55 * execResult[1], + 2.55 * execResult[2], + 2.55 * execResult[3], + execResult[4] + ]; + } + }, { + re: /hsl\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/, + format: 'hsl', + parse: function(execResult) { + return [ + execResult[1] / 360, + execResult[2] / 100, + execResult[3] / 100, + execResult[4] + ]; + } + }, { + re: /hsla\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/, + format: 'hsla', + parse: function(execResult) { + return [ + execResult[1] / 360, + execResult[2] / 100, + execResult[3] / 100, + execResult[4] + ]; + } + }, { + //predefined color name + re: /^([a-z]{3,})$/, + format: 'alias', + parse: function(execResult) { + var hexval = this.colorNameToHex(execResult[0]) || '#000000'; + var match = this.stringParsers[0].re.exec(hexval), + values = match && this.stringParsers[0].parse.apply(this, [match]); + return values; + } + }], + colorNameToHex: function(name) { + if (typeof this.colors[name.toLowerCase()] !== 'undefined') { + return this.colors[name.toLowerCase()]; + } + return false; + } + }; + + + var defaults = { + horizontal: false, // horizontal mode layout ? + inline: false, //forces to show the colorpicker as an inline element + color: false, //forces a color + format: false, //forces a format + input: 'input', // children input selector + container: false, // container selector + component: '.add-on, .input-group-addon', // children component selector + sliders: { + saturation: { + maxLeft: 100, + maxTop: 100, + callLeft: 'setSaturation', + callTop: 'setBrightness' + }, + hue: { + maxLeft: 0, + maxTop: 100, + callLeft: false, + callTop: 'setHue' + }, + alpha: { + maxLeft: 0, + maxTop: 100, + callLeft: false, + callTop: 'setAlpha' + } + }, + slidersHorz: { + saturation: { + maxLeft: 100, + maxTop: 100, + callLeft: 'setSaturation', + callTop: 'setBrightness' + }, + hue: { + maxLeft: 100, + maxTop: 0, + callLeft: 'setHue', + callTop: false + }, + alpha: { + maxLeft: 100, + maxTop: 0, + callLeft: 'setAlpha', + callTop: false + } + }, + template: '
' + }; + + var Colorpicker = function(element, options) { + this.element = $(element).addClass('colorpicker-element'); + this.options = $.extend({}, defaults, this.element.data(), options); + this.component = this.options.component; + this.component = (this.component !== false) ? this.element.find(this.component) : false; + if (this.component && (this.component.length === 0)) { + this.component = false; + } + this.container = (this.options.container === true) ? this.element : this.options.container; + this.container = (this.container !== false) ? $(this.container) : false; + + // Is the element an input? Should we search inside for any input? + this.input = this.element.is('input') ? this.element : (this.options.input ? + this.element.find(this.options.input) : false); + if (this.input && (this.input.length === 0)) { + this.input = false; + } + // Set HSB color + this.color = new Color(this.options.color !== false ? this.options.color : this.getValue()); + this.format = this.options.format !== false ? this.options.format : this.color.origFormat; + + // Setup picker + this.picker = $(this.options.template); + if (this.options.inline) { + this.picker.addClass('colorpicker-inline colorpicker-visible'); + } else { + this.picker.addClass('colorpicker-hidden'); + } + if (this.options.horizontal) { + this.picker.addClass('colorpicker-horizontal'); + } + if (this.format === 'rgba' || this.format === 'hsla') { + this.picker.addClass('colorpicker-with-alpha'); + } + this.picker.on('mousedown.colorpicker', $.proxy(this.mousedown, this)); + this.picker.appendTo(this.container ? this.container : $('body')); + + // Bind events + if (this.input !== false) { + this.input.on({ + 'keyup.colorpicker': $.proxy(this.keyup, this) + }); + if (this.component === false) { + this.element.on({ + 'focus.colorpicker': $.proxy(this.show, this) + }); + } + if (this.options.inline === false) { + this.element.on({ + 'focusout.colorpicker': $.proxy(this.hide, this) + }); + } + } + + if (this.component !== false) { + this.component.on({ + 'click.colorpicker': $.proxy(this.show, this) + }); + } + + if ((this.input === false) && (this.component === false)) { + this.element.on({ + 'click.colorpicker': $.proxy(this.show, this) + }); + } + this.update(); + + $($.proxy(function() { + this.element.trigger('create'); + }, this)); + }; + + Colorpicker.version = '2.0.0-beta'; + + Colorpicker.Color = Color; + + Colorpicker.prototype = { + constructor: Colorpicker, + destroy: function() { + this.picker.remove(); + this.element.removeData('colorpicker').off('.colorpicker'); + if (this.input !== false) { + this.input.off('.colorpicker'); + } + if (this.component !== false) { + this.component.off('.colorpicker'); + } + this.element.removeClass('colorpicker-element'); + this.element.trigger({ + type: 'destroy' + }); + }, + reposition: function() { + if (this.options.inline !== false) { + return false; + } + var type = this.container && this.container[0] !== document.body ? 'position' : 'offset'; + var offset = this.component ? this.component[type]() : this.element[type](); + this.picker.css({ + top: offset.top + (this.component ? this.component.outerHeight() : this.element.outerHeight()), + left: offset.left + }); + }, + show: function(e) { + if (this.isDisabled()) { + return false; + } + this.picker.addClass('colorpicker-visible').removeClass('colorpicker-hidden'); + this.reposition(); + $(window).on('resize.colorpicker', $.proxy(this.reposition, this)); + if (!this.hasInput() && e) { + if (e.stopPropagation && e.preventDefault) { + e.stopPropagation(); + e.preventDefault(); + } + } + if (this.options.inline === false) { + $(window.document).on({ + 'mousedown.colorpicker': $.proxy(this.hide, this) + }); + } + this.element.trigger({ + type: 'showPicker', + color: this.color + }); + }, + hide: function() { + this.picker.addClass('colorpicker-hidden').removeClass('colorpicker-visible'); + $(window).off('resize.colorpicker', this.reposition); + $(document).off({ + 'mousedown.colorpicker': this.hide + }); + this.update(); + this.element.trigger({ + type: 'hidePicker', + color: this.color + }); + }, + updateData: function(val) { + val = val || this.color.toString(this.format); + this.element.data('color', val); + return val; + }, + updateInput: function(val) { + val = val || this.color.toString(this.format); + if (this.input !== false) { + this.input.prop('value', val); + } + return val; + }, + updatePicker: function(val) { + if (val !== undefined) { + this.color = new Color(val); + } + var sl = (this.options.horizontal === false) ? this.options.sliders : this.options.slidersHorz; + var icns = this.picker.find('i'); + if (icns.length === 0) { + return; + } + if (this.options.horizontal === false) { + sl = this.options.sliders; + icns.eq(1).css('top', sl.hue.maxTop * (1 - this.color.value.h)).end() + .eq(2).css('top', sl.alpha.maxTop * (1 - this.color.value.a)); + } else { + sl = this.options.slidersHorz; + icns.eq(1).css('left', sl.hue.maxLeft * (1 - this.color.value.h)).end() + .eq(2).css('left', sl.alpha.maxLeft * (1 - this.color.value.a)); + } + icns.eq(0).css({ + 'top': sl.saturation.maxTop - this.color.value.b * sl.saturation.maxTop, + 'left': this.color.value.s * sl.saturation.maxLeft + }); + this.picker.find('.colorpicker-saturation').css('backgroundColor', this.color.toHex(this.color.value.h, 1, 1, 1)); + this.picker.find('.colorpicker-alpha').css('backgroundColor', this.color.toHex()); + this.picker.find('.colorpicker-color, .colorpicker-color div').css('backgroundColor', this.color.toString(this.format)); + return val; + }, + updateComponent: function(val) { + val = val || this.color.toString(this.format); + if (this.component !== false) { + var icn = this.component.find('i').eq(0); + if (icn.length > 0) { + icn.css({ + 'backgroundColor': val + }); + } else { + this.component.css({ + 'backgroundColor': val + }); + } + } + return val; + }, + update: function(force) { + var val = this.updateComponent(); + if ((this.getValue(false) !== false) || (force === true)) { + // Update input/data only if the current value is not blank + this.updateInput(val); + this.updateData(val); + } + this.updatePicker(); + return val; + + }, + setValue: function(val) { // set color manually + this.color = new Color(val); + this.update(); + this.element.trigger({ + type: 'changeColor', + color: this.color, + value: val + }); + }, + getValue: function(defaultValue) { + defaultValue = (defaultValue === undefined) ? '#000000' : defaultValue; + var val; + if (this.hasInput()) { + val = this.input.val(); + } else { + val = this.element.data('color'); + } + if ((val === undefined) || (val === '') || (val === null)) { + // if not defined or empty, return default + val = defaultValue; + } + return val; + }, + hasInput: function() { + return (this.input !== false); + }, + isDisabled: function() { + if (this.hasInput()) { + return (this.input.prop('disabled') === true); + } + return false; + }, + disable: function() { + if (this.hasInput()) { + this.input.prop('disabled', true); + return true; + } + return false; + }, + enable: function() { + if (this.hasInput()) { + this.input.prop('disabled', false); + return true; + } + return false; + }, + currentSlider: null, + mousePointer: { + left: 0, + top: 0 + }, + mousedown: function(e) { + e.stopPropagation(); + e.preventDefault(); + + var target = $(e.target); + + //detect the slider and set the limits and callbacks + var zone = target.closest('div'); + var sl = this.options.horizontal ? this.options.slidersHorz : this.options.sliders; + if (!zone.is('.colorpicker')) { + if (zone.is('.colorpicker-saturation')) { + this.currentSlider = $.extend({}, sl.saturation); + } else if (zone.is('.colorpicker-hue')) { + this.currentSlider = $.extend({}, sl.hue); + } else if (zone.is('.colorpicker-alpha')) { + this.currentSlider = $.extend({}, sl.alpha); + } else { + return false; + } + var offset = zone.offset(); + //reference to guide's style + this.currentSlider.guide = zone.find('i')[0].style; + this.currentSlider.left = e.pageX - offset.left; + this.currentSlider.top = e.pageY - offset.top; + this.mousePointer = { + left: e.pageX, + top: e.pageY + }; + //trigger mousemove to move the guide to the current position + $(document).on({ + 'mousemove.colorpicker': $.proxy(this.mousemove, this), + 'mouseup.colorpicker': $.proxy(this.mouseup, this) + }).trigger('mousemove'); + } + return false; + }, + mousemove: function(e) { + e.stopPropagation(); + e.preventDefault(); + var left = Math.max( + 0, + Math.min( + this.currentSlider.maxLeft, + this.currentSlider.left + ((e.pageX || this.mousePointer.left) - this.mousePointer.left) + ) + ); + var top = Math.max( + 0, + Math.min( + this.currentSlider.maxTop, + this.currentSlider.top + ((e.pageY || this.mousePointer.top) - this.mousePointer.top) + ) + ); + this.currentSlider.guide.left = left + 'px'; + this.currentSlider.guide.top = top + 'px'; + if (this.currentSlider.callLeft) { + this.color[this.currentSlider.callLeft].call(this.color, left / 100); + } + if (this.currentSlider.callTop) { + this.color[this.currentSlider.callTop].call(this.color, top / 100); + } + this.update(true); + + this.element.trigger({ + type: 'changeColor', + color: this.color + }); + return false; + }, + mouseup: function(e) { + e.stopPropagation(); + e.preventDefault(); + $(document).off({ + 'mousemove.colorpicker': this.mousemove, + 'mouseup.colorpicker': this.mouseup + }); + return false; + }, + keyup: function(e) { + if ((e.keyCode === 38)) { + if (this.color.value.a < 1) { + this.color.value.a = Math.round((this.color.value.a + 0.01) * 100) / 100; + } + this.update(true); + } else if ((e.keyCode === 40)) { + if (this.color.value.a > 0) { + this.color.value.a = Math.round((this.color.value.a - 0.01) * 100) / 100; + } + this.update(true); + } else { + var val = this.input.val(); + this.color = new Color(val); + if (this.getValue(false) !== false) { + this.updateData(); + this.updateComponent(); + this.updatePicker(); + } + } + this.element.trigger({ + type: 'changeColor', + color: this.color, + value: val + }); + } + }; + + $.colorpicker = Colorpicker; + + $.fn.colorpicker = function(option) { + var pickerArgs = arguments; + + return this.each(function() { + var $this = $(this), + inst = $this.data('colorpicker'), + options = ((typeof option === 'object') ? option : {}); + if ((!inst) && (typeof option !== 'string')) { + $this.data('colorpicker', new Colorpicker(this, options)); + } else { + if (typeof option === 'string') { + inst[option].apply(inst, Array.prototype.slice.call(pickerArgs, 1)); + } + } + }); + }; + + $.fn.colorpicker.constructor = Colorpicker; + + })); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-confirmation/bootstrap-confirmation.js b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-confirmation/bootstrap-confirmation.js new file mode 100644 index 0000000..c7be151 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-confirmation/bootstrap-confirmation.js @@ -0,0 +1,240 @@ ++function ($) { + 'use strict'; + + //var for check event at body can have only one. + var event_body = false; + + // CONFIRMATION PUBLIC CLASS DEFINITION + // =============================== + var Confirmation = function (element, options) { + var that = this; + + this.init('confirmation', element, options); + + + $(element).on('show.bs.confirmation', function(e) { + that.options.onShow(e, this); + + $(this).addClass('open'); + + var options = that.options; + var all = options.all_selector; + + if(options.singleton) { + $(all+'.in').not(that.$element).confirmation('hide'); + } + }); + + $(element).on('hide.bs.confirmation', function(e) { + that.options.onHide(e, this); + + $(this).removeClass('open'); + }); + + $(element).on('shown.bs.confirmation', function(e) { + var options = that.options; + var all = options.all_selector; + + that.$element.on('click.dismiss.bs.confirmation', '[data-dismiss="confirmation"]', $.proxy(that.hide, that)); + + if(that.isPopout()) { + if(!event_body) { + event_body = $('body').on('click', function (e) { + if(that.$element.is(e.target)) return; + if(that.$element.has(e.target).length) return; + if($('.popover').has(e.target).length) return; + + that.$element.confirmation('hide'); + + $('body').unbind(e); + + event_body = false; + + return; + }); + } + } + }); + + $(element).on('click', function(e) { + e.preventDefault(); + }); + } + + if (!$.fn.popover || !$.fn.tooltip) throw new Error('Confirmation requires popover.js and tooltip.js'); + + Confirmation.DEFAULTS = $.extend({}, $.fn.popover.Constructor.DEFAULTS, { + placement : 'right', + title : 'Are you sure?', + btnOkClass : 'btn btn-sm btn-danger', + btnOkLabel : 'Delete', + btnOkIcon : 'glyphicon glyphicon-ok', + btnCancelClass : 'btn btn-sm btn-default', + btnCancelLabel : 'Cancel', + btnCancelIcon : 'glyphicon glyphicon-remove', + href : '#', + target : '_self', + singleton : true, + popout : true, + onShow : function(event, element){}, + onHide : function(event, element){}, + onConfirm : function(event, element){}, + onCancel : function(event, element){}, + template : '' + }); + + + // NOTE: CONFIRMATION EXTENDS popover.js + // ================================ + Confirmation.prototype = $.extend({}, $.fn.popover.Constructor.prototype); + + Confirmation.prototype.constructor = Confirmation; + + Confirmation.prototype.getDefaults = function () { + return Confirmation.DEFAULTS; + } + + Confirmation.prototype.setContent = function () { + var that = this; + var $tip = this.tip(); + var title = this.getTitle(); + var $btnOk = $tip.find('[data-apply="confirmation"]'); + var $btnCancel = $tip.find('[data-dismiss="confirmation"]'); + var options = this.options + + $btnOk.addClass(this.getBtnOkClass()) + .html(this.getBtnOkLabel()) + .prepend($('').addClass(this.getBtnOkIcon()), " ") + .attr('href', this.getHref()) + .attr('target', this.getTarget()) + .off('click').on('click', function(event) { + options.onConfirm(event, that.$element); + + that.$element.confirmation('hide'); + }); + + $btnCancel.addClass(this.getBtnCancelClass()) + .html(this.getBtnCancelLabel()) + .prepend($('').addClass(this.getBtnCancelIcon()), " ") + .off('click').on('click', function(event){ + options.onCancel(event, that.$element); + + that.$element.confirmation('hide'); + }); + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title); + + $tip.removeClass('fade top bottom left right in'); + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide(); + } + + Confirmation.prototype.getBtnOkClass = function () { + var $e = this.$element; + var o = this.options; + + return $e.attr('data-btnOkClass') || (typeof o.btnOkClass == 'function' ? o.btnOkClass.call($e[0]) : o.btnOkClass); + } + + Confirmation.prototype.getBtnOkLabel = function () { + var $e = this.$element; + var o = this.options; + + return $e.attr('data-btnOkLabel') || (typeof o.btnOkLabel == 'function' ? o.btnOkLabel.call($e[0]) : o.btnOkLabel); + } + + Confirmation.prototype.getBtnOkIcon = function () { + var $e = this.$element; + var o = this.options; + + return $e.attr('data-btnOkIcon') || (typeof o.btnOkIcon == 'function' ? o.btnOkIcon.call($e[0]) : o.btnOkIcon); + } + + Confirmation.prototype.getBtnCancelClass = function () { + var $e = this.$element; + var o = this.options; + + return $e.attr('data-btnCancelClass') || (typeof o.btnCancelClass == 'function' ? o.btnCancelClass.call($e[0]) : o.btnCancelClass); + } + + Confirmation.prototype.getBtnCancelLabel = function () { + var $e = this.$element; + var o = this.options; + + return $e.attr('data-btnCancelLabel') || (typeof o.btnCancelLabel == 'function' ? o.btnCancelLabel.call($e[0]) : o.btnCancelLabel); + } + + Confirmation.prototype.getBtnCancelIcon = function () { + var $e = this.$element; + var o = this.options; + + return $e.attr('data-btnCancelIcon') || (typeof o.btnCancelIcon == 'function' ? o.btnCancelIcon.call($e[0]) : o.btnCancelIcon); + } + + Confirmation.prototype.getHref = function () { + var $e = this.$element; + var o = this.options; + + return $e.attr('data-href') || (typeof o.href == 'function' ? o.href.call($e[0]) : o.href); + } + + Confirmation.prototype.getTarget = function () { + var $e = this.$element; + var o = this.options; + + return $e.attr('data-target') || (typeof o.target == 'function' ? o.target.call($e[0]) : o.target); + } + + Confirmation.prototype.isPopout = function () { + var popout; + var $e = this.$element; + var o = this.options; + + popout = $e.attr('data-popout') || (typeof o.popout == 'function' ? o.popout.call($e[0]) : o.popout); + + if(popout == 'false') popout = false; + + return popout + } + + + // CONFIRMATION PLUGIN DEFINITION + // ========================= + var old = $.fn.confirmation; + + $.fn.confirmation = function (option) { + var that = this; + + return this.each(function () { + var $this = $(this); + var data = $this.data('bs.confirmation'); + var options = typeof option == 'object' && option; + + options = options || {}; + options.all_selector = that.selector; + + if (!data && option == 'destroy') return; + if (!data) $this.data('bs.confirmation', (data = new Confirmation(this, options))); + if (typeof option == 'string') data[option](); + }); + } + + $.fn.confirmation.Constructor = Confirmation + + + // CONFIRMATION NO CONFLICT + // =================== + $.fn.confirmation.noConflict = function () { + $.fn.confirmation = old; + + return this; + } +}(jQuery); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-datepicker/css/datepicker3.css b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-datepicker/css/datepicker3.css new file mode 100644 index 0000000..aa78b1d --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-datepicker/css/datepicker3.css @@ -0,0 +1,790 @@ +/*! + * Datepicker for Bootstrap + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ +.datepicker { + padding: 4px; + border-radius: 4px; + direction: ltr; + /*.dow { + border-top: 1px solid #ddd !important; + }*/ +} +.datepicker-inline { + width: 220px; +} +.datepicker.datepicker-rtl { + direction: rtl; +} +.datepicker.datepicker-rtl table tr td span { + float: right; +} +.datepicker-dropdown { + top: 0; + left: 0; +} +.datepicker-dropdown:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-top: 0; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; +} +.datepicker-dropdown:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #fff; + border-top: 0; + position: absolute; +} +.datepicker-dropdown.datepicker-orient-left:before { + left: 6px; +} +.datepicker-dropdown.datepicker-orient-left:after { + left: 7px; +} +.datepicker-dropdown.datepicker-orient-right:before { + right: 6px; +} +.datepicker-dropdown.datepicker-orient-right:after { + right: 7px; +} +.datepicker-dropdown.datepicker-orient-top:before { + top: -7px; +} +.datepicker-dropdown.datepicker-orient-top:after { + top: -6px; +} +.datepicker-dropdown.datepicker-orient-bottom:before { + bottom: -7px; + border-bottom: 0; + border-top: 7px solid #999; +} +.datepicker-dropdown.datepicker-orient-bottom:after { + bottom: -6px; + border-bottom: 0; + border-top: 6px solid #fff; +} +.datepicker > div { + display: none; +} +.datepicker.days div.datepicker-days { + display: block; +} +.datepicker.months div.datepicker-months { + display: block; +} +.datepicker.years div.datepicker-years { + display: block; +} +.datepicker table { + margin: 0; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.datepicker table tr td, +.datepicker table tr th { + text-align: center; + width: 30px; + height: 30px; + border-radius: 4px; + border: none; +} +.table-striped .datepicker table tr td, +.table-striped .datepicker table tr th { + background-color: transparent; +} +.datepicker table tr td.day:hover, +.datepicker table tr td.day.focused { + background: #eeeeee; + cursor: pointer; +} +.datepicker table tr td.old, +.datepicker table tr td.new { + color: #999999; +} +.datepicker table tr td.disabled, +.datepicker table tr td.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td.today, +.datepicker table tr td.today:hover, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today.disabled:hover { + color: #000000; + background-color: #ffdb99; + border-color: #ffb733; +} +.datepicker table tr td.today:hover, +.datepicker table tr td.today:hover:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today:focus, +.datepicker table tr td.today:hover:focus, +.datepicker table tr td.today.disabled:focus, +.datepicker table tr td.today.disabled:hover:focus, +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.today, +.open .dropdown-toggle.datepicker table tr td.today:hover, +.open .dropdown-toggle.datepicker table tr td.today.disabled, +.open .dropdown-toggle.datepicker table tr td.today.disabled:hover { + color: #000000; + background-color: #ffcd70; + border-color: #f59e00; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.today, +.open .dropdown-toggle.datepicker table tr td.today:hover, +.open .dropdown-toggle.datepicker table tr td.today.disabled, +.open .dropdown-toggle.datepicker table tr td.today.disabled:hover { + background-image: none; +} +.datepicker table tr td.today.disabled, +.datepicker table tr td.today:hover.disabled, +.datepicker table tr td.today.disabled.disabled, +.datepicker table tr td.today.disabled:hover.disabled, +.datepicker table tr td.today[disabled], +.datepicker table tr td.today:hover[disabled], +.datepicker table tr td.today.disabled[disabled], +.datepicker table tr td.today.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td.today, +fieldset[disabled] .datepicker table tr td.today:hover, +fieldset[disabled] .datepicker table tr td.today.disabled, +fieldset[disabled] .datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today:hover.disabled:hover, +.datepicker table tr td.today.disabled.disabled:hover, +.datepicker table tr td.today.disabled:hover.disabled:hover, +.datepicker table tr td.today[disabled]:hover, +.datepicker table tr td.today:hover[disabled]:hover, +.datepicker table tr td.today.disabled[disabled]:hover, +.datepicker table tr td.today.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.today:hover, +fieldset[disabled] .datepicker table tr td.today:hover:hover, +fieldset[disabled] .datepicker table tr td.today.disabled:hover, +fieldset[disabled] .datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today.disabled:focus, +.datepicker table tr td.today:hover.disabled:focus, +.datepicker table tr td.today.disabled.disabled:focus, +.datepicker table tr td.today.disabled:hover.disabled:focus, +.datepicker table tr td.today[disabled]:focus, +.datepicker table tr td.today:hover[disabled]:focus, +.datepicker table tr td.today.disabled[disabled]:focus, +.datepicker table tr td.today.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.today:focus, +fieldset[disabled] .datepicker table tr td.today:hover:focus, +fieldset[disabled] .datepicker table tr td.today.disabled:focus, +fieldset[disabled] .datepicker table tr td.today.disabled:hover:focus, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today:hover.disabled:active, +.datepicker table tr td.today.disabled.disabled:active, +.datepicker table tr td.today.disabled:hover.disabled:active, +.datepicker table tr td.today[disabled]:active, +.datepicker table tr td.today:hover[disabled]:active, +.datepicker table tr td.today.disabled[disabled]:active, +.datepicker table tr td.today.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td.today:active, +fieldset[disabled] .datepicker table tr td.today:hover:active, +fieldset[disabled] .datepicker table tr td.today.disabled:active, +fieldset[disabled] .datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today:hover.disabled.active, +.datepicker table tr td.today.disabled.disabled.active, +.datepicker table tr td.today.disabled:hover.disabled.active, +.datepicker table tr td.today[disabled].active, +.datepicker table tr td.today:hover[disabled].active, +.datepicker table tr td.today.disabled[disabled].active, +.datepicker table tr td.today.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td.today.active, +fieldset[disabled] .datepicker table tr td.today:hover.active, +fieldset[disabled] .datepicker table tr td.today.disabled.active, +fieldset[disabled] .datepicker table tr td.today.disabled:hover.active { + background-color: #ffdb99; + border-color: #ffb733; +} +.datepicker table tr td.today:hover:hover { + color: #000; +} +.datepicker table tr td.today.active:hover { + color: #fff; +} +.datepicker table tr td.range, +.datepicker table tr td.range:hover, +.datepicker table tr td.range.disabled, +.datepicker table tr td.range.disabled:hover { + background: #eeeeee; + border-radius: 0; +} +.datepicker table tr td.range.today, +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today.disabled:hover { + color: #000000; + background-color: #f7ca77; + border-color: #f1a417; + border-radius: 0; +} +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today:hover:hover, +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today:focus, +.datepicker table tr td.range.today:hover:focus, +.datepicker table tr td.range.today.disabled:focus, +.datepicker table tr td.range.today.disabled:hover:focus, +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.range.today, +.open .dropdown-toggle.datepicker table tr td.range.today:hover, +.open .dropdown-toggle.datepicker table tr td.range.today.disabled, +.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { + color: #000000; + background-color: #f4bb51; + border-color: #bf800c; +} +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.range.today, +.open .dropdown-toggle.datepicker table tr td.range.today:hover, +.open .dropdown-toggle.datepicker table tr td.range.today.disabled, +.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { + background-image: none; +} +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today:hover.disabled, +.datepicker table tr td.range.today.disabled.disabled, +.datepicker table tr td.range.today.disabled:hover.disabled, +.datepicker table tr td.range.today[disabled], +.datepicker table tr td.range.today:hover[disabled], +.datepicker table tr td.range.today.disabled[disabled], +.datepicker table tr td.range.today.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td.range.today, +fieldset[disabled] .datepicker table tr td.range.today:hover, +fieldset[disabled] .datepicker table tr td.range.today.disabled, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today:hover.disabled:hover, +.datepicker table tr td.range.today.disabled.disabled:hover, +.datepicker table tr td.range.today.disabled:hover.disabled:hover, +.datepicker table tr td.range.today[disabled]:hover, +.datepicker table tr td.range.today:hover[disabled]:hover, +.datepicker table tr td.range.today.disabled[disabled]:hover, +.datepicker table tr td.range.today.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.range.today:hover, +fieldset[disabled] .datepicker table tr td.range.today:hover:hover, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today.disabled:focus, +.datepicker table tr td.range.today:hover.disabled:focus, +.datepicker table tr td.range.today.disabled.disabled:focus, +.datepicker table tr td.range.today.disabled:hover.disabled:focus, +.datepicker table tr td.range.today[disabled]:focus, +.datepicker table tr td.range.today:hover[disabled]:focus, +.datepicker table tr td.range.today.disabled[disabled]:focus, +.datepicker table tr td.range.today.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.range.today:focus, +fieldset[disabled] .datepicker table tr td.range.today:hover:focus, +fieldset[disabled] .datepicker table tr td.range.today.disabled:focus, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today:hover.disabled:active, +.datepicker table tr td.range.today.disabled.disabled:active, +.datepicker table tr td.range.today.disabled:hover.disabled:active, +.datepicker table tr td.range.today[disabled]:active, +.datepicker table tr td.range.today:hover[disabled]:active, +.datepicker table tr td.range.today.disabled[disabled]:active, +.datepicker table tr td.range.today.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td.range.today:active, +fieldset[disabled] .datepicker table tr td.range.today:hover:active, +fieldset[disabled] .datepicker table tr td.range.today.disabled:active, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today:hover.disabled.active, +.datepicker table tr td.range.today.disabled.disabled.active, +.datepicker table tr td.range.today.disabled:hover.disabled.active, +.datepicker table tr td.range.today[disabled].active, +.datepicker table tr td.range.today:hover[disabled].active, +.datepicker table tr td.range.today.disabled[disabled].active, +.datepicker table tr td.range.today.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td.range.today.active, +fieldset[disabled] .datepicker table tr td.range.today:hover.active, +fieldset[disabled] .datepicker table tr td.range.today.disabled.active, +fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active { + background-color: #f7ca77; + border-color: #f1a417; +} +.datepicker table tr td.selected, +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected.disabled:hover { + color: #ffffff; + background-color: #999999; + border-color: #555555; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected:hover:hover, +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected:focus, +.datepicker table tr td.selected:hover:focus, +.datepicker table tr td.selected.disabled:focus, +.datepicker table tr td.selected.disabled:hover:focus, +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.selected, +.open .dropdown-toggle.datepicker table tr td.selected:hover, +.open .dropdown-toggle.datepicker table tr td.selected.disabled, +.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover { + color: #ffffff; + background-color: #858585; + border-color: #373737; +} +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.selected, +.open .dropdown-toggle.datepicker table tr td.selected:hover, +.open .dropdown-toggle.datepicker table tr td.selected.disabled, +.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover { + background-image: none; +} +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected:hover.disabled, +.datepicker table tr td.selected.disabled.disabled, +.datepicker table tr td.selected.disabled:hover.disabled, +.datepicker table tr td.selected[disabled], +.datepicker table tr td.selected:hover[disabled], +.datepicker table tr td.selected.disabled[disabled], +.datepicker table tr td.selected.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td.selected, +fieldset[disabled] .datepicker table tr td.selected:hover, +fieldset[disabled] .datepicker table tr td.selected.disabled, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected:hover.disabled:hover, +.datepicker table tr td.selected.disabled.disabled:hover, +.datepicker table tr td.selected.disabled:hover.disabled:hover, +.datepicker table tr td.selected[disabled]:hover, +.datepicker table tr td.selected:hover[disabled]:hover, +.datepicker table tr td.selected.disabled[disabled]:hover, +.datepicker table tr td.selected.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.selected:hover, +fieldset[disabled] .datepicker table tr td.selected:hover:hover, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected.disabled:focus, +.datepicker table tr td.selected:hover.disabled:focus, +.datepicker table tr td.selected.disabled.disabled:focus, +.datepicker table tr td.selected.disabled:hover.disabled:focus, +.datepicker table tr td.selected[disabled]:focus, +.datepicker table tr td.selected:hover[disabled]:focus, +.datepicker table tr td.selected.disabled[disabled]:focus, +.datepicker table tr td.selected.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.selected:focus, +fieldset[disabled] .datepicker table tr td.selected:hover:focus, +fieldset[disabled] .datepicker table tr td.selected.disabled:focus, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected:hover.disabled:active, +.datepicker table tr td.selected.disabled.disabled:active, +.datepicker table tr td.selected.disabled:hover.disabled:active, +.datepicker table tr td.selected[disabled]:active, +.datepicker table tr td.selected:hover[disabled]:active, +.datepicker table tr td.selected.disabled[disabled]:active, +.datepicker table tr td.selected.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td.selected:active, +fieldset[disabled] .datepicker table tr td.selected:hover:active, +fieldset[disabled] .datepicker table tr td.selected.disabled:active, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected:hover.disabled.active, +.datepicker table tr td.selected.disabled.disabled.active, +.datepicker table tr td.selected.disabled:hover.disabled.active, +.datepicker table tr td.selected[disabled].active, +.datepicker table tr td.selected:hover[disabled].active, +.datepicker table tr td.selected.disabled[disabled].active, +.datepicker table tr td.selected.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td.selected.active, +fieldset[disabled] .datepicker table tr td.selected:hover.active, +fieldset[disabled] .datepicker table tr td.selected.disabled.active, +fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active { + background-color: #999999; + border-color: #555555; +} +.datepicker table tr td.active, +.datepicker table tr td.active:hover, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active.disabled:hover { + color: #ffffff; + background-color: #428bca; + border-color: #357ebd; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.active:hover, +.datepicker table tr td.active:hover:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active:focus, +.datepicker table tr td.active:hover:focus, +.datepicker table tr td.active.disabled:focus, +.datepicker table tr td.active.disabled:hover:focus, +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.active, +.open .dropdown-toggle.datepicker table tr td.active:hover, +.open .dropdown-toggle.datepicker table tr td.active.disabled, +.open .dropdown-toggle.datepicker table tr td.active.disabled:hover { + color: #ffffff; + background-color: #3276b1; + border-color: #285e8e; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td.active, +.open .dropdown-toggle.datepicker table tr td.active:hover, +.open .dropdown-toggle.datepicker table tr td.active.disabled, +.open .dropdown-toggle.datepicker table tr td.active.disabled:hover { + background-image: none; +} +.datepicker table tr td.active.disabled, +.datepicker table tr td.active:hover.disabled, +.datepicker table tr td.active.disabled.disabled, +.datepicker table tr td.active.disabled:hover.disabled, +.datepicker table tr td.active[disabled], +.datepicker table tr td.active:hover[disabled], +.datepicker table tr td.active.disabled[disabled], +.datepicker table tr td.active.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td.active, +fieldset[disabled] .datepicker table tr td.active:hover, +fieldset[disabled] .datepicker table tr td.active.disabled, +fieldset[disabled] .datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active:hover.disabled:hover, +.datepicker table tr td.active.disabled.disabled:hover, +.datepicker table tr td.active.disabled:hover.disabled:hover, +.datepicker table tr td.active[disabled]:hover, +.datepicker table tr td.active:hover[disabled]:hover, +.datepicker table tr td.active.disabled[disabled]:hover, +.datepicker table tr td.active.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td.active:hover, +fieldset[disabled] .datepicker table tr td.active:hover:hover, +fieldset[disabled] .datepicker table tr td.active.disabled:hover, +fieldset[disabled] .datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active.disabled:focus, +.datepicker table tr td.active:hover.disabled:focus, +.datepicker table tr td.active.disabled.disabled:focus, +.datepicker table tr td.active.disabled:hover.disabled:focus, +.datepicker table tr td.active[disabled]:focus, +.datepicker table tr td.active:hover[disabled]:focus, +.datepicker table tr td.active.disabled[disabled]:focus, +.datepicker table tr td.active.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td.active:focus, +fieldset[disabled] .datepicker table tr td.active:hover:focus, +fieldset[disabled] .datepicker table tr td.active.disabled:focus, +fieldset[disabled] .datepicker table tr td.active.disabled:hover:focus, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active:hover.disabled:active, +.datepicker table tr td.active.disabled.disabled:active, +.datepicker table tr td.active.disabled:hover.disabled:active, +.datepicker table tr td.active[disabled]:active, +.datepicker table tr td.active:hover[disabled]:active, +.datepicker table tr td.active.disabled[disabled]:active, +.datepicker table tr td.active.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td.active:active, +fieldset[disabled] .datepicker table tr td.active:hover:active, +fieldset[disabled] .datepicker table tr td.active.disabled:active, +fieldset[disabled] .datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active:hover.disabled.active, +.datepicker table tr td.active.disabled.disabled.active, +.datepicker table tr td.active.disabled:hover.disabled.active, +.datepicker table tr td.active[disabled].active, +.datepicker table tr td.active:hover[disabled].active, +.datepicker table tr td.active.disabled[disabled].active, +.datepicker table tr td.active.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td.active.active, +fieldset[disabled] .datepicker table tr td.active:hover.active, +fieldset[disabled] .datepicker table tr td.active.disabled.active, +fieldset[disabled] .datepicker table tr td.active.disabled:hover.active { + background-color: #428bca; + border-color: #357ebd; +} +.datepicker table tr td span { + display: block; + width: 23%; + height: 54px; + line-height: 54px; + float: left; + margin: 1%; + cursor: pointer; + border-radius: 4px; +} +.datepicker table tr td span:hover { + background: #eeeeee; +} +.datepicker table tr td span.disabled, +.datepicker table tr td span.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td span.active, +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active.disabled:hover { + color: #ffffff; + background-color: #428bca; + border-color: #357ebd; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active:hover:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active:focus, +.datepicker table tr td span.active:hover:focus, +.datepicker table tr td span.active.disabled:focus, +.datepicker table tr td span.active.disabled:hover:focus, +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td span.active, +.open .dropdown-toggle.datepicker table tr td span.active:hover, +.open .dropdown-toggle.datepicker table tr td span.active.disabled, +.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover { + color: #ffffff; + background-color: #3276b1; + border-color: #285e8e; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.open .dropdown-toggle.datepicker table tr td span.active, +.open .dropdown-toggle.datepicker table tr td span.active:hover, +.open .dropdown-toggle.datepicker table tr td span.active.disabled, +.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover { + background-image: none; +} +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active:hover.disabled, +.datepicker table tr td span.active.disabled.disabled, +.datepicker table tr td span.active.disabled:hover.disabled, +.datepicker table tr td span.active[disabled], +.datepicker table tr td span.active:hover[disabled], +.datepicker table tr td span.active.disabled[disabled], +.datepicker table tr td span.active.disabled:hover[disabled], +fieldset[disabled] .datepicker table tr td span.active, +fieldset[disabled] .datepicker table tr td span.active:hover, +fieldset[disabled] .datepicker table tr td span.active.disabled, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active:hover.disabled:hover, +.datepicker table tr td span.active.disabled.disabled:hover, +.datepicker table tr td span.active.disabled:hover.disabled:hover, +.datepicker table tr td span.active[disabled]:hover, +.datepicker table tr td span.active:hover[disabled]:hover, +.datepicker table tr td span.active.disabled[disabled]:hover, +.datepicker table tr td span.active.disabled:hover[disabled]:hover, +fieldset[disabled] .datepicker table tr td span.active:hover, +fieldset[disabled] .datepicker table tr td span.active:hover:hover, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active.disabled:focus, +.datepicker table tr td span.active:hover.disabled:focus, +.datepicker table tr td span.active.disabled.disabled:focus, +.datepicker table tr td span.active.disabled:hover.disabled:focus, +.datepicker table tr td span.active[disabled]:focus, +.datepicker table tr td span.active:hover[disabled]:focus, +.datepicker table tr td span.active.disabled[disabled]:focus, +.datepicker table tr td span.active.disabled:hover[disabled]:focus, +fieldset[disabled] .datepicker table tr td span.active:focus, +fieldset[disabled] .datepicker table tr td span.active:hover:focus, +fieldset[disabled] .datepicker table tr td span.active.disabled:focus, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active:hover.disabled:active, +.datepicker table tr td span.active.disabled.disabled:active, +.datepicker table tr td span.active.disabled:hover.disabled:active, +.datepicker table tr td span.active[disabled]:active, +.datepicker table tr td span.active:hover[disabled]:active, +.datepicker table tr td span.active.disabled[disabled]:active, +.datepicker table tr td span.active.disabled:hover[disabled]:active, +fieldset[disabled] .datepicker table tr td span.active:active, +fieldset[disabled] .datepicker table tr td span.active:hover:active, +fieldset[disabled] .datepicker table tr td span.active.disabled:active, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active:hover.disabled.active, +.datepicker table tr td span.active.disabled.disabled.active, +.datepicker table tr td span.active.disabled:hover.disabled.active, +.datepicker table tr td span.active[disabled].active, +.datepicker table tr td span.active:hover[disabled].active, +.datepicker table tr td span.active.disabled[disabled].active, +.datepicker table tr td span.active.disabled:hover[disabled].active, +fieldset[disabled] .datepicker table tr td span.active.active, +fieldset[disabled] .datepicker table tr td span.active:hover.active, +fieldset[disabled] .datepicker table tr td span.active.disabled.active, +fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { + background-color: #428bca; + border-color: #357ebd; +} +.datepicker table tr td span.old, +.datepicker table tr td span.new { + color: #999999; +} +.datepicker th.datepicker-switch { + width: 145px; +} +.datepicker thead tr:first-child th, +.datepicker tfoot tr th { + cursor: pointer; +} +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr th:hover { + background: #eeeeee; +} +.datepicker .cw { + font-size: 10px; + width: 12px; + padding: 0 2px 0 5px; + vertical-align: middle; +} +.datepicker thead tr:first-child th.cw { + cursor: default; + background-color: transparent; +} +.input-group.date .input-group-addon i { + cursor: pointer; + width: 16px; + height: 16px; +} +.input-daterange input { + text-align: center; +} +.input-daterange input:first-child { + border-radius: 3px 0 0 3px; +} +.input-daterange input:last-child { + border-radius: 0 3px 3px 0; +} +.input-daterange .input-group-addon { + width: auto; + min-width: 16px; + padding: 4px 5px; + font-weight: normal; + line-height: 1.428571429; + text-align: center; + text-shadow: 0 1px 0 #fff; + vertical-align: middle; + background-color: #eeeeee; + border: solid #cccccc; + border-width: 1px 0; + margin-left: -5px; + margin-right: -5px; +} +.datepicker.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + float: left; + display: none; + min-width: 160px; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 5px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + *border-right-width: 2px; + *border-bottom-width: 2px; + color: #333333; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + line-height: 1.428571429; +} +.datepicker.dropdown-menu th, +.datepicker.dropdown-menu td { + padding: 4px 5px; +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-datepicker/js/bootstrap-datepicker.js b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-datepicker/js/bootstrap-datepicker.js new file mode 100644 index 0000000..f17de6d --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-datepicker/js/bootstrap-datepicker.js @@ -0,0 +1,1671 @@ +/* ========================================================= + * bootstrap-datepicker.js + * Repo: https://github.com/eternicode/bootstrap-datepicker/ + * Demo: http://eternicode.github.io/bootstrap-datepicker/ + * Docs: http://bootstrap-datepicker.readthedocs.org/ + * Forked from http://www.eyecon.ro/bootstrap-datepicker + * ========================================================= + * Started by Stefan Petre; improvements by Andrew Rowls + contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + +(function($, undefined){ + + var $window = $(window); + + function UTCDate(){ + return new Date(Date.UTC.apply(Date, arguments)); + } + function UTCToday(){ + var today = new Date(); + return UTCDate(today.getFullYear(), today.getMonth(), today.getDate()); + } + function alias(method){ + return function(){ + return this[method].apply(this, arguments); + }; + } + + var DateArray = (function(){ + var extras = { + get: function(i){ + return this.slice(i)[0]; + }, + contains: function(d){ + // Array.indexOf is not cross-browser; + // $.inArray doesn't work with Dates + var val = d && d.valueOf(); + for (var i=0, l=this.length; i < l; i++) + if (this[i].valueOf() === val) + return i; + return -1; + }, + remove: function(i){ + this.splice(i,1); + }, + replace: function(new_array){ + if (!new_array) + return; + if (!$.isArray(new_array)) + new_array = [new_array]; + this.clear(); + this.push.apply(this, new_array); + }, + clear: function(){ + this.splice(0); + }, + copy: function(){ + var a = new DateArray(); + a.replace(this); + return a; + } + }; + + return function(){ + var a = []; + a.push.apply(a, arguments); + $.extend(a, extras); + return a; + }; + })(); + + + // Picker object + + var Datepicker = function(element, options){ + this.dates = new DateArray(); + this.viewDate = UTCToday(); + this.focusDate = null; + + this._process_options(options); + + this.element = $(element); + this.isInline = false; + this.isInput = this.element.is('input'); + this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false; + this.hasInput = this.component && this.element.find('input').length; + if (this.component && this.component.length === 0) + this.component = false; + + this.picker = $(DPGlobal.template); + this._buildEvents(); + this._attachEvents(); + + if (this.isInline){ + this.picker.addClass('datepicker-inline').appendTo(this.element); + } + else { + this.picker.addClass('datepicker-dropdown dropdown-menu'); + } + + if (this.o.rtl){ + this.picker.addClass('datepicker-rtl'); + } + + this.viewMode = this.o.startView; + + if (this.o.calendarWeeks) + this.picker.find('tfoot th.today') + .attr('colspan', function(i, val){ + return parseInt(val) + 1; + }); + + this._allow_update = false; + + this.setStartDate(this._o.startDate); + this.setEndDate(this._o.endDate); + this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled); + + this.fillDow(); + this.fillMonths(); + + this._allow_update = true; + + this.update(); + this.showMode(); + + if (this.isInline){ + this.show(); + } + }; + + Datepicker.prototype = { + constructor: Datepicker, + + _process_options: function(opts){ + // Store raw options for reference + this._o = $.extend({}, this._o, opts); + // Processed options + var o = this.o = $.extend({}, this._o); + + // Check if "de-DE" style date is available, if not language should + // fallback to 2 letter code eg "de" + var lang = o.language; + if (!dates[lang]){ + lang = lang.split('-')[0]; + if (!dates[lang]) + lang = defaults.language; + } + o.language = lang; + + switch (o.startView){ + case 2: + case 'decade': + o.startView = 2; + break; + case 1: + case 'year': + o.startView = 1; + break; + default: + o.startView = 0; + } + + switch (o.minViewMode){ + case 1: + case 'months': + o.minViewMode = 1; + break; + case 2: + case 'years': + o.minViewMode = 2; + break; + default: + o.minViewMode = 0; + } + + o.startView = Math.max(o.startView, o.minViewMode); + + // true, false, or Number > 0 + if (o.multidate !== true){ + o.multidate = Number(o.multidate) || false; + if (o.multidate !== false) + o.multidate = Math.max(0, o.multidate); + else + o.multidate = 1; + } + o.multidateSeparator = String(o.multidateSeparator); + + o.weekStart %= 7; + o.weekEnd = ((o.weekStart + 6) % 7); + + var format = DPGlobal.parseFormat(o.format); + if (o.startDate !== -Infinity){ + if (!!o.startDate){ + if (o.startDate instanceof Date) + o.startDate = this._local_to_utc(this._zero_time(o.startDate)); + else + o.startDate = DPGlobal.parseDate(o.startDate, format, o.language); + } + else { + o.startDate = -Infinity; + } + } + if (o.endDate !== Infinity){ + if (!!o.endDate){ + if (o.endDate instanceof Date) + o.endDate = this._local_to_utc(this._zero_time(o.endDate)); + else + o.endDate = DPGlobal.parseDate(o.endDate, format, o.language); + } + else { + o.endDate = Infinity; + } + } + + o.daysOfWeekDisabled = o.daysOfWeekDisabled||[]; + if (!$.isArray(o.daysOfWeekDisabled)) + o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/); + o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){ + return parseInt(d, 10); + }); + + var plc = String(o.orientation).toLowerCase().split(/\s+/g), + _plc = o.orientation.toLowerCase(); + plc = $.grep(plc, function(word){ + return (/^auto|left|right|top|bottom$/).test(word); + }); + o.orientation = {x: 'auto', y: 'auto'}; + if (!_plc || _plc === 'auto') + ; // no action + else if (plc.length === 1){ + switch (plc[0]){ + case 'top': + case 'bottom': + o.orientation.y = plc[0]; + break; + case 'left': + case 'right': + o.orientation.x = plc[0]; + break; + } + } + else { + _plc = $.grep(plc, function(word){ + return (/^left|right$/).test(word); + }); + o.orientation.x = _plc[0] || 'auto'; + + _plc = $.grep(plc, function(word){ + return (/^top|bottom$/).test(word); + }); + o.orientation.y = _plc[0] || 'auto'; + } + }, + _events: [], + _secondaryEvents: [], + _applyEvents: function(evs){ + for (var i=0, el, ch, ev; i < evs.length; i++){ + el = evs[i][0]; + if (evs[i].length === 2){ + ch = undefined; + ev = evs[i][1]; + } + else if (evs[i].length === 3){ + ch = evs[i][1]; + ev = evs[i][2]; + } + el.on(ev, ch); + } + }, + _unapplyEvents: function(evs){ + for (var i=0, el, ev, ch; i < evs.length; i++){ + el = evs[i][0]; + if (evs[i].length === 2){ + ch = undefined; + ev = evs[i][1]; + } + else if (evs[i].length === 3){ + ch = evs[i][1]; + ev = evs[i][2]; + } + el.off(ev, ch); + } + }, + _buildEvents: function(){ + if (this.isInput){ // single input + this._events = [ + [this.element, { + focus: $.proxy(this.show, this), + keyup: $.proxy(function(e){ + if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) + this.update(); + }, this), + keydown: $.proxy(this.keydown, this) + }] + ]; + } + else if (this.component && this.hasInput){ // component: input + button + this._events = [ + // For components that are not readonly, allow keyboard nav + [this.element.find('input'), { + focus: $.proxy(this.show, this), + keyup: $.proxy(function(e){ + if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) + this.update(); + }, this), + keydown: $.proxy(this.keydown, this) + }], + [this.component, { + click: $.proxy(this.show, this) + }] + ]; + } + else if (this.element.is('div')){ // inline datepicker + this.isInline = true; + } + else { + this._events = [ + [this.element, { + click: $.proxy(this.show, this) + }] + ]; + } + this._events.push( + // Component: listen for blur on element descendants + [this.element, '*', { + blur: $.proxy(function(e){ + this._focused_from = e.target; + }, this) + }], + // Input: listen for blur on element + [this.element, { + blur: $.proxy(function(e){ + this._focused_from = e.target; + }, this) + }] + ); + + this._secondaryEvents = [ + [this.picker, { + click: $.proxy(this.click, this) + }], + [$(window), { + resize: $.proxy(this.place, this) + }], + [$(document), { + 'mousedown touchstart': $.proxy(function(e){ + // Clicked outside the datepicker, hide it + if (!( + this.element.is(e.target) || + this.element.find(e.target).length || + this.picker.is(e.target) || + this.picker.find(e.target).length + )){ + this.hide(); + } + }, this) + }] + ]; + }, + _attachEvents: function(){ + this._detachEvents(); + this._applyEvents(this._events); + }, + _detachEvents: function(){ + this._unapplyEvents(this._events); + }, + _attachSecondaryEvents: function(){ + this._detachSecondaryEvents(); + this._applyEvents(this._secondaryEvents); + }, + _detachSecondaryEvents: function(){ + this._unapplyEvents(this._secondaryEvents); + }, + _trigger: function(event, altdate){ + var date = altdate || this.dates.get(-1), + local_date = this._utc_to_local(date); + + this.element.trigger({ + type: event, + date: local_date, + dates: $.map(this.dates, this._utc_to_local), + format: $.proxy(function(ix, format){ + if (arguments.length === 0){ + ix = this.dates.length - 1; + format = this.o.format; + } + else if (typeof ix === 'string'){ + format = ix; + ix = this.dates.length - 1; + } + format = format || this.o.format; + var date = this.dates.get(ix); + return DPGlobal.formatDate(date, format, this.o.language); + }, this) + }); + }, + + show: function(){ + if (!this.isInline) + this.picker.appendTo('body'); + this.picker.show(); + this.place(); + this._attachSecondaryEvents(); + this._trigger('show'); + }, + + hide: function(){ + if (this.isInline) + return; + if (!this.picker.is(':visible')) + return; + this.focusDate = null; + this.picker.hide().detach(); + this._detachSecondaryEvents(); + this.viewMode = this.o.startView; + this.showMode(); + + if ( + this.o.forceParse && + ( + this.isInput && this.element.val() || + this.hasInput && this.element.find('input').val() + ) + ) + this.setValue(); + this._trigger('hide'); + }, + + remove: function(){ + this.hide(); + this._detachEvents(); + this._detachSecondaryEvents(); + this.picker.remove(); + delete this.element.data().datepicker; + if (!this.isInput){ + delete this.element.data().date; + } + }, + + _utc_to_local: function(utc){ + return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000)); + }, + _local_to_utc: function(local){ + return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000)); + }, + _zero_time: function(local){ + return local && new Date(local.getFullYear(), local.getMonth(), local.getDate()); + }, + _zero_utc_time: function(utc){ + return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate())); + }, + + getDates: function(){ + return $.map(this.dates, this._utc_to_local); + }, + + getUTCDates: function(){ + return $.map(this.dates, function(d){ + return new Date(d); + }); + }, + + getDate: function(){ + return this._utc_to_local(this.getUTCDate()); + }, + + getUTCDate: function(){ + return new Date(this.dates.get(-1)); + }, + + setDates: function(){ + var args = $.isArray(arguments[0]) ? arguments[0] : arguments; + this.update.apply(this, args); + this._trigger('changeDate'); + this.setValue(); + }, + + setUTCDates: function(){ + var args = $.isArray(arguments[0]) ? arguments[0] : arguments; + this.update.apply(this, $.map(args, this._utc_to_local)); + this._trigger('changeDate'); + this.setValue(); + }, + + setDate: alias('setDates'), + setUTCDate: alias('setUTCDates'), + + setValue: function(){ + var formatted = this.getFormattedDate(); + if (!this.isInput){ + if (this.component){ + this.element.find('input').val(formatted).change(); + } + } + else { + this.element.val(formatted).change(); + } + }, + + getFormattedDate: function(format){ + if (format === undefined) + format = this.o.format; + + var lang = this.o.language; + return $.map(this.dates, function(d){ + return DPGlobal.formatDate(d, format, lang); + }).join(this.o.multidateSeparator); + }, + + setStartDate: function(startDate){ + this._process_options({startDate: startDate}); + this.update(); + this.updateNavArrows(); + }, + + setEndDate: function(endDate){ + this._process_options({endDate: endDate}); + this.update(); + this.updateNavArrows(); + }, + + setDaysOfWeekDisabled: function(daysOfWeekDisabled){ + this._process_options({daysOfWeekDisabled: daysOfWeekDisabled}); + this.update(); + this.updateNavArrows(); + }, + + place: function(){ + if (this.isInline) + return; + var calendarWidth = this.picker.outerWidth(), + calendarHeight = this.picker.outerHeight(), + visualPadding = 10, + windowWidth = $window.width(), + windowHeight = $window.height(), + scrollTop = $window.scrollTop(); + + var zIndex = parseInt(this.element.parents().filter(function(){ + return $(this).css('z-index') !== 'auto'; + }).first().css('z-index'))+10; + var offset = this.component ? this.component.parent().offset() : this.element.offset(); + var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); + var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); + var left = offset.left, + top = offset.top; + + this.picker.removeClass( + 'datepicker-orient-top datepicker-orient-bottom '+ + 'datepicker-orient-right datepicker-orient-left' + ); + + if (this.o.orientation.x !== 'auto'){ + this.picker.addClass('datepicker-orient-' + this.o.orientation.x); + if (this.o.orientation.x === 'right') + left -= calendarWidth - width; + } + // auto x orientation is best-placement: if it crosses a window + // edge, fudge it sideways + else { + // Default to left + this.picker.addClass('datepicker-orient-left'); + if (offset.left < 0) + left -= offset.left - visualPadding; + else if (offset.left + calendarWidth > windowWidth) + left = windowWidth - calendarWidth - visualPadding; + } + + // auto y orientation is best-situation: top or bottom, no fudging, + // decision based on which shows more of the calendar + var yorient = this.o.orientation.y, + top_overflow, bottom_overflow; + if (yorient === 'auto'){ + top_overflow = -scrollTop + offset.top - calendarHeight; + bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight); + if (Math.max(top_overflow, bottom_overflow) === bottom_overflow) + yorient = 'top'; + else + yorient = 'bottom'; + } + this.picker.addClass('datepicker-orient-' + yorient); + if (yorient === 'top') + top += height; + else + top -= calendarHeight + parseInt(this.picker.css('padding-top')); + + this.picker.css({ + top: top, + left: left, + zIndex: zIndex + }); + }, + + _allow_update: true, + update: function(){ + if (!this._allow_update) + return; + + var oldDates = this.dates.copy(), + dates = [], + fromArgs = false; + if (arguments.length){ + $.each(arguments, $.proxy(function(i, date){ + if (date instanceof Date) + date = this._local_to_utc(date); + dates.push(date); + }, this)); + fromArgs = true; + } + else { + dates = this.isInput + ? this.element.val() + : this.element.data('date') || this.element.find('input').val(); + if (dates && this.o.multidate) + dates = dates.split(this.o.multidateSeparator); + else + dates = [dates]; + delete this.element.data().date; + } + + dates = $.map(dates, $.proxy(function(date){ + return DPGlobal.parseDate(date, this.o.format, this.o.language); + }, this)); + dates = $.grep(dates, $.proxy(function(date){ + return ( + date < this.o.startDate || + date > this.o.endDate || + !date + ); + }, this), true); + this.dates.replace(dates); + + if (this.dates.length) + this.viewDate = new Date(this.dates.get(-1)); + else if (this.viewDate < this.o.startDate) + this.viewDate = new Date(this.o.startDate); + else if (this.viewDate > this.o.endDate) + this.viewDate = new Date(this.o.endDate); + + if (fromArgs){ + // setting date by clicking + this.setValue(); + } + else if (dates.length){ + // setting date by typing + if (String(oldDates) !== String(this.dates)) + this._trigger('changeDate'); + } + if (!this.dates.length && oldDates.length) + this._trigger('clearDate'); + + this.fill(); + }, + + fillDow: function(){ + var dowCnt = this.o.weekStart, + html = ']*>`([\s\S]*)`<\/pre>/gi, function(str, innerHTML) {
+ innerHTML = innerHTML.replace(/^\t+/g, ' '); // convert tabs to spaces (you know it makes sense)
+ innerHTML = innerHTML.replace(/\n/g, '\n ');
+ return '\n\n ' + innerHTML + '\n';
+ });
+
+ // Lists
+
+ // Escape numbers that could trigger an ol
+ // If there are more than three spaces before the code, it would be in a pre tag
+ // Make sure we are escaping the period not matching any character
+ string = string.replace(/^(\s{0,3}\d+)\. /g, '$1\\. ');
+
+ // Converts lists that have no child lists (of same type) first, then works it's way up
+ var noChildrenRegex = /<(ul|ol)\b[^>]*>(?:(?!]*>((?:(?!/gi; + while(string.match(deepest)) { + string = string.replace(deepest, function(str) { + return replaceBlockquotes(str); + }); + } + + function replaceBlockquotes(html) { + html = html.replace(/]*>([\s\S]*?)<\/blockquote>/gi, function(str, inner) { + inner = inner.replace(/^\s+|\s+$/g, ''); + inner = cleanUp(inner); + inner = inner.replace(/^/gm, '> '); + inner = inner.replace(/^(>([ \t]{2,}>)+)/gm, '> >'); + return inner; + }); + return html; + } + + function cleanUp(string) { + string = string.replace(/^[\t\r\n]+|[\t\r\n]+$/g, ''); // trim leading/trailing whitespace + string = string.replace(/\n\s+\n/g, '\n\n'); + string = string.replace(/\n{3,}/g, '\n\n'); // limit consecutive linebreaks to 2 + return string; + } + + return cleanUp(string); +}; + +if (typeof exports === 'object') { + exports.toMarkdown = toMarkdown; +} \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-maxlength/bootstrap-maxlength.js b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-maxlength/bootstrap-maxlength.js new file mode 100644 index 0000000..0d367bc --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-maxlength/bootstrap-maxlength.js @@ -0,0 +1,322 @@ +(function ($) { + 'use strict'; + + $.fn.extend({ + maxlength: function (options, callback) { + + var documentBody = $('body'), + defaults = { + alwaysShow: false, // if true the indicator it's always shown. + threshold: 10, // Represents how many chars left are needed to show up the counter + warningClass: 'label label-success', + limitReachedClass: 'label label-important', + separator: ' / ', + preText: '', + postText: '', + showMaxLength : true, + placement: 'bottom', + showCharsTyped: true, // show the number of characters typed and not the number of characters remaining + validate: false, // if the browser doesn't support the maxlength attribute, attempt to type more than + // the indicated chars, will be prevented. + utf8: false // counts using bytesize rather than length. eg: '£' is counted as 2 characters. + }; + + if ($.isFunction(options) && !callback) { + callback = options; + options = {}; + } + options = $.extend(defaults, options); + + /** + * Return the length of the specified input. + * + * @param input + * @return {number} + */ + function inputLength(input) { + var text = input.val(); + + // Remove all double-character (\r\n) linebreaks, so they're counted only once. + text = text.replace(new RegExp('\r?\n','g'), '\n'); + // var matches = text.match(/\n/g); + + var currentLength = 0; + + if (options.utf8) { + currentLength = utf8Length(input.val()); + } else { + currentLength = input.val().length; + } + return currentLength; + } + + /** + * Return the length of the specified input in UTF8 encoding. + * + * @param input + * @return {number} + */ + function utf8Length(string) { + var utf8length = 0; + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utf8length++; + } + else if((c > 127) && (c < 2048)) { + utf8length = utf8length+2; + } + else { + utf8length = utf8length+3; + } + } + return utf8length; + } + + /** + * Return true if the indicator should be showing up. + * + * @param input + * @param thereshold + * @param maxlength + * @return {number} + */ + function charsLeftThreshold(input, thereshold, maxlength) { + var output = true; + if (!options.alwaysShow && (maxlength - inputLength(input) > thereshold)) { + output = false; + } + return output; + } + + /** + * Returns how many chars are left to complete the fill up of the form. + * + * @param input + * @param maxlength + * @return {number} + */ + function remainingChars(input, maxlength) { + var length = maxlength - inputLength(input); + return length; + } + + /** + * When called displays the indicator. + * + * @param indicator + */ + function showRemaining(indicator) { + indicator.css({ + display: 'block' + }); + } + + /** + * When called shows the indicator. + * + * @param indicator + */ + function hideRemaining(indicator) { + indicator.css({ + display: 'none' + }); + } + + /** + * This function updates the value in the indicator + * + * @param maxLengthThisInput + * @param typedChars + * @return String + */ + function updateMaxLengthHTML(maxLengthThisInput, typedChars) { + var output = ''; + if (options.message){ + output = options.message.replace('%charsTyped%', typedChars) + .replace('%charsRemaining%', maxLengthThisInput - typedChars) + .replace('%charsTotal%', maxLengthThisInput); + } else { + if (options.preText) { + output += options.preText; + } + if (!options.showCharsTyped) { + output += maxLengthThisInput - typedChars; + } + else { + output += typedChars; + } + if (options.showMaxLength) { + output += options.separator + maxLengthThisInput; + } + if (options.postText) { + output += options.postText; + } + } + return output; + } + + /** + * This function updates the value of the counter in the indicator. + * Wants as parameters: the number of remaining chars, the element currently managed, + * the maxLength for the current input and the indicator generated for it. + * + * @param remaining + * @param currentInput + * @param maxLengthCurrentInput + * @param maxLengthIndicator + */ + function manageRemainingVisibility(remaining, currentInput, maxLengthCurrentInput, maxLengthIndicator) { + maxLengthIndicator.html(updateMaxLengthHTML(maxLengthCurrentInput, (maxLengthCurrentInput - remaining))); + + if (remaining > 0) { + if (charsLeftThreshold(currentInput, options.threshold, maxLengthCurrentInput)) { + showRemaining(maxLengthIndicator.removeClass(options.limitReachedClass).addClass(options.warningClass)); + } else { + hideRemaining(maxLengthIndicator); + } + } else { + showRemaining(maxLengthIndicator.removeClass(options.warningClass).addClass(options.limitReachedClass)); + } + } + + /** + * This function returns an object containing all the + * informations about the position of the current input + * + * @param currentInput + * @return object {bottom height left right top width} + * + */ + function getPosition(currentInput) { + var el = currentInput[0]; + return $.extend({}, (typeof el.getBoundingClientRect === 'function') ? el.getBoundingClientRect() : { + width: el.offsetWidth, + height: el.offsetHeight + }, currentInput.offset()); + } + + /** + * This function places the maxLengthIndicator at the + * top / bottom / left / right of the currentInput + * + * @param currentInput + * @param maxLengthIndicator + * @return null + * + */ + function place(currentInput, maxLengthIndicator) { + var pos = getPosition(currentInput), + inputOuter = currentInput.outerWidth(), + outerWidth = maxLengthIndicator.outerWidth(), + actualWidth = maxLengthIndicator.width(), + actualHeight = maxLengthIndicator.height(); + + switch (options.placement) { + case 'bottom': + maxLengthIndicator.css({top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}); + break; + case 'top': + maxLengthIndicator.css({top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}); + break; + case 'left': + maxLengthIndicator.css({top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}); + break; + case 'right': + maxLengthIndicator.css({top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}); + break; + case 'bottom-right': + maxLengthIndicator.css({top: pos.top + pos.height, left: pos.left + pos.width}); + break; + case 'top-right': + maxLengthIndicator.css({top: pos.top - actualHeight, left: pos.left + inputOuter}); + break; + case 'top-left': + maxLengthIndicator.css({top: pos.top - actualHeight, left: pos.left - outerWidth}); + break; + case 'bottom-left': + maxLengthIndicator.css({top: pos.top + currentInput.outerHeight(), left: pos.left - outerWidth}); + break; + case 'centered-right': + maxLengthIndicator.css({top: pos.top + (actualHeight / 2), left: pos.left + inputOuter - outerWidth - 3}); + break; + } + } + + /** + * This function retrieves the maximum length of currentInput + * + * @param currentInput + * @return {number} + * + */ + function getMaxLength(currentInput) { + return currentInput.attr('maxlength') || currentInput.attr('size'); + } + + return this.each(function() { + + var currentInput = $(this), + maxLengthCurrentInput, + maxLengthIndicator; + + $(window).resize(function() { + if(maxLengthIndicator) { + place(currentInput, maxLengthIndicator); + } + }); + + currentInput.focus(function () { + var maxlengthContent = updateMaxLengthHTML(maxLengthCurrentInput, '0'); + maxLengthCurrentInput = getMaxLength(currentInput); + + if (!maxLengthIndicator) { + maxLengthIndicator = $('').css({ + display: 'none', + position: 'absolute', + whiteSpace: 'nowrap', + zIndex: 1099 + }).html(maxlengthContent); + } + + + // We need to detect resizes if we are dealing with a textarea: + if (currentInput.is('textarea')) { + currentInput.data('maxlenghtsizex', currentInput.outerWidth()); + currentInput.data('maxlenghtsizey', currentInput.outerHeight()); + + currentInput.mouseup(function() { + if (currentInput.outerWidth() !== currentInput.data('maxlenghtsizex') || currentInput.outerHeight() !== currentInput.data('maxlenghtsizey')) { + place(currentInput, maxLengthIndicator); + } + + currentInput.data('maxlenghtsizex', currentInput.outerWidth()); + currentInput.data('maxlenghtsizey', currentInput.outerHeight()); + }); + } + + documentBody.append(maxLengthIndicator); + + var remaining = remainingChars(currentInput, getMaxLength(currentInput)); + manageRemainingVisibility(remaining, currentInput, maxLengthCurrentInput, maxLengthIndicator); + place(currentInput, maxLengthIndicator); + }); + + currentInput.blur(function() { + maxLengthIndicator.remove(); + }); + + currentInput.keyup(function() { + var remaining = remainingChars(currentInput, getMaxLength(currentInput)), + output = true; + if (options.validate && remaining < 0) { + output = false; + } else { + manageRemainingVisibility(remaining, currentInput, maxLengthCurrentInput, maxLengthIndicator); + } + return output; + }); + }); + } + }); +}(jQuery)); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-multiselect/bootstrap-multiselect.css b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-multiselect/bootstrap-multiselect.css new file mode 100644 index 0000000..4d8bd5c --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-multiselect/bootstrap-multiselect.css @@ -0,0 +1 @@ +.multiselect-container{position:absolute;list-style-type:none;margin:0;padding:0}.multiselect-container .input-group{margin:5px}.multiselect-container>li{padding:0}.multiselect-container>li>a.multiselect-all label{font-weight:700}.multiselect-container>li>label.multiselect-group{margin:0;padding:3px 20px;height:100%;font-weight:700}.multiselect-container>li>a{padding:0}.multiselect-container>li>a>label{margin:0;height:100%;cursor:pointer;font-weight:400;padding:3px 20px 3px 40px}.multiselect-container>li>a>label.radio,.multiselect-container>li>a>label.checkbox{margin:0}.multiselect-container>li>a>label>input[type=checkbox]{margin-bottom:5px}.btn-group>.btn-group:nth-child(2)>.multiselect.btn{border-top-left-radius:4px;border-bottom-left-radius:4px} \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-multiselect/bootstrap-multiselect.js b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-multiselect/bootstrap-multiselect.js new file mode 100644 index 0000000..8520424 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-multiselect/bootstrap-multiselect.js @@ -0,0 +1,994 @@ +/** + * bootstrap-multiselect.js + * https://github.com/davidstutz/bootstrap-multiselect + * + * Copyright 2012 - 2014 David Stutz + * + * Dual licensed under the BSD-3-Clause and the Apache License, Version 2.0. + */ +!function($) { + + "use strict";// jshint ;_; + + if (typeof ko !== 'undefined' && ko.bindingHandlers && !ko.bindingHandlers.multiselect) { + ko.bindingHandlers.multiselect = { + + init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + + var listOfSelectedItems = allBindingsAccessor().selectedOptions, + config = ko.utils.unwrapObservable(valueAccessor()); + + $(element).multiselect(config); + + if (isObservableArray(listOfSelectedItems)) { + // Subscribe to the selectedOptions: ko.observableArray + listOfSelectedItems.subscribe(function (changes) { + var addedArray = [], deletedArray = []; + changes.forEach(function (change) { + switch (change.status) { + case 'added': + addedArray.push(change.value); + break; + case 'deleted': + deletedArray.push(change.value); + break; + } + }); + if (addedArray.length > 0) { + $(element).multiselect('select', addedArray); + }; + if (deletedArray.length > 0) { + $(element).multiselect('deselect', deletedArray); + }; + }, null, "arrayChange"); + } + }, + + update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + + var listOfItems = allBindingsAccessor().options, + ms = $(element).data('multiselect'), + config = ko.utils.unwrapObservable(valueAccessor()); + + if (isObservableArray(listOfItems)) { + // Subscribe to the options: ko.observableArray incase it changes later + listOfItems.subscribe(function (theArray) { + $(element).multiselect('rebuild'); + }); + } + + if (!ms) { + $(element).multiselect(config); + } + else { + ms.updateOriginalOptions(); + } + } + }; + } + + function isObservableArray(obj) { + return ko.isObservable(obj) && !(obj.destroyAll === undefined); + } + + /** + * Constructor to create a new multiselect using the given select. + * + * @param {jQuery} select + * @param {Object} options + * @returns {Multiselect} + */ + function Multiselect(select, options) { + + this.options = this.mergeOptions(options); + this.$select = $(select); + + // Initialization. + // We have to clone to create a new reference. + this.originalOptions = this.$select.clone()[0].options; + this.query = ''; + this.searchTimeout = null; + + this.options.multiple = this.$select.attr('multiple') === "multiple"; + this.options.onChange = $.proxy(this.options.onChange, this); + this.options.onDropdownShow = $.proxy(this.options.onDropdownShow, this); + this.options.onDropdownHide = $.proxy(this.options.onDropdownHide, this); + + // Build select all if enabled. + this.buildContainer(); + this.buildButton(); + this.buildSelectAll(); + this.buildDropdown(); + this.buildDropdownOptions(); + this.buildFilter(); + + this.updateButtonText(); + this.updateSelectAll(); + + this.$select.hide().after(this.$container); + }; + + Multiselect.prototype = { + + defaults: { + /** + * Default text function will either print 'None selected' in case no + * option is selected or a list of the selected options up to a length of 3 selected options. + * + * @param {jQuery} options + * @param {jQuery} select + * @returns {String} + */ + buttonText: function(options, select) { + if (options.length === 0) { + return this.nonSelectedText + ' '; + } + else { + if (options.length > this.numberDisplayed) { + return options.length + ' ' + this.nSelectedText + ' '; + } + else { + var selected = ''; + options.each(function() { + var label = ($(this).attr('label') !== undefined) ? $(this).attr('label') : $(this).html(); + + selected += label + ', '; + }); + return selected.substr(0, selected.length - 2) + ' '; + } + } + }, + /** + * Updates the title of the button similar to the buttonText function. + * @param {jQuery} options + * @param {jQuery} select + * @returns {@exp;selected@call;substr} + */ + buttonTitle: function(options, select) { + if (options.length === 0) { + return this.nonSelectedText; + } + else { + var selected = ''; + options.each(function () { + selected += $(this).text() + ', '; + }); + return selected.substr(0, selected.length - 2); + } + }, + /** + * Create a label. + * + * @param {jQuery} element + * @returns {String} + */ + label: function(element){ + return $(element).attr('label') || $(element).html(); + }, + /** + * Triggered on change of the multiselect. + * Not triggered when selecting/deselecting options manually. + * + * @param {jQuery} option + * @param {Boolean} checked + */ + onChange : function(option, checked) { + + }, + /** + * Triggered when the dropdown is shown. + * + * @param {jQuery} event + */ + onDropdownShow: function(event) { + + }, + /** + * Triggered when the dropdown is hidden. + * + * @param {jQuery} event + */ + onDropdownHide: function(event) { + + }, + buttonClass: 'btn btn-default', + dropRight: false, + selectedClass: 'active', + buttonWidth: 'auto', + buttonContainer: '', + // Maximum height of the dropdown menu. + // If maximum height is exceeded a scrollbar will be displayed. + maxHeight: false, + checkboxName: 'multiselect', + includeSelectAllOption: false, + includeSelectAllIfMoreThan: 0, + selectAllText: ' Select all', + selectAllValue: 'multiselect-all', + enableFiltering: false, + enableCaseInsensitiveFiltering: false, + filterPlaceholder: 'Search', + // possible options: 'text', 'value', 'both' + filterBehavior: 'text', + preventInputChangeEvent: false, + nonSelectedText: 'None selected', + nSelectedText: 'selected', + numberDisplayed: 3, + templates: { + button: '', + ul: '', + filter: '', + li: '', + divider: '', + liGroup: '' + } + }, + + constructor: Multiselect, + + /** + * Builds the container of the multiselect. + */ + buildContainer: function() { + this.$container = $(this.options.buttonContainer); + this.$container.on('show.bs.dropdown', this.options.onDropdownShow); + this.$container.on('hide.bs.dropdown', this.options.onDropdownHide); + }, + + /** + * Builds the button of the multiselect. + */ + buildButton: function() { + this.$button = $(this.options.templates.button).addClass(this.options.buttonClass); + + // Adopt active state. + if (this.$select.prop('disabled')) { + this.disable(); + } + else { + this.enable(); + } + + // Manually add button width if set. + if (this.options.buttonWidth && this.options.buttonWidth !== 'auto') { + this.$button.css({ + 'width' : this.options.buttonWidth + }); + } + + // Keep the tab index from the select. + var tabindex = this.$select.attr('tabindex'); + if (tabindex) { + this.$button.attr('tabindex', tabindex); + } + + this.$container.prepend(this.$button); + }, + + /** + * Builds the ul representing the dropdown menu. + */ + buildDropdown: function() { + + // Build ul. + this.$ul = $(this.options.templates.ul); + + if (this.options.dropRight) { + this.$ul.addClass('pull-right'); + } + + // Set max height of dropdown menu to activate auto scrollbar. + if (this.options.maxHeight) { + // TODO: Add a class for this option to move the css declarations. + this.$ul.css({ + 'max-height': this.options.maxHeight + 'px', + 'overflow-y': 'auto', + 'overflow-x': 'hidden' + }); + } + + this.$container.append(this.$ul); + }, + + /** + * Build the dropdown options and binds all nessecary events. + * Uses createDivider and createOptionValue to create the necessary options. + */ + buildDropdownOptions: function() { + + this.$select.children().each($.proxy(function(index, element) { + + // Support optgroups and options without a group simultaneously. + var tag = $(element).prop('tagName') + .toLowerCase(); + + if (tag === 'optgroup') { + this.createOptgroup(element); + } + else if (tag === 'option') { + + if ($(element).data('role') === 'divider') { + this.createDivider(); + } + else { + this.createOptionValue(element); + } + + } + + // Other illegal tags will be ignored. + }, this)); + + // Bind the change event on the dropdown elements. + $('li input', this.$ul).on('change', $.proxy(function(event) { + var $target = $(event.target); + + var checked = $target.prop('checked') || false; + var isSelectAllOption = $target.val() === this.options.selectAllValue; + + // Apply or unapply the configured selected class. + if (this.options.selectedClass) { + if (checked) { + $target.parents('li') + .addClass(this.options.selectedClass); + } + else { + $target.parents('li') + .removeClass(this.options.selectedClass); + } + } + + // Get the corresponding option. + var value = $target.val(); + var $option = this.getOptionByValue(value); + + var $optionsNotThis = $('option', this.$select).not($option); + var $checkboxesNotThis = $('input', this.$container).not($target); + + if (isSelectAllOption) { + var values = []; + + // Select the visible checkboxes except the "select-all" and possible divider. + var availableInputs = $('li input[value!="' + this.options.selectAllValue + '"][data-role!="divider"]', this.$ul).filter(':visible'); + for (var i = 0, j = availableInputs.length; i < j; i++) { + values.push(availableInputs[i].value); + } + + if (checked) { + this.select(values); + } + else { + this.deselect(values); + } + } + + if (checked) { + $option.prop('selected', true); + + if (this.options.multiple) { + // Simply select additional option. + $option.prop('selected', true); + } + else { + // Unselect all other options and corresponding checkboxes. + if (this.options.selectedClass) { + $($checkboxesNotThis).parents('li').removeClass(this.options.selectedClass); + } + + $($checkboxesNotThis).prop('checked', false); + $optionsNotThis.prop('selected', false); + + // It's a single selection, so close. + this.$button.click(); + } + + if (this.options.selectedClass === "active") { + $optionsNotThis.parents("a").css("outline", ""); + } + } + else { + // Unselect option. + $option.prop('selected', false); + } + + this.$select.change(); + this.options.onChange($option, checked); + + this.updateButtonText(); + this.updateSelectAll(); + + if(this.options.preventInputChangeEvent) { + return false; + } + }, this)); + + $('li a', this.$ul).on('touchstart click', function(event) { + event.stopPropagation(); + + var $target = $(event.target); + + if (event.shiftKey) { + var checked = $target.prop('checked') || false; + + if (checked) { + var prev = $target.parents('li:last') + .siblings('li[class="active"]:first'); + + var currentIdx = $target.parents('li') + .index(); + var prevIdx = prev.index(); + + if (currentIdx > prevIdx) { + $target.parents("li:last").prevUntil(prev).each( + function() { + $(this).find("input:first").prop("checked", true) + .trigger("change"); + } + ); + } + else { + $target.parents("li:last").nextUntil(prev).each( + function() { + $(this).find("input:first").prop("checked", true) + .trigger("change"); + } + ); + } + } + } + + $target.blur(); + }); + + // Keyboard support. + this.$container.on('keydown', $.proxy(function(event) { + if ($('input[type="text"]', this.$container).is(':focus')) { + return; + } + if ((event.keyCode === 9 || event.keyCode === 27) + && this.$container.hasClass('open')) { + + // Close on tab or escape. + this.$button.click(); + } + else { + var $items = $(this.$container).find("li:not(.divider):visible a"); + + if (!$items.length) { + return; + } + + var index = $items.index($items.filter(':focus')); + + // Navigation up. + if (event.keyCode === 38 && index > 0) { + index--; + } + // Navigate down. + else if (event.keyCode === 40 && index < $items.length - 1) { + index++; + } + else if (!~index) { + index = 0; + } + + var $current = $items.eq(index); + $current.focus(); + + if (event.keyCode === 32 || event.keyCode === 13) { + var $checkbox = $current.find('input'); + + $checkbox.prop("checked", !$checkbox.prop("checked")); + $checkbox.change(); + } + + event.stopPropagation(); + event.preventDefault(); + } + }, this)); + }, + + /** + * Create an option using the given select option. + * + * @param {jQuery} element + */ + createOptionValue: function(element) { + if ($(element).is(':selected')) { + $(element).prop('selected', true); + } + + // Support the label attribute on options. + var label = this.options.label(element); + var value = $(element).val(); + var inputType = this.options.multiple ? "checkbox" : "radio"; + + var $li = $(this.options.templates.li); + $('label', $li).addClass(inputType); + $('label', $li).append(''); + + var selected = $(element).prop('selected') || false; + var $checkbox = $('input', $li); + $checkbox.val(value); + + if (value === this.options.selectAllValue) { + $checkbox.parent().parent() + .addClass('multiselect-all'); + } + + $('label', $li).append(" " + label); + + this.$ul.append($li); + + if ($(element).is(':disabled')) { + $checkbox.attr('disabled', 'disabled') + .prop('disabled', true) + .parents('li') + .addClass('disabled'); + } + + $checkbox.prop('checked', selected); + + if (selected && this.options.selectedClass) { + $checkbox.parents('li') + .addClass(this.options.selectedClass); + } + }, + + /** + * Creates a divider using the given select option. + * + * @param {jQuery} element + */ + createDivider: function(element) { + var $divider = $(this.options.templates.divider); + this.$ul.append($divider); + }, + + /** + * Creates an optgroup. + * + * @param {jQuery} group + */ + createOptgroup: function(group) { + var groupName = $(group).prop('label'); + + // Add a header for the group. + var $li = $(this.options.templates.liGroup); + $('label', $li).text(groupName); + + this.$ul.append($li); + + if ($(group).is(':disabled')) { + $li.addClass('disabled'); + } + + // Add the options of the group. + $('option', group).each($.proxy(function(index, element) { + this.createOptionValue(element); + }, this)); + }, + + /** + * Build the selct all. + * Checks if a select all ahs already been created. + */ + buildSelectAll: function() { + var alreadyHasSelectAll = this.hasSelectAll(); + + if (!alreadyHasSelectAll && this.options.includeSelectAllOption && this.options.multiple + && $('option[data-role!="divider"]', this.$select).length > this.options.includeSelectAllIfMoreThan) { + + // Check whether to add a divider after the select all. + if (this.options.includeSelectAllDivider) { + this.$select.prepend(''); + } + }, + + /** + * Builds the filter. + */ + buildFilter: function() { + + // Build filter if filtering OR case insensitive filtering is enabled and the number of options exceeds (or equals) enableFilterLength. + if (this.options.enableFiltering || this.options.enableCaseInsensitiveFiltering) { + var enableFilterLength = Math.max(this.options.enableFiltering, this.options.enableCaseInsensitiveFiltering); + + if (this.$select.find('option').length >= enableFilterLength) { + + this.$filter = $(this.options.templates.filter); + $('input', this.$filter).attr('placeholder', this.options.filterPlaceholder); + this.$ul.prepend(this.$filter); + + this.$filter.val(this.query).on('click', function(event) { + event.stopPropagation(); + }).on('input keydown', $.proxy(function(event) { + // This is useful to catch "keydown" events after the browser has updated the control. + clearTimeout(this.searchTimeout); + + this.searchTimeout = this.asyncFunction($.proxy(function() { + + if (this.query !== event.target.value) { + this.query = event.target.value; + + $.each($('li', this.$ul), $.proxy(function(index, element) { + var value = $('input', element).val(); + var text = $('label', element).text(); + + var filterCandidate = ''; + if ((this.options.filterBehavior === 'text')) { + filterCandidate = text; + } + else if ((this.options.filterBehavior === 'value')) { + filterCandidate = value; + } + else if (this.options.filterBehavior === 'both') { + filterCandidate = text + '\n' + value; + } + + if (value !== this.options.selectAllValue && text) { + // by default lets assume that element is not + // interesting for this search + var showElement = false; + + if (this.options.enableCaseInsensitiveFiltering && filterCandidate.toLowerCase().indexOf(this.query.toLowerCase()) > -1) { + showElement = true; + } + else if (filterCandidate.indexOf(this.query) > -1) { + showElement = true; + } + + if (showElement) { + $(element).show(); + } + else { + $(element).hide(); + } + } + }, this)); + } + + // TODO: check whether select all option needs to be updated. + }, this), 300, this); + }, this)); + } + } + }, + + /** + * Unbinds the whole plugin. + */ + destroy: function() { + this.$container.remove(); + this.$select.show(); + this.$select.data('multiselect', null); + }, + + /** + * Refreshs the multiselect based on the selected options of the select. + */ + refresh: function() { + $('option', this.$select).each($.proxy(function(index, element) { + var $input = $('li input', this.$ul).filter(function() { + return $(this).val() === $(element).val(); + }); + + if ($(element).is(':selected')) { + $input.prop('checked', true); + + if (this.options.selectedClass) { + $input.parents('li') + .addClass(this.options.selectedClass); + } + } + else { + $input.prop('checked', false); + + if (this.options.selectedClass) { + $input.parents('li') + .removeClass(this.options.selectedClass); + } + } + + if ($(element).is(":disabled")) { + $input.attr('disabled', 'disabled') + .prop('disabled', true) + .parents('li') + .addClass('disabled'); + } + else { + $input.prop('disabled', false) + .parents('li') + .removeClass('disabled'); + } + }, this)); + + this.updateButtonText(); + this.updateSelectAll(); + }, + + /** + * Select all options of the given values. + * + * @param {Array} selectValues + */ + select: function(selectValues) { + if(!$.isArray(selectValues)) { + selectValues = [selectValues]; + } + + for (var i = 0; i < selectValues.length; i++) { + var value = selectValues[i]; + + var $option = this.getOptionByValue(value); + var $checkbox = this.getInputByValue(value); + + if (this.options.selectedClass) { + $checkbox.parents('li') + .addClass(this.options.selectedClass); + } + + $checkbox.prop('checked', true); + $option.prop('selected', true); + } + + this.updateButtonText(); + }, + + /** + * Clears all selected items + * + */ + clearSelection: function () { + + var selected = this.getSelected(); + + if (selected.length) { + + var arry = []; + + for (var i = 0; i < selected.length; i = i + 1) { + arry.push(selected[i].value); + } + + this.deselect(arry); + this.$select.change(); + } + }, + + /** + * Deselects all options of the given values. + * + * @param {Array} deselectValues + */ + deselect: function(deselectValues) { + if(!$.isArray(deselectValues)) { + deselectValues = [deselectValues]; + } + + for (var i = 0; i < deselectValues.length; i++) { + + var value = deselectValues[i]; + + var $option = this.getOptionByValue(value); + var $checkbox = this.getInputByValue(value); + + if (this.options.selectedClass) { + $checkbox.parents('li') + .removeClass(this.options.selectedClass); + } + + $checkbox.prop('checked', false); + $option.prop('selected', false); + } + + this.updateButtonText(); + }, + + /** + * Rebuild the plugin. + * Rebuilds the dropdown, the filter and the select all option. + */ + rebuild: function() { + this.$ul.html(''); + + // Remove select all option in select. + $('option[value="' + this.options.selectAllValue + '"]', this.$select).remove(); + + // Important to distinguish between radios and checkboxes. + this.options.multiple = this.$select.attr('multiple') === "multiple"; + + this.buildSelectAll(); + this.buildDropdownOptions(); + this.buildFilter(); + + this.updateButtonText(); + this.updateSelectAll(); + }, + + /** + * The provided data will be used to build the dropdown. + * + * @param {Array} dataprovider + */ + dataprovider: function(dataprovider) { + var optionDOM = ""; + dataprovider.forEach(function (option) { + optionDOM += ''; + }); + + this.$select.html(optionDOM); + this.rebuild(); + }, + + /** + * Enable the multiselect. + */ + enable: function() { + this.$select.prop('disabled', false); + this.$button.prop('disabled', false) + .removeClass('disabled'); + }, + + /** + * Disable the multiselect. + */ + disable: function() { + this.$select.prop('disabled', true); + this.$button.prop('disabled', true) + .addClass('disabled'); + }, + + /** + * Set the options. + * + * @param {Array} options + */ + setOptions: function(options) { + this.options = this.mergeOptions(options); + }, + + /** + * Merges the given options with the default options. + * + * @param {Array} options + * @returns {Array} + */ + mergeOptions: function(options) { + return $.extend(true, {}, this.defaults, options); + }, + + /** + * Checks whether a select all option is present. + * + * @returns {Boolean} + */ + hasSelectAll: function() { + return $('option[value="' + this.options.selectAllValue + '"]', this.$select).length > 0; + }, + + /** + * Updates the select all option based on the currently selected options. + */ + updateSelectAll: function() { + if (this.hasSelectAll()) { + var selected = this.getSelected(); + + if (selected.length === $('option:not([data-role=divider])', this.$select).length - 1) { + this.select(this.options.selectAllValue); + } + else { + this.deselect(this.options.selectAllValue); + } + } + }, + + /** + * Update the button text and its title based on the currently selected options. + */ + updateButtonText: function() { + var options = this.getSelected(); + + // First update the displayed button text. + $('button', this.$container).html(this.options.buttonText(options, this.$select)); + + // Now update the title attribute of the button. + $('button', this.$container).attr('title', this.options.buttonTitle(options, this.$select)); + + }, + + /** + * Get all selected options. + * + * @returns {jQUery} + */ + getSelected: function() { + return $('option[value!="' + this.options.selectAllValue + '"]:selected', this.$select).filter(function() { + return $(this).prop('selected'); + }); + }, + + /** + * Gets a select option by its value. + * + * @param {String} value + * @returns {jQuery} + */ + getOptionByValue: function (value) { + + var options = $('option', this.$select); + var valueToCompare = value.toString(); + + for (var i = 0; i < options.length; i = i + 1) { + var option = options[i]; + if (option.value === valueToCompare) { + return $(option); + } + } + }, + + /** + * Get the input (radio/checkbox) by its value. + * + * @param {String} value + * @returns {jQuery} + */ + getInputByValue: function (value) { + + var checkboxes = $('li input', this.$ul); + var valueToCompare = value.toString(); + + for (var i = 0; i < checkboxes.length; i = i + 1) { + var checkbox = checkboxes[i]; + if (checkbox.value === valueToCompare) { + return $(checkbox); + } + } + }, + + /** + * Used for knockout integration. + */ + updateOriginalOptions: function() { + this.originalOptions = this.$select.clone()[0].options; + }, + + asyncFunction: function(callback, timeout, self) { + var args = Array.prototype.slice.call(arguments, 3); + return setTimeout(function() { + callback.apply(self || window, args); + }, timeout); + } + }; + + $.fn.multiselect = function(option, parameter) { + return this.each(function() { + var data = $(this).data('multiselect'); + var options = typeof option === 'object' && option; + + // Initialize the multiselect. + if (!data) { + data = new Multiselect(this, options); + $(this).data('multiselect', data); + } + + // Call multiselect method. + if (typeof option === 'string') { + data[option](parameter); + + if (option === 'destroy') { + $(this).data('multiselect', false); + } + } + }); + }; + + $.fn.multiselect.Constructor = Multiselect; + + $(function() { + $("select[data-role=multiselect]").multiselect(); + }); + +}(window.jQuery); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-tagsinput/bootstrap-tagsinput.css b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-tagsinput/bootstrap-tagsinput.css new file mode 100644 index 0000000..98cfa7f --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-tagsinput/bootstrap-tagsinput.css @@ -0,0 +1,45 @@ +.bootstrap-tagsinput { + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + display: inline-block; + padding: 4px 6px; + margin-bottom: 10px; + color: #555; + vertical-align: middle; + border-radius: 4px; + max-width: 100%; + line-height: 22px; +} +.bootstrap-tagsinput input { + border: none; + box-shadow: none; + outline: none; + background-color: transparent; + padding: 0; + margin: 0; + width: auto !important; + max-width: inherit; +} +.bootstrap-tagsinput input:focus { + border: none; + box-shadow: none; +} +.bootstrap-tagsinput .tag { + margin-right: 2px; + color: white; +} +.bootstrap-tagsinput .tag [data-role="remove"] { + margin-left: 8px; + cursor: pointer; +} +.bootstrap-tagsinput .tag [data-role="remove"]:after { + content: "x"; + padding: 0px 2px; +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover:active { + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-tagsinput/bootstrap-tagsinput.js b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-tagsinput/bootstrap-tagsinput.js new file mode 100644 index 0000000..4402463 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-tagsinput/bootstrap-tagsinput.js @@ -0,0 +1,635 @@ +(function ($) { + "use strict"; + + var defaultOptions = { + tagClass: function(item) { + return 'label label-info'; + }, + itemValue: function(item) { + return item ? item.toString() : item; + }, + itemText: function(item) { + return this.itemValue(item); + }, + freeInput: true, + addOnBlur: true, + maxTags: undefined, + maxChars: undefined, + confirmKeys: [13, 44], + onTagExists: function(item, $tag) { + $tag.hide().fadeIn(); + }, + trimValue: false, + allowDuplicates: false + }; + + /** + * Constructor function + */ + function TagsInput(element, options) { + var tagsId, + tagClass; + this.itemsArray = []; + + this.$element = $(element); + this.$element.hide(); + + this.isSelect = (element.tagName === 'SELECT'); + this.multiple = (this.isSelect && element.hasAttribute('multiple')); + this.objectItems = options && options.itemValue; + this.placeholderText = element.hasAttribute('placeholder') ? this.$element.attr('placeholder') : ''; + this.inputSize = Math.max(1, this.placeholderText.length); + + this.$container = $(''); + this.$input = $('').appendTo(this.$container); + + if (!!element.id) { + tagsId = element.id + 'tags-input'; + this.$input.attr('id', tagsId); + $('label[for="' + element.id + '"]').attr('for', tagsId); + } + + + this.$element.after(this.$container); + + options = options || {}; + if(options.tagClass === undefined) { + tagClass = this.$element.data('tag-class'); + if(tagClass) { + options.tagClass = function() { + return tagClass; + }; + } + } + var inputWidth = (this.inputSize < 3 ? 3 : this.inputSize) + "em"; + this.$input.get(0).style.cssText = "width: " + inputWidth + " !important;"; + this.build(options); + } + + TagsInput.prototype = { + constructor: TagsInput, + + /** + * Adds the given item as a new tag. Pass true to dontPushVal to prevent + * updating the elements val() + */ + add: function(item, dontPushVal) { + var self = this; + + if (self.options.maxTags && self.itemsArray.length >= self.options.maxTags) + return; + + // Ignore falsey values, except false + if (item !== false && !item) + return; + + // Trim value + if (typeof item === "string" && self.options.trimValue) { + item = $.trim(item); + } + + // Throw an error when trying to add an object while the itemValue option was not set + if (typeof item === "object" && !self.objectItems) + throw("Can't add objects when itemValue option is not set"); + + // Ignore strings only containg whitespace + if (item.toString().match(/^\s*$/)) + return; + + // If SELECT but not multiple, remove current tag + if (self.isSelect && !self.multiple && self.itemsArray.length > 0) + self.remove(self.itemsArray[0]); + + if (typeof item === "string" && this.$element[0].tagName === 'INPUT') { + var items = item.split(','); + if (items.length > 1) { + for (var i = 0; i < items.length; i++) { + this.add(items[i], true); + } + + if (!dontPushVal) + self.pushVal(); + return; + } + } + + var itemValue = self.options.itemValue(item), + itemText = self.options.itemText(item), + tagClass = self.options.tagClass(item); + + // Ignore items allready added + var existing = $.grep(self.itemsArray, function(item) { return self.options.itemValue(item) === itemValue; } )[0]; + if (existing && !self.options.allowDuplicates) { + // Invoke onTagExists + if (self.options.onTagExists) { + var $existingTag = $(".tag", self.$container).filter(function() { return $(this).data("item") === existing; }); + self.options.onTagExists(item, $existingTag); + } + return; + } + + // if length greater than limit + if (self.items().toString().length + item.length + 1 > self.options.maxInputLength) + return; + + // raise beforeItemAdd arg + var beforeItemAddEvent = $.Event('beforeItemAdd', { item: item, cancel: false }); + self.$element.trigger(beforeItemAddEvent); + if (beforeItemAddEvent.cancel) + return; + + // register item in internal array and map + self.itemsArray.push(item); + + // add a tag element + var $tag = $('' + htmlEncode(itemText) + ''); + $tag.data('item', item); + self.findInputWrapper().before($tag); + $tag.after(' '); + + // add if item represents a value not present in one of the 's options + if (self.isSelect && !$('option[value="' + encodeURIComponent(itemValue) + '"]',self.$element)[0]) { + var $option = $(''); + $option.data('item', item); + $option.attr('value', itemValue); + self.$element.append($option); + } + + if (!dontPushVal) + self.pushVal(); + + // Add class when reached maxTags + if (self.options.maxTags === self.itemsArray.length || self.items().toString().length === self.options.maxInputLength) + self.$container.addClass('bootstrap-tagsinput-max'); + + self.$element.trigger($.Event('itemAdded', { item: item })); + }, + + /** + * Removes the given item. Pass true to dontPushVal to prevent updating the + * elements val() + */ + remove: function(item, dontPushVal) { + var self = this; + + if (self.objectItems) { + if (typeof item === "object") + item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == self.options.itemValue(item); } ); + else + item = $.grep(self.itemsArray, function(other) { return self.options.itemValue(other) == item; } ); + + item = item[item.length-1]; + } + + if (item) { + var beforeItemRemoveEvent = $.Event('beforeItemRemove', { item: item, cancel: false }); + self.$element.trigger(beforeItemRemoveEvent); + if (beforeItemRemoveEvent.cancel) + return; + + $('.tag', self.$container).filter(function() { return $(this).data('item') === item; }).remove(); + $('option', self.$element).filter(function() { return $(this).data('item') === item; }).remove(); + if($.inArray(item, self.itemsArray) !== -1) + self.itemsArray.splice($.inArray(item, self.itemsArray), 1); + } + + if (!dontPushVal) + self.pushVal(); + + // Remove class when reached maxTags + if (self.options.maxTags > self.itemsArray.length) + self.$container.removeClass('bootstrap-tagsinput-max'); + + self.$element.trigger($.Event('itemRemoved', { item: item })); + }, + + /** + * Removes all items + */ + removeAll: function() { + var self = this; + + $('.tag', self.$container).remove(); + $('option', self.$element).remove(); + + while(self.itemsArray.length > 0) + self.itemsArray.pop(); + + self.pushVal(); + }, + + /** + * Refreshes the tags so they match the text/value of their corresponding + * item. + */ + refresh: function() { + var self = this; + $('.tag', self.$container).each(function() { + var $tag = $(this), + item = $tag.data('item'), + itemValue = self.options.itemValue(item), + itemText = self.options.itemText(item), + tagClass = self.options.tagClass(item); + + // Update tag's class and inner text + $tag.attr('class', null); + $tag.addClass('tag ' + htmlEncode(tagClass)); + $tag.contents().filter(function() { + return this.nodeType == 3; + })[0].nodeValue = htmlEncode(itemText); + + if (self.isSelect) { + var option = $('option', self.$element).filter(function() { return $(this).data('item') === item; }); + option.attr('value', itemValue); + } + }); + }, + + /** + * Returns the items added as tags + */ + items: function() { + return this.itemsArray; + }, + + /** + * Assembly value by retrieving the value of each item, and set it on the + * element. + */ + pushVal: function() { + var self = this, + val = $.map(self.items(), function(item) { + return self.options.itemValue(item).toString(); + }); + + self.$element.val(val, true).trigger('change'); + }, + + /** + * Initializes the tags input behaviour on the element + */ + build: function(options) { + var self = this; + + self.options = $.extend({}, defaultOptions, options); + // When itemValue is set, freeInput should always be false + if (self.objectItems) + self.options.freeInput = false; + + makeOptionItemFunction(self.options, 'itemValue'); + makeOptionItemFunction(self.options, 'itemText'); + makeOptionFunction(self.options, 'tagClass'); + + // Typeahead Bootstrap version 2.3.2 + if (self.options.typeahead) { + var typeahead = self.options.typeahead || {}; + + makeOptionFunction(typeahead, 'source'); + + self.$input.typeahead($.extend({}, typeahead, { + source: function (query, process) { + function processItems(items) { + var texts = []; + + for (var i = 0; i < items.length; i++) { + var text = self.options.itemText(items[i]); + map[text] = items[i]; + texts.push(text); + } + process(texts); + } + + this.map = {}; + var map = this.map, + data = typeahead.source(query); + + if ($.isFunction(data.success)) { + // support for Angular callbacks + data.success(processItems); + } else if ($.isFunction(data.then)) { + // support for Angular promises + data.then(processItems); + } else { + // support for functions and jquery promises + $.when(data) + .then(processItems); + } + }, + updater: function (text) { + self.add(this.map[text]); + }, + matcher: function (text) { + return (text.toLowerCase().indexOf(this.query.trim().toLowerCase()) !== -1); + }, + sorter: function (texts) { + return texts.sort(); + }, + highlighter: function (text) { + var regex = new RegExp( '(' + this.query + ')', 'gi' ); + return text.replace( regex, "$1" ); + } + })); + } + + // typeahead.js + if (self.options.typeaheadjs) { + var typeaheadjs = self.options.typeaheadjs || {}; + + self.$input.typeahead(null, typeaheadjs).on('typeahead:selected', $.proxy(function (obj, datum) { + if (typeaheadjs.valueKey) + self.add(datum[typeaheadjs.valueKey]); + else + self.add(datum); + self.$input.typeahead('val', ''); + }, self)); + } + + self.$container.on('click', $.proxy(function(event) { + if (! self.$element.attr('disabled')) { + self.$input.removeAttr('disabled'); + } + self.$input.focus(); + }, self)); + + if (self.options.addOnBlur && self.options.freeInput) { + self.$input.on('focusout', $.proxy(function(event) { + // HACK: only process on focusout when no typeahead opened, to + // avoid adding the typeahead text as tag + if ($('.typeahead, .twitter-typeahead', self.$container).length === 0) { + self.add(self.$input.val()); + self.$input.val(''); + } + }, self)); + } + + + self.$container.on('keydown', 'input', $.proxy(function(event) { + var $input = $(event.target), + $inputWrapper = self.findInputWrapper(); + + if (self.$element.attr('disabled')) { + self.$input.attr('disabled', 'disabled'); + return; + } + + switch (event.which) { + // BACKSPACE + case 8: + if (doGetCaretPosition($input[0]) === 0) { + var prev = $inputWrapper.prev(); + if (prev) { + self.remove(prev.data('item')); + } + } + break; + + // DELETE + case 46: + if (doGetCaretPosition($input[0]) === 0) { + var next = $inputWrapper.next(); + if (next) { + self.remove(next.data('item')); + } + } + break; + + // LEFT ARROW + case 37: + // Try to move the input before the previous tag + var $prevTag = $inputWrapper.prev(); + if ($input.val().length === 0 && $prevTag[0]) { + $prevTag.before($inputWrapper); + $input.focus(); + } + break; + // RIGHT ARROW + case 39: + // Try to move the input after the next tag + var $nextTag = $inputWrapper.next(); + if ($input.val().length === 0 && $nextTag[0]) { + $nextTag.after($inputWrapper); + $input.focus(); + } + break; + default: + // ignore + } + + // Reset internal input's size + var textLength = $input.val().length, + wordSpace = Math.ceil(textLength / 5), + size = textLength + wordSpace + 1; + $input.attr('size', Math.max(this.inputSize, $input.val().length)); + }, self)); + + self.$container.on('keypress', 'input', $.proxy(function(event) { + var $input = $(event.target); + + if (self.$element.attr('disabled')) { + self.$input.attr('disabled', 'disabled'); + return; + } + + var text = $input.val(), + maxLengthReached = self.options.maxChars && text.length >= self.options.maxChars; + if (self.options.freeInput && (keyCombinationInList(event, self.options.confirmKeys) || maxLengthReached)) { + self.add(maxLengthReached ? text.substr(0, self.options.maxChars) : text); + $input.val(''); + event.preventDefault(); + } + + // Reset internal input's size + var textLength = $input.val().length, + wordSpace = Math.ceil(textLength / 5), + size = textLength + wordSpace + 1; + $input.attr('size', Math.max(this.inputSize, $input.val().length)); + }, self)); + + // Remove icon clicked + self.$container.on('click', '[data-role=remove]', $.proxy(function(event) { + if (self.$element.attr('disabled')) { + return; + } + self.remove($(event.target).closest('.tag').data('item')); + }, self)); + + // Only add existing value as tags when using strings as tags + if (self.options.itemValue === defaultOptions.itemValue) { + if (self.$element[0].tagName === 'INPUT') { + self.add(self.$element.val()); + } else { + $('option', self.$element).each(function() { + self.add($(this).attr('value'), true); + }); + } + } + }, + + /** + * Removes all tagsinput behaviour and unregsiter all event handlers + */ + destroy: function() { + var self = this; + + // Unbind events + self.$container.off('keypress', 'input'); + self.$container.off('click', '[role=remove]'); + + self.$container.remove(); + self.$element.removeData('tagsinput'); + self.$element.show(); + }, + + /** + * Sets focus on the tagsinput + */ + focus: function() { + this.$input.focus(); + }, + + /** + * Returns the internal input element + */ + input: function() { + return this.$input; + }, + + /** + * Returns the element which is wrapped around the internal input. This + * is normally the $container, but typeahead.js moves the $input element. + */ + findInputWrapper: function() { + var elt = this.$input[0], + container = this.$container[0]; + while(elt && elt.parentNode !== container) + elt = elt.parentNode; + + return $(elt); + } + }; + + /** + * Register JQuery plugin + */ + $.fn.tagsinput = function(arg1, arg2) { + var results = []; + + this.each(function() { + var tagsinput = $(this).data('tagsinput'); + // Initialize a new tags input + if (!tagsinput) { + tagsinput = new TagsInput(this, arg1); + $(this).data('tagsinput', tagsinput); + results.push(tagsinput); + + if (this.tagName === 'SELECT') { + $('option', $(this)).attr('selected', 'selected'); + } + + // Init tags from $(this).val() + $(this).val($(this).val()); + } else if (!arg1 && !arg2) { + // tagsinput already exists + // no function, trying to init + results.push(tagsinput); + } else if(tagsinput[arg1] !== undefined) { + // Invoke function on existing tags input + var retVal = tagsinput[arg1](arg2); + if (retVal !== undefined) + results.push(retVal); + } + }); + + if ( typeof arg1 == 'string') { + // Return the results from the invoked function calls + return results.length > 1 ? results : results[0]; + } else { + return results; + } + }; + + $.fn.tagsinput.Constructor = TagsInput; + + /** + * Most options support both a string or number as well as a function as + * option value. This function makes sure that the option with the given + * key in the given options is wrapped in a function + */ + function makeOptionItemFunction(options, key) { + if (typeof options[key] !== 'function') { + var propertyName = options[key]; + options[key] = function(item) { return item[propertyName]; }; + } + } + function makeOptionFunction(options, key) { + if (typeof options[key] !== 'function') { + var value = options[key]; + options[key] = function() { return value; }; + } + } + /** + * HtmlEncodes the given value + */ + var htmlEncodeContainer = $(''); + function htmlEncode(value) { + if (value) { + return htmlEncodeContainer.text(value).html(); + } else { + return ''; + } + } + + /** + * Returns the position of the caret in the given input field + * http://flightschool.acylt.com/devnotes/caret-position-woes/ + */ + function doGetCaretPosition(oField) { + var iCaretPos = 0; + if (document.selection) { + oField.focus (); + var oSel = document.selection.createRange(); + oSel.moveStart ('character', -oField.value.length); + iCaretPos = oSel.text.length; + } else if (oField.selectionStart || oField.selectionStart == '0') { + iCaretPos = oField.selectionStart; + } + return (iCaretPos); + } + + /** + * Returns boolean indicates whether user has pressed an expected key combination. + * @param object keyPressEvent: JavaScript event object, refer + * http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html + * @param object lookupList: expected key combinations, as in: + * [13, {which: 188, shiftKey: true}] + */ + function keyCombinationInList(keyPressEvent, lookupList) { + var found = false; + $.each(lookupList, function (index, keyCombination) { + if (typeof (keyCombination) === 'number' && keyPressEvent.which === keyCombination) { + found = true; + return false; + } + + if (keyPressEvent.which === keyCombination.which) { + var alt = !keyCombination.hasOwnProperty('altKey') || keyPressEvent.altKey === keyCombination.altKey, + shift = !keyCombination.hasOwnProperty('shiftKey') || keyPressEvent.shiftKey === keyCombination.shiftKey, + ctrl = !keyCombination.hasOwnProperty('ctrlKey') || keyPressEvent.ctrlKey === keyCombination.ctrlKey; + if (alt && shift && ctrl) { + found = true; + return false; + } + } + }); + + return found; + } + + /** + * Initialize tagsinput behaviour on inputs and selects which have + * data-role=tagsinput + */ + $(function() { + $("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput(); + }); +})(window.jQuery); \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-timepicker/css/bootstrap-timepicker.css b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-timepicker/css/bootstrap-timepicker.css new file mode 100644 index 0000000..fec5049 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-timepicker/css/bootstrap-timepicker.css @@ -0,0 +1,148 @@ +/*! + * Timepicker Component for Twitter Bootstrap + * + * Copyright 2013 Joris de Wit + * + * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +.bootstrap-timepicker { + position: relative; +} +.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu { + left: auto; + right: 0; +} +.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before { + left: auto; + right: 12px; +} +.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after { + left: auto; + right: 13px; +} +.bootstrap-timepicker .add-on { + cursor: pointer; +} +.bootstrap-timepicker .add-on i { + display: inline-block; + width: 16px; + height: 16px; +} +.bootstrap-timepicker-widget.dropdown-menu { + padding: 4px; +} +.bootstrap-timepicker-widget.dropdown-menu.open { + display: inline-block; +} +.bootstrap-timepicker-widget.dropdown-menu:before { + border-bottom: 7px solid rgba(0, 0, 0, 0.2); + border-left: 7px solid transparent; + border-right: 7px solid transparent; + content: ""; + display: inline-block; + position: absolute; +} +.bootstrap-timepicker-widget.dropdown-menu:after { + border-bottom: 6px solid #FFFFFF; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + content: ""; + display: inline-block; + position: absolute; +} +.bootstrap-timepicker-widget.timepicker-orient-left:before { + left: 6px; +} +.bootstrap-timepicker-widget.timepicker-orient-left:after { + left: 7px; +} +.bootstrap-timepicker-widget.timepicker-orient-right:before { + right: 6px; +} +.bootstrap-timepicker-widget.timepicker-orient-right:after { + right: 7px; +} +.bootstrap-timepicker-widget.timepicker-orient-top:before { + top: -7px; +} +.bootstrap-timepicker-widget.timepicker-orient-top:after { + top: -6px; +} +.bootstrap-timepicker-widget.timepicker-orient-bottom:before { + bottom: -7px; + border-bottom: 0; + border-top: 7px solid #999; +} +.bootstrap-timepicker-widget.timepicker-orient-bottom:after { + bottom: -6px; + border-bottom: 0; + border-top: 6px solid #ffffff; +} +.bootstrap-timepicker-widget a.btn, +.bootstrap-timepicker-widget input { + border-radius: 4px; +} +.bootstrap-timepicker-widget table { + width: 100%; + margin: 0; +} +.bootstrap-timepicker-widget table td { + text-align: center; + height: 30px; + margin: 0; + padding: 2px; +} +.bootstrap-timepicker-widget table td:not(.separator) { + min-width: 30px; +} +.bootstrap-timepicker-widget table td span { + width: 100%; +} +.bootstrap-timepicker-widget table td a { + border: 1px transparent solid; + width: 100%; + display: inline-block; + margin: 0; + padding: 8px 0; + outline: 0; + color: #333; +} +.bootstrap-timepicker-widget table td a:hover { + text-decoration: none; + background-color: #eee; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + border-color: #ddd; +} +.bootstrap-timepicker-widget table td a i { + margin-top: 2px; + font-size: 18px; +} +.bootstrap-timepicker-widget table td input { + width: 32px; + margin: 0; + text-align: center; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.bootstrap-timepicker-widget .modal-content { + padding: 4px; +} +@media (min-width: 767px) { + .bootstrap-timepicker-widget.modal { + width: 200px; + margin-left: -100px; + } +} +@media (max-width: 767px) { + .bootstrap-timepicker { + width: 100%; + } + .bootstrap-timepicker .dropdown-menu { + width: 100%; + } +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-timepicker/js/bootstrap-timepicker.js b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-timepicker/js/bootstrap-timepicker.js new file mode 100644 index 0000000..7c8adc1 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/bootstrap-timepicker/js/bootstrap-timepicker.js @@ -0,0 +1,1097 @@ +/*! + * Timepicker Component for Twitter Bootstrap + * + * Copyright 2013 Joris de Wit + * + * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +(function($, window, document, undefined) { + 'use strict'; + + // TIMEPICKER PUBLIC CLASS DEFINITION + var Timepicker = function(element, options) { + this.widget = ''; + this.$element = $(element); + this.defaultTime = options.defaultTime; + this.disableFocus = options.disableFocus; + this.disableMousewheel = options.disableMousewheel; + this.isOpen = options.isOpen; + this.minuteStep = options.minuteStep; + this.modalBackdrop = options.modalBackdrop; + this.orientation = options.orientation; + this.secondStep = options.secondStep; + this.showInputs = options.showInputs; + this.showMeridian = options.showMeridian; + this.showSeconds = options.showSeconds; + this.template = options.template; + this.appendWidgetTo = options.appendWidgetTo; + this.showWidgetOnAddonClick = options.showWidgetOnAddonClick; + + this._init(); + }; + + Timepicker.prototype = { + + constructor: Timepicker, + _init: function() { + var self = this; + + if (this.showWidgetOnAddonClick && (this.$element.parent().hasClass('input-append') || this.$element.parent().hasClass('input-prepend'))) { + this.$element.parent('.input-append, .input-prepend').find('.add-on').on({ + 'click.timepicker': $.proxy(this.showWidget, this) + }); + this.$element.on({ + 'focus.timepicker': $.proxy(this.highlightUnit, this), + 'click.timepicker': $.proxy(this.highlightUnit, this), + 'keydown.timepicker': $.proxy(this.elementKeydown, this), + 'blur.timepicker': $.proxy(this.blurElement, this), + 'mousewheel.timepicker DOMMouseScroll.timepicker': $.proxy(this.mousewheel, this) + }); + } else { + if (this.template) { + this.$element.on({ + 'focus.timepicker': $.proxy(this.showWidget, this), + 'click.timepicker': $.proxy(this.showWidget, this), + 'blur.timepicker': $.proxy(this.blurElement, this), + 'mousewheel.timepicker DOMMouseScroll.timepicker': $.proxy(this.mousewheel, this) + }); + } else { + this.$element.on({ + 'focus.timepicker': $.proxy(this.highlightUnit, this), + 'click.timepicker': $.proxy(this.highlightUnit, this), + 'keydown.timepicker': $.proxy(this.elementKeydown, this), + 'blur.timepicker': $.proxy(this.blurElement, this), + 'mousewheel.timepicker DOMMouseScroll.timepicker': $.proxy(this.mousewheel, this) + }); + } + } + + if (this.template !== false) { + this.$widget = $(this.getTemplate()).on('click', $.proxy(this.widgetClick, this)); + } else { + this.$widget = false; + } + + if (this.showInputs && this.$widget !== false) { + this.$widget.find('input').each(function() { + $(this).on({ + 'click.timepicker': function() { $(this).select(); }, + 'keydown.timepicker': $.proxy(self.widgetKeydown, self), + 'keyup.timepicker': $.proxy(self.widgetKeyup, self) + }); + }); + } + + this.setDefaultTime(this.defaultTime); + }, + + blurElement: function() { + this.highlightedUnit = null; + this.updateFromElementVal(); + }, + + clear: function() { + this.hour = ''; + this.minute = ''; + this.second = ''; + this.meridian = ''; + + this.$element.val(''); + }, + + decrementHour: function() { + if (this.showMeridian) { + if (this.hour === 1) { + this.hour = 12; + } else if (this.hour === 12) { + this.hour--; + + return this.toggleMeridian(); + } else if (this.hour === 0) { + this.hour = 11; + + return this.toggleMeridian(); + } else { + this.hour--; + } + } else { + if (this.hour <= 0) { + this.hour = 23; + } else { + this.hour--; + } + } + }, + + decrementMinute: function(step) { + var newVal; + + if (step) { + newVal = this.minute - step; + } else { + newVal = this.minute - this.minuteStep; + } + + if (newVal < 0) { + this.decrementHour(); + this.minute = newVal + 60; + } else { + this.minute = newVal; + } + }, + + decrementSecond: function() { + var newVal = this.second - this.secondStep; + + if (newVal < 0) { + this.decrementMinute(true); + this.second = newVal + 60; + } else { + this.second = newVal; + } + }, + + elementKeydown: function(e) { + switch (e.keyCode) { + case 9: //tab + case 27: // escape + this.updateFromElementVal(); + break; + case 37: // left arrow + e.preventDefault(); + this.highlightPrevUnit(); + break; + case 38: // up arrow + e.preventDefault(); + switch (this.highlightedUnit) { + case 'hour': + this.incrementHour(); + this.highlightHour(); + break; + case 'minute': + this.incrementMinute(); + this.highlightMinute(); + break; + case 'second': + this.incrementSecond(); + this.highlightSecond(); + break; + case 'meridian': + this.toggleMeridian(); + this.highlightMeridian(); + break; + } + this.update(); + break; + case 39: // right arrow + e.preventDefault(); + this.highlightNextUnit(); + break; + case 40: // down arrow + e.preventDefault(); + switch (this.highlightedUnit) { + case 'hour': + this.decrementHour(); + this.highlightHour(); + break; + case 'minute': + this.decrementMinute(); + this.highlightMinute(); + break; + case 'second': + this.decrementSecond(); + this.highlightSecond(); + break; + case 'meridian': + this.toggleMeridian(); + this.highlightMeridian(); + break; + } + + this.update(); + break; + } + }, + + getCursorPosition: function() { + var input = this.$element.get(0); + + if ('selectionStart' in input) {// Standard-compliant browsers + + return input.selectionStart; + } else if (document.selection) {// IE fix + input.focus(); + var sel = document.selection.createRange(), + selLen = document.selection.createRange().text.length; + + sel.moveStart('character', - input.value.length); + + return sel.text.length - selLen; + } + }, + + getTemplate: function() { + var template, + hourTemplate, + minuteTemplate, + secondTemplate, + meridianTemplate, + templateContent; + + if (this.showInputs) { + hourTemplate = ''; + minuteTemplate = ''; + secondTemplate = ''; + meridianTemplate = ''; + } else { + hourTemplate = ''; + minuteTemplate = ''; + secondTemplate = ''; + meridianTemplate = ''; + } + + templateContent = ' ', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + container: false, + viewport: { + selector: 'body', + padding: 0 + } + } + + Tooltip.prototype.init = function (type, element, options) { + this.enabled = true + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport) + + var triggers = this.options.trigger.split(' ') + + for (var i = triggers.length; i--;) { + var trigger = triggers[i] + + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' + var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' + + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + Tooltip.prototype.getDefaults = function () { + return Tooltip.DEFAULTS + } + + Tooltip.prototype.getOptions = function (options) { + options = $.extend({}, this.getDefaults(), this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay, + hide: options.delay + } + } + + return options + } + + Tooltip.prototype.getDelegateOptions = function () { + var options = {} + var defaults = this.getDefaults() + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }) + + return options + } + + Tooltip.prototype.enter = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (self && self.$tip && self.$tip.is(':visible')) { + self.hoverState = 'in' + return + } + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + clearTimeout(self.timeout) + + self.hoverState = 'in' + + if (!self.options.delay || !self.options.delay.show) return self.show() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + Tooltip.prototype.leave = function (obj) { + var self = obj instanceof this.constructor ? + obj : $(obj.currentTarget).data('bs.' + this.type) + + if (!self) { + self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) + $(obj.currentTarget).data('bs.' + this.type, self) + } + + clearTimeout(self.timeout) + + self.hoverState = 'out' + + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.timeout = setTimeout(function () { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + Tooltip.prototype.show = function () { + var e = $.Event('show.bs.' + this.type) + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + + var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) + if (e.isDefaultPrevented() || !inDom) return + var that = this + + var $tip = this.tip() + + var tipId = this.getUID(this.type) + + this.setContent() + $tip.attr('id', tipId) + this.$element.attr('aria-describedby', tipId) + + if (this.options.animation) $tip.addClass('fade') + + var placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + var autoToken = /\s?auto?\s?/i + var autoPlace = autoToken.test(placement) + if (autoPlace) placement = placement.replace(autoToken, '') || 'top' + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + .addClass(placement) + .data('bs.' + this.type, this) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + + var pos = this.getPosition() + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (autoPlace) { + var orgPlacement = placement + var $container = this.options.container ? $(this.options.container) : this.$element.parent() + var containerDim = this.getPosition($container) + + placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' : + placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' : + placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' : + placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' : + placement + + $tip + .removeClass(orgPlacement) + .addClass(placement) + } + + var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) + + this.applyPlacement(calculatedOffset, placement) + + var complete = function () { + var prevHoverState = that.hoverState + that.$element.trigger('shown.bs.' + that.type) + that.hoverState = null + + if (prevHoverState == 'out') that.leave(that) + } + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + } + } + + Tooltip.prototype.applyPlacement = function (offset, placement) { + var $tip = this.tip() + var width = $tip[0].offsetWidth + var height = $tip[0].offsetHeight + + // manually read margins because getBoundingClientRect includes difference + var marginTop = parseInt($tip.css('margin-top'), 10) + var marginLeft = parseInt($tip.css('margin-left'), 10) + + // we must check for NaN for ie 8/9 + if (isNaN(marginTop)) marginTop = 0 + if (isNaN(marginLeft)) marginLeft = 0 + + offset.top = offset.top + marginTop + offset.left = offset.left + marginLeft + + // $.fn.offset doesn't round pixel values + // so we use setOffset directly with our own function B-0 + $.offset.setOffset($tip[0], $.extend({ + using: function (props) { + $tip.css({ + top: Math.round(props.top), + left: Math.round(props.left) + }) + } + }, offset), 0) + + $tip.addClass('in') + + // check to see if placing tip in new offset caused the tip to resize itself + var actualWidth = $tip[0].offsetWidth + var actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + } + + var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) + + if (delta.left) offset.left += delta.left + else offset.top += delta.top + + var isVertical = /top|bottom/.test(placement) + var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight + var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' + + $tip.offset(offset) + this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) + } + + Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) { + this.arrow() + .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') + .css(isHorizontal ? 'top' : 'left', '') + } + + Tooltip.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + Tooltip.prototype.hide = function (callback) { + var that = this + var $tip = this.tip() + var e = $.Event('hide.bs.' + this.type) + + function complete() { + if (that.hoverState != 'in') $tip.detach() + that.$element + .removeAttr('aria-describedby') + .trigger('hidden.bs.' + that.type) + callback && callback() + } + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + $.support.transition && this.$tip.hasClass('fade') ? + $tip + .one('bsTransitionEnd', complete) + .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : + complete() + + this.hoverState = null + + return this + } + + Tooltip.prototype.fixTitle = function () { + var $e = this.$element + if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + Tooltip.prototype.hasContent = function () { + return this.getTitle() + } + + Tooltip.prototype.getPosition = function ($element) { + $element = $element || this.$element + + var el = $element[0] + var isBody = el.tagName == 'BODY' + + var elRect = el.getBoundingClientRect() + if (elRect.width == null) { + // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 + elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) + } + var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() + var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } + var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null + + return $.extend({}, elRect, scroll, outerDims, elOffset) + } + + Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { + return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : + placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : + /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } + + } + + Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { + var delta = { top: 0, left: 0 } + if (!this.$viewport) return delta + + var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 + var viewportDimensions = this.getPosition(this.$viewport) + + if (/right|left/.test(placement)) { + var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll + var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight + if (topEdgeOffset < viewportDimensions.top) { // top overflow + delta.top = viewportDimensions.top - topEdgeOffset + } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow + delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset + } + } else { + var leftEdgeOffset = pos.left - viewportPadding + var rightEdgeOffset = pos.left + viewportPadding + actualWidth + if (leftEdgeOffset < viewportDimensions.left) { // left overflow + delta.left = viewportDimensions.left - leftEdgeOffset + } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow + delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset + } + } + + return delta + } + + Tooltip.prototype.getTitle = function () { + var title + var $e = this.$element + var o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + Tooltip.prototype.getUID = function (prefix) { + do prefix += ~~(Math.random() * 1000000) + while (document.getElementById(prefix)) + return prefix + } + + Tooltip.prototype.tip = function () { + return (this.$tip = this.$tip || $(this.options.template)) + } + + Tooltip.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) + } + + Tooltip.prototype.enable = function () { + this.enabled = true + } + + Tooltip.prototype.disable = function () { + this.enabled = false + } + + Tooltip.prototype.toggleEnabled = function () { + this.enabled = !this.enabled + } + + Tooltip.prototype.toggle = function (e) { + var self = this + if (e) { + self = $(e.currentTarget).data('bs.' + this.type) + if (!self) { + self = new this.constructor(e.currentTarget, this.getDelegateOptions()) + $(e.currentTarget).data('bs.' + this.type, self) + } + } + + self.tip().hasClass('in') ? self.leave(self) : self.enter(self) + } + + Tooltip.prototype.destroy = function () { + var that = this + clearTimeout(this.timeout) + this.hide(function () { + that.$element.off('.' + that.type).removeData('bs.' + that.type) + }) + } + + + // TOOLTIP PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tooltip') + var options = typeof option == 'object' && option + + if (!data && option == 'destroy') return + if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tooltip + + $.fn.tooltip = Plugin + $.fn.tooltip.Constructor = Tooltip + + + // TOOLTIP NO CONFLICT + // =================== + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: popover.js v3.3.2 + * http://getbootstrap.com/javascript/#popovers + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // POPOVER PUBLIC CLASS DEFINITION + // =============================== + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') + + Popover.VERSION = '3.3.2' + + Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }) + + + // NOTE: POPOVER EXTENDS tooltip.js + // ================================ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) + + Popover.prototype.constructor = Popover + + Popover.prototype.getDefaults = function () { + return Popover.DEFAULTS + } + + Popover.prototype.setContent = function () { + var $tip = this.tip() + var title = this.getTitle() + var content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events + this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' + ](content) + + $tip.removeClass('fade top bottom left right in') + + // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do + // this manually by checking the contents. + if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() + } + + Popover.prototype.hasContent = function () { + return this.getTitle() || this.getContent() + } + + Popover.prototype.getContent = function () { + var $e = this.$element + var o = this.options + + return $e.attr('data-content') + || (typeof o.content == 'function' ? + o.content.call($e[0]) : + o.content) + } + + Popover.prototype.arrow = function () { + return (this.$arrow = this.$arrow || this.tip().find('.arrow')) + } + + Popover.prototype.tip = function () { + if (!this.$tip) this.$tip = $(this.options.template) + return this.$tip + } + + + // POPOVER PLUGIN DEFINITION + // ========================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.popover') + var options = typeof option == 'object' && option + + if (!data && option == 'destroy') return + if (!data) $this.data('bs.popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.popover + + $.fn.popover = Plugin + $.fn.popover.Constructor = Popover + + + // POPOVER NO CONFLICT + // =================== + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(jQuery); + +/* ======================================================================== + * Bootstrap: tab.js v3.3.2 + * http://getbootstrap.com/javascript/#tabs + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // TAB CLASS DEFINITION + // ==================== + + var Tab = function (element) { + this.element = $(element) + } + + Tab.VERSION = '3.3.2' + + Tab.TRANSITION_DURATION = 150 + + Tab.prototype.show = function () { + var $this = this.element + var $ul = $this.closest('ul:not(.dropdown-menu)') + var selector = $this.data('target') + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 + } + + if ($this.parent('li').hasClass('active')) return + + var $previous = $ul.find('.active:last a') + var hideEvent = $.Event('hide.bs.tab', { + relatedTarget: $this[0] + }) + var showEvent = $.Event('show.bs.tab', { + relatedTarget: $previous[0] + }) + + $previous.trigger(hideEvent) + $this.trigger(showEvent) + + if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return + + var $target = $(selector) + + this.activate($this.closest('li'), $ul) + this.activate($target, $target.parent(), function () { + $previous.trigger({ + type: 'hidden.bs.tab', + relatedTarget: $this[0] + }) + $this.trigger({ + type: 'shown.bs.tab', + relatedTarget: $previous[0] + }) + }) + } + + Tab.prototype.activate = function (element, container, callback) { + var $active = container.find('> .active') + var transition = callback + && $.support.transition + && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length) + + function next() { + $active + .removeClass('active') + .find('> .dropdown-menu > .active') + .removeClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', false) + + element + .addClass('active') + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + + if (transition) { + element[0].offsetWidth // reflow for transition + element.addClass('in') + } else { + element.removeClass('fade') + } + + if (element.parent('.dropdown-menu')) { + element + .closest('li.dropdown') + .addClass('active') + .end() + .find('[data-toggle="tab"]') + .attr('aria-expanded', true) + } + + callback && callback() + } + + $active.length && transition ? + $active + .one('bsTransitionEnd', next) + .emulateTransitionEnd(Tab.TRANSITION_DURATION) : + next() + + $active.removeClass('in') + } + + + // TAB PLUGIN DEFINITION + // ===================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.tab') + + if (!data) $this.data('bs.tab', (data = new Tab(this))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.tab + + $.fn.tab = Plugin + $.fn.tab.Constructor = Tab + + + // TAB NO CONFLICT + // =============== + + $.fn.tab.noConflict = function () { + $.fn.tab = old + return this + } + + + // TAB DATA-API + // ============ + + var clickHandler = function (e) { + e.preventDefault() + Plugin.call($(this), 'show') + } + + $(document) + .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) + .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: affix.js v3.3.2 + * http://getbootstrap.com/javascript/#affix + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // AFFIX CLASS DEFINITION + // ====================== + + var Affix = function (element, options) { + this.options = $.extend({}, Affix.DEFAULTS, options) + + this.$target = $(this.options.target) + .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) + .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) + + this.$element = $(element) + this.affixed = + this.unpin = + this.pinnedOffset = null + + this.checkPosition() + } + + Affix.VERSION = '3.3.2' + + Affix.RESET = 'affix affix-top affix-bottom' + + Affix.DEFAULTS = { + offset: 0, + target: window + } + + Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + var targetHeight = this.$target.height() + + if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false + + if (this.affixed == 'bottom') { + if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' + return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' + } + + var initializing = this.affixed == null + var colliderTop = initializing ? scrollTop : position.top + var colliderHeight = initializing ? targetHeight : height + + if (offsetTop != null && scrollTop <= offsetTop) return 'top' + if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' + + return false + } + + Affix.prototype.getPinnedOffset = function () { + if (this.pinnedOffset) return this.pinnedOffset + this.$element.removeClass(Affix.RESET).addClass('affix') + var scrollTop = this.$target.scrollTop() + var position = this.$element.offset() + return (this.pinnedOffset = position.top - scrollTop) + } + + Affix.prototype.checkPositionWithEventLoop = function () { + setTimeout($.proxy(this.checkPosition, this), 1) + } + + Affix.prototype.checkPosition = function () { + if (!this.$element.is(':visible')) return + + var height = this.$element.height() + var offset = this.options.offset + var offsetTop = offset.top + var offsetBottom = offset.bottom + var scrollHeight = $('body').height() + + if (typeof offset != 'object') offsetBottom = offsetTop = offset + if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) + if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) + + var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) + + if (this.affixed != affix) { + if (this.unpin != null) this.$element.css('top', '') + + var affixType = 'affix' + (affix ? '-' + affix : '') + var e = $.Event(affixType + '.bs.affix') + + this.$element.trigger(e) + + if (e.isDefaultPrevented()) return + + this.affixed = affix + this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null + + this.$element + .removeClass(Affix.RESET) + .addClass(affixType) + .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') + } + + if (affix == 'bottom') { + this.$element.offset({ + top: scrollHeight - height - offsetBottom + }) + } + } + + + // AFFIX PLUGIN DEFINITION + // ======================= + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.affix') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.affix', (data = new Affix(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.affix + + $.fn.affix = Plugin + $.fn.affix.Constructor = Affix + + + // AFFIX NO CONFLICT + // ================= + + $.fn.affix.noConflict = function () { + $.fn.affix = old + return this + } + + + // AFFIX DATA-API + // ============== + + $(window).on('load', function () { + $('[data-spy="affix"]').each(function () { + var $spy = $(this) + var data = $spy.data() + + data.offset = data.offset || {} + + if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom + if (data.offsetTop != null) data.offset.top = data.offsetTop + + Plugin.call($spy, data) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: collapse.js v3.3.2 + * http://getbootstrap.com/javascript/#collapse + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // COLLAPSE PUBLIC CLASS DEFINITION + // ================================ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, Collapse.DEFAULTS, options) + this.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]') + this.transitioning = null + + if (this.options.parent) { + this.$parent = this.getParent() + } else { + this.addAriaAndCollapsedClass(this.$element, this.$trigger) + } + + if (this.options.toggle) this.toggle() + } + + Collapse.VERSION = '3.3.2' + + Collapse.TRANSITION_DURATION = 350 + + Collapse.DEFAULTS = { + toggle: true, + trigger: '[data-toggle="collapse"]' + } + + Collapse.prototype.dimension = function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + Collapse.prototype.show = function () { + if (this.transitioning || this.$element.hasClass('in')) return + + var activesData + var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') + + if (actives && actives.length) { + activesData = actives.data('bs.collapse') + if (activesData && activesData.transitioning) return + } + + var startEvent = $.Event('show.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + if (actives && actives.length) { + Plugin.call(actives, 'hide') + activesData || actives.data('bs.collapse', null) + } + + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + .addClass('collapsing')[dimension](0) + .attr('aria-expanded', true) + + this.$trigger + .removeClass('collapsed') + .attr('aria-expanded', true) + + this.transitioning = 1 + + var complete = function () { + this.$element + .removeClass('collapsing') + .addClass('collapse in')[dimension]('') + this.transitioning = 0 + this.$element + .trigger('shown.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + var scrollSize = $.camelCase(['scroll', dimension].join('-')) + + this.$element + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) + } + + Collapse.prototype.hide = function () { + if (this.transitioning || !this.$element.hasClass('in')) return + + var startEvent = $.Event('hide.bs.collapse') + this.$element.trigger(startEvent) + if (startEvent.isDefaultPrevented()) return + + var dimension = this.dimension() + + this.$element[dimension](this.$element[dimension]())[0].offsetHeight + + this.$element + .addClass('collapsing') + .removeClass('collapse in') + .attr('aria-expanded', false) + + this.$trigger + .addClass('collapsed') + .attr('aria-expanded', false) + + this.transitioning = 1 + + var complete = function () { + this.transitioning = 0 + this.$element + .removeClass('collapsing') + .addClass('collapse') + .trigger('hidden.bs.collapse') + } + + if (!$.support.transition) return complete.call(this) + + this.$element + [dimension](0) + .one('bsTransitionEnd', $.proxy(complete, this)) + .emulateTransitionEnd(Collapse.TRANSITION_DURATION) + } + + Collapse.prototype.toggle = function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + Collapse.prototype.getParent = function () { + return $(this.options.parent) + .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') + .each($.proxy(function (i, element) { + var $element = $(element) + this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) + }, this)) + .end() + } + + Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { + var isOpen = $element.hasClass('in') + + $element.attr('aria-expanded', isOpen) + $trigger + .toggleClass('collapsed', !isOpen) + .attr('aria-expanded', isOpen) + } + + function getTargetFromTrigger($trigger) { + var href + var target = $trigger.attr('data-target') + || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 + + return $(target) + } + + + // COLLAPSE PLUGIN DEFINITION + // ========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.collapse') + var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) + + if (!data && options.toggle && option == 'show') options.toggle = false + if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.collapse + + $.fn.collapse = Plugin + $.fn.collapse.Constructor = Collapse + + + // COLLAPSE NO CONFLICT + // ==================== + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + // COLLAPSE DATA-API + // ================= + + $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { + var $this = $(this) + + if (!$this.attr('data-target')) e.preventDefault() + + var $target = getTargetFromTrigger($this) + var data = $target.data('bs.collapse') + var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this }) + + Plugin.call($target, option) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: scrollspy.js v3.3.2 + * http://getbootstrap.com/javascript/#scrollspy + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // SCROLLSPY CLASS DEFINITION + // ========================== + + function ScrollSpy(element, options) { + var process = $.proxy(this.process, this) + + this.$body = $('body') + this.$scrollElement = $(element).is('body') ? $(window) : $(element) + this.options = $.extend({}, ScrollSpy.DEFAULTS, options) + this.selector = (this.options.target || '') + ' .nav li > a' + this.offsets = [] + this.targets = [] + this.activeTarget = null + this.scrollHeight = 0 + + this.$scrollElement.on('scroll.bs.scrollspy', process) + this.refresh() + this.process() + } + + ScrollSpy.VERSION = '3.3.2' + + ScrollSpy.DEFAULTS = { + offset: 10 + } + + ScrollSpy.prototype.getScrollHeight = function () { + return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) + } + + ScrollSpy.prototype.refresh = function () { + var offsetMethod = 'offset' + var offsetBase = 0 + + if (!$.isWindow(this.$scrollElement[0])) { + offsetMethod = 'position' + offsetBase = this.$scrollElement.scrollTop() + } + + this.offsets = [] + this.targets = [] + this.scrollHeight = this.getScrollHeight() + + var self = this + + this.$body + .find(this.selector) + .map(function () { + var $el = $(this) + var href = $el.data('target') || $el.attr('href') + var $href = /^#./.test(href) && $(href) + + return ($href + && $href.length + && $href.is(':visible') + && [[$href[offsetMethod]().top + offsetBase, href]]) || null + }) + .sort(function (a, b) { return a[0] - b[0] }) + .each(function () { + self.offsets.push(this[0]) + self.targets.push(this[1]) + }) + } + + ScrollSpy.prototype.process = function () { + var scrollTop = this.$scrollElement.scrollTop() + this.options.offset + var scrollHeight = this.getScrollHeight() + var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() + var offsets = this.offsets + var targets = this.targets + var activeTarget = this.activeTarget + var i + + if (this.scrollHeight != scrollHeight) { + this.refresh() + } + + if (scrollTop >= maxScroll) { + return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) + } + + if (activeTarget && scrollTop < offsets[0]) { + this.activeTarget = null + return this.clear() + } + + for (i = offsets.length; i--;) { + activeTarget != targets[i] + && scrollTop >= offsets[i] + && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) + && this.activate(targets[i]) + } + } + + ScrollSpy.prototype.activate = function (target) { + this.activeTarget = target + + this.clear() + + var selector = this.selector + + '[data-target="' + target + '"],' + + this.selector + '[href="' + target + '"]' + + var active = $(selector) + .parents('li') + .addClass('active') + + if (active.parent('.dropdown-menu').length) { + active = active + .closest('li.dropdown') + .addClass('active') + } + + active.trigger('activate.bs.scrollspy') + } + + ScrollSpy.prototype.clear = function () { + $(this.selector) + .parentsUntil(this.options.target, '.active') + .removeClass('active') + } + + + // SCROLLSPY PLUGIN DEFINITION + // =========================== + + function Plugin(option) { + return this.each(function () { + var $this = $(this) + var data = $this.data('bs.scrollspy') + var options = typeof option == 'object' && option + + if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + var old = $.fn.scrollspy + + $.fn.scrollspy = Plugin + $.fn.scrollspy.Constructor = ScrollSpy + + + // SCROLLSPY NO CONFLICT + // ===================== + + $.fn.scrollspy.noConflict = function () { + $.fn.scrollspy = old + return this + } + + + // SCROLLSPY DATA-API + // ================== + + $(window).on('load.bs.scrollspy.data-api', function () { + $('[data-spy="scroll"]').each(function () { + var $spy = $(this) + Plugin.call($spy, $spy.data()) + }) + }) + +}(jQuery); + +/* ======================================================================== + * Bootstrap: transition.js v3.3.2 + * http://getbootstrap.com/javascript/#transitions + * ======================================================================== + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * ======================================================================== */ + + ++function ($) { + 'use strict'; + + // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) + // ============================================================ + + function transitionEnd() { + var el = document.createElement('bootstrap') + + var transEndEventNames = { + WebkitTransition : 'webkitTransitionEnd', + MozTransition : 'transitionend', + OTransition : 'oTransitionEnd otransitionend', + transition : 'transitionend' + } + + for (var name in transEndEventNames) { + if (el.style[name] !== undefined) { + return { end: transEndEventNames[name] } + } + } + + return false // explicit for ie8 ( ._.) + } + + // http://blog.alexmaccaw.com/css-transitions + $.fn.emulateTransitionEnd = function (duration) { + var called = false + var $el = this + $(this).one('bsTransitionEnd', function () { called = true }) + var callback = function () { if (!called) $($el).trigger($.support.transition.end) } + setTimeout(callback, duration) + return this + } + + $(function () { + $.support.transition = transitionEnd() + + if (!$.support.transition) return + + $.event.special.bsTransitionEnd = { + bindType: $.support.transition.end, + delegateType: $.support.transition.end, + handle: function (e) { + if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) + } + } + }) + +}(jQuery); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/chartist/chartist.css b/StudyDoIT/Areas/AdminIT/Content/vendor/chartist/chartist.css new file mode 100644 index 0000000..eff5a2c --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/chartist/chartist.css @@ -0,0 +1,547 @@ +/* Chartist.js 0.7.2 + * Copyright © 2015 Gion Kunz + * Free to use under the WTFPL license. + * http://www.wtfpl.net/ + */ +.ct-chart .ct-label, +.ct-chart .ct-label.ct-horizontal { + display: block; + width: 100%; + height: 100%; + fill: rgba(0,0,0,.4); + color: rgba(0,0,0,.4); + font-size: .75rem; + text-align: left; +} +.ct-chart .ct-label.ct-vertical { + display: block; + width: 100%; + height: 100%; + fill: rgba(0,0,0,.4); + color: rgba(0,0,0,.4); + font-size: .75rem; + text-align: right; +} +.ct-chart .ct-grid { + stroke: rgba(0,0,0,.2); + stroke-width: 1px; + stroke-dasharray: 2px; +} +.ct-chart .ct-point { + stroke-width: 10px; + stroke-linecap: round; +} +.ct-chart .ct-line { + fill: none; + stroke-width: 4px; +} +.ct-chart .ct-area { + stroke: none; + fill-opacity: .1; +} +.ct-chart .ct-bar { + fill: none; + stroke-width: 10px; +} +.ct-chart .ct-slice.ct-donut { + fill: none; + stroke-width: 60px; +} +.ct-chart .ct-series.ct-series-a .ct-bar, +.ct-chart .ct-series.ct-series-a .ct-line, +.ct-chart .ct-series.ct-series-a .ct-point, +.ct-chart .ct-series.ct-series-a .ct-slice.ct-donut { stroke: #d70206 } +.ct-chart .ct-series.ct-series-a .ct-area, +.ct-chart .ct-series.ct-series-a .ct-slice:not(.ct-donut) { fill: #d70206 } +.ct-chart .ct-series.ct-series-b .ct-bar, +.ct-chart .ct-series.ct-series-b .ct-line, +.ct-chart .ct-series.ct-series-b .ct-point, +.ct-chart .ct-series.ct-series-b .ct-slice.ct-donut { stroke: #f05b4f } +.ct-chart .ct-series.ct-series-b .ct-area, +.ct-chart .ct-series.ct-series-b .ct-slice:not(.ct-donut) { fill: #f05b4f } +.ct-chart .ct-series.ct-series-c .ct-bar, +.ct-chart .ct-series.ct-series-c .ct-line, +.ct-chart .ct-series.ct-series-c .ct-point, +.ct-chart .ct-series.ct-series-c .ct-slice.ct-donut { stroke: #f4c63d } +.ct-chart .ct-series.ct-series-c .ct-area, +.ct-chart .ct-series.ct-series-c .ct-slice:not(.ct-donut) { fill: #f4c63d } +.ct-chart .ct-series.ct-series-d .ct-bar, +.ct-chart .ct-series.ct-series-d .ct-line, +.ct-chart .ct-series.ct-series-d .ct-point, +.ct-chart .ct-series.ct-series-d .ct-slice.ct-donut { stroke: #d17905 } +.ct-chart .ct-series.ct-series-d .ct-area, +.ct-chart .ct-series.ct-series-d .ct-slice:not(.ct-donut) { fill: #d17905 } +.ct-chart .ct-series.ct-series-e .ct-bar, +.ct-chart .ct-series.ct-series-e .ct-line, +.ct-chart .ct-series.ct-series-e .ct-point, +.ct-chart .ct-series.ct-series-e .ct-slice.ct-donut { stroke: #453d3f } +.ct-chart .ct-series.ct-series-e .ct-area, +.ct-chart .ct-series.ct-series-e .ct-slice:not(.ct-donut) { fill: #453d3f } +.ct-chart .ct-series.ct-series-f .ct-bar, +.ct-chart .ct-series.ct-series-f .ct-line, +.ct-chart .ct-series.ct-series-f .ct-point, +.ct-chart .ct-series.ct-series-f .ct-slice.ct-donut { stroke: #59922b } +.ct-chart .ct-series.ct-series-f .ct-area, +.ct-chart .ct-series.ct-series-f .ct-slice:not(.ct-donut) { fill: #59922b } +.ct-chart .ct-series.ct-series-g .ct-bar, +.ct-chart .ct-series.ct-series-g .ct-line, +.ct-chart .ct-series.ct-series-g .ct-point, +.ct-chart .ct-series.ct-series-g .ct-slice.ct-donut { stroke: #0544d3 } +.ct-chart .ct-series.ct-series-g .ct-area, +.ct-chart .ct-series.ct-series-g .ct-slice:not(.ct-donut) { fill: #0544d3 } +.ct-chart .ct-series.ct-series-h .ct-bar, +.ct-chart .ct-series.ct-series-h .ct-line, +.ct-chart .ct-series.ct-series-h .ct-point, +.ct-chart .ct-series.ct-series-h .ct-slice.ct-donut { stroke: #6b0392 } +.ct-chart .ct-series.ct-series-h .ct-area, +.ct-chart .ct-series.ct-series-h .ct-slice:not(.ct-donut) { fill: #6b0392 } +.ct-chart .ct-series.ct-series-i .ct-bar, +.ct-chart .ct-series.ct-series-i .ct-line, +.ct-chart .ct-series.ct-series-i .ct-point, +.ct-chart .ct-series.ct-series-i .ct-slice.ct-donut { stroke: #f05b4f } +.ct-chart .ct-series.ct-series-i .ct-area, +.ct-chart .ct-series.ct-series-i .ct-slice:not(.ct-donut) { fill: #f05b4f } +.ct-chart .ct-series.ct-series-j .ct-bar, +.ct-chart .ct-series.ct-series-j .ct-line, +.ct-chart .ct-series.ct-series-j .ct-point, +.ct-chart .ct-series.ct-series-j .ct-slice.ct-donut { stroke: #dda458 } +.ct-chart .ct-series.ct-series-j .ct-area, +.ct-chart .ct-series.ct-series-j .ct-slice:not(.ct-donut) { fill: #dda458 } +.ct-chart .ct-series.ct-series-k .ct-bar, +.ct-chart .ct-series.ct-series-k .ct-line, +.ct-chart .ct-series.ct-series-k .ct-point, +.ct-chart .ct-series.ct-series-k .ct-slice.ct-donut { stroke: #eacf7d } +.ct-chart .ct-series.ct-series-k .ct-area, +.ct-chart .ct-series.ct-series-k .ct-slice:not(.ct-donut) { fill: #eacf7d } +.ct-chart .ct-series.ct-series-l .ct-bar, +.ct-chart .ct-series.ct-series-l .ct-line, +.ct-chart .ct-series.ct-series-l .ct-point, +.ct-chart .ct-series.ct-series-l .ct-slice.ct-donut { stroke: #86797d } +.ct-chart .ct-series.ct-series-l .ct-area, +.ct-chart .ct-series.ct-series-l .ct-slice:not(.ct-donut) { fill: #86797d } +.ct-chart .ct-series.ct-series-m .ct-bar, +.ct-chart .ct-series.ct-series-m .ct-line, +.ct-chart .ct-series.ct-series-m .ct-point, +.ct-chart .ct-series.ct-series-m .ct-slice.ct-donut { stroke: #b2c326 } +.ct-chart .ct-series.ct-series-m .ct-area, +.ct-chart .ct-series.ct-series-m .ct-slice:not(.ct-donut) { fill: #b2c326 } +.ct-chart .ct-series.ct-series-n .ct-bar, +.ct-chart .ct-series.ct-series-n .ct-line, +.ct-chart .ct-series.ct-series-n .ct-point, +.ct-chart .ct-series.ct-series-n .ct-slice.ct-donut { stroke: #6188e2 } +.ct-chart .ct-series.ct-series-n .ct-area, +.ct-chart .ct-series.ct-series-n .ct-slice:not(.ct-donut) { fill: #6188e2 } +.ct-chart .ct-series.ct-series-o .ct-bar, +.ct-chart .ct-series.ct-series-o .ct-line, +.ct-chart .ct-series.ct-series-o .ct-point, +.ct-chart .ct-series.ct-series-o .ct-slice.ct-donut { stroke: #a748ca } +.ct-chart .ct-series.ct-series-o .ct-area, +.ct-chart .ct-series.ct-series-o .ct-slice:not(.ct-donut) { fill: #a748ca } +.ct-chart.ct-square { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-square:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 100%; +} +.ct-chart.ct-square:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-square>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-minor-second { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-minor-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 93.75%; +} +.ct-chart.ct-minor-second:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-minor-second>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-major-second { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-major-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 88.8888888889%; +} +.ct-chart.ct-major-second:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-major-second>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-minor-third { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-minor-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 83.3333333333%; +} +.ct-chart.ct-minor-third:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-minor-third>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-major-third { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-major-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 80%; +} +.ct-chart.ct-major-third:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-major-third>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-perfect-fourth { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-perfect-fourth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 75%; +} +.ct-chart.ct-perfect-fourth:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-perfect-fourth>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-perfect-fifth { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-perfect-fifth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 66.6666666667%; +} +.ct-chart.ct-perfect-fifth:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-perfect-fifth>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-minor-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-minor-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 62.5%; +} +.ct-chart.ct-minor-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-minor-sixth>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-golden-section { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-golden-section:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 61.804697157%; +} +.ct-chart.ct-golden-section:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-golden-section>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-major-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-major-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 60%; +} +.ct-chart.ct-major-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-major-sixth>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-minor-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-minor-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 56.25%; +} +.ct-chart.ct-minor-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-minor-seventh>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-major-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-major-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 53.3333333333%; +} +.ct-chart.ct-major-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-major-seventh>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-octave { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 50%; +} +.ct-chart.ct-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-octave>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-major-tenth { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-major-tenth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 40%; +} +.ct-chart.ct-major-tenth:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-major-tenth>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-major-eleventh { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-major-eleventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 37.5%; +} +.ct-chart.ct-major-eleventh:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-major-eleventh>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-major-twelfth { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-major-twelfth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 33.3333333333%; +} +.ct-chart.ct-major-twelfth:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-major-twelfth>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} +.ct-chart.ct-double-octave { + display: block; + position: relative; + width: 100%; +} +.ct-chart.ct-double-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 25%; +} +.ct-chart.ct-double-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-chart.ct-double-octave>svg { + display: block; + position: absolute; + top: 0; + left: 0; +} \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/chartist/chartist.js b/StudyDoIT/Areas/AdminIT/Content/vendor/chartist/chartist.js new file mode 100644 index 0000000..5b15860 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/chartist/chartist.js @@ -0,0 +1,3370 @@ +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], function () { + return (root.returnExportsGlobal = factory()); + }); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like enviroments that support module.exports, + // like Node. + module.exports = factory(); + } else { + root['Chartist'] = factory(); + } +}(this, function () { + + /* Chartist.js 0.7.2 + * Copyright © 2015 Gion Kunz + * Free to use under the WTFPL license. + * http://www.wtfpl.net/ + */ + /** + * The core module of Chartist that is mainly providing static functions and higher level functions for chart modules. + * + * @module Chartist.Core + */ + var Chartist = { + version: '0.7.1' + }; + + (function (window, document, Chartist) { + 'use strict'; + + /** + * Helps to simplify functional style code + * + * @memberof Chartist.Core + * @param {*} n This exact value will be returned by the noop function + * @return {*} The same value that was provided to the n parameter + */ + Chartist.noop = function (n) { + return n; + }; + + /** + * Generates a-z from a number 0 to 26 + * + * @memberof Chartist.Core + * @param {Number} n A number from 0 to 26 that will result in a letter a-z + * @return {String} A character from a-z based on the input number n + */ + Chartist.alphaNumerate = function (n) { + // Limit to a-z + return String.fromCharCode(97 + n % 26); + }; + + /** + * Simple recursive object extend + * + * @memberof Chartist.Core + * @param {Object} target Target object where the source will be merged into + * @param {Object...} sources This object (objects) will be merged into target and then target is returned + * @return {Object} An object that has the same reference as target but is extended and merged with the properties of source + */ + Chartist.extend = function (target) { + target = target || {}; + + var sources = Array.prototype.slice.call(arguments, 1); + sources.forEach(function(source) { + for (var prop in source) { + if (typeof source[prop] === 'object' && !(source[prop] instanceof Array)) { + target[prop] = Chartist.extend(target[prop], source[prop]); + } else { + target[prop] = source[prop]; + } + } + }); + + return target; + }; + + /** + * Replaces all occurrences of subStr in str with newSubStr and returns a new string. + * + * @memberof Chartist.Core + * @param {String} str + * @param {String} subStr + * @param {String} newSubStr + * @return {String} + */ + Chartist.replaceAll = function(str, subStr, newSubStr) { + return str.replace(new RegExp(subStr, 'g'), newSubStr); + }; + + /** + * Converts a string to a number while removing the unit if present. If a number is passed then this will be returned unmodified. + * + * @memberof Chartist.Core + * @param {String|Number} value + * @return {Number} Returns the string as number or NaN if the passed length could not be converted to pixel + */ + Chartist.stripUnit = function(value) { + if(typeof value === 'string') { + value = value.replace(/[^0-9\+-\.]/g, ''); + } + + return +value; + }; + + /** + * Converts a number to a string with a unit. If a string is passed then this will be returned unmodified. + * + * @memberof Chartist.Core + * @param {Number} value + * @param {String} unit + * @return {String} Returns the passed number value with unit. + */ + Chartist.ensureUnit = function(value, unit) { + if(typeof value === 'number') { + value = value + unit; + } + + return value; + }; + + /** + * This is a wrapper around document.querySelector that will return the query if it's already of type Node + * + * @memberof Chartist.Core + * @param {String|Node} query The query to use for selecting a Node or a DOM node that will be returned directly + * @return {Node} + */ + Chartist.querySelector = function(query) { + return query instanceof Node ? query : document.querySelector(query); + }; + + /** + * Functional style helper to produce array with given length initialized with undefined values + * + * @memberof Chartist.Core + * @param length + * @return {Array} + */ + Chartist.times = function(length) { + return Array.apply(null, new Array(length)); + }; + + /** + * Sum helper to be used in reduce functions + * + * @memberof Chartist.Core + * @param previous + * @param current + * @return {*} + */ + Chartist.sum = function(previous, current) { + return previous + current; + }; + + /** + * Map for multi dimensional arrays where their nested arrays will be mapped in serial. The output array will have the length of the largest nested array. The callback function is called with variable arguments where each argument is the nested array value (or undefined if there are no more values). + * + * @memberof Chartist.Core + * @param arr + * @param cb + * @return {Array} + */ + Chartist.serialMap = function(arr, cb) { + var result = [], + length = Math.max.apply(null, arr.map(function(e) { + return e.length; + })); + + Chartist.times(length).forEach(function(e, index) { + var args = arr.map(function(e) { + return e[index]; + }); + + result[index] = cb.apply(null, args); + }); + + return result; + }; + + /** + * A map with characters to escape for strings to be safely used as attribute values. + * + * @memberof Chartist.Core + * @type {Object} + */ + Chartist.escapingMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''' + }; + + /** + * This function serializes arbitrary data to a string. In case of data that can't be easily converted to a string, this function will create a wrapper object and serialize the data using JSON.stringify. The outcoming string will always be escaped using Chartist.escapingMap. + * If called with null or undefined the function will return immediately with null or undefined. + * + * @memberof Chartist.Core + * @param {Number|String|Object} data + * @return {String} + */ + Chartist.serialize = function(data) { + if(data === null || data === undefined) { + return data; + } else if(typeof data === 'number') { + data = ''+data; + } else if(typeof data === 'object') { + data = JSON.stringify({data: data}); + } + + return Object.keys(Chartist.escapingMap).reduce(function(result, key) { + return Chartist.replaceAll(result, key, Chartist.escapingMap[key]); + }, data); + }; + + /** + * This function de-serializes a string previously serialized with Chartist.serialize. The string will always be unescaped using Chartist.escapingMap before it's returned. Based on the input value the return type can be Number, String or Object. JSON.parse is used with try / catch to see if the unescaped string can be parsed into an Object and this Object will be returned on success. + * + * @memberof Chartist.Core + * @param {String} data + * @return {String|Number|Object} + */ + Chartist.deserialize = function(data) { + if(typeof data !== 'string') { + return data; + } + + data = Object.keys(Chartist.escapingMap).reduce(function(result, key) { + return Chartist.replaceAll(result, Chartist.escapingMap[key], key); + }, data); + + try { + data = JSON.parse(data); + data = data.data !== undefined ? data.data : data; + } catch(e) {} + + return data; + }; + + /** + * Create or reinitialize the SVG element for the chart + * + * @memberof Chartist.Core + * @param {Node} container The containing DOM Node object that will be used to plant the SVG element + * @param {String} width Set the width of the SVG element. Default is 100% + * @param {String} height Set the height of the SVG element. Default is 100% + * @param {String} className Specify a class to be added to the SVG element + * @return {Object} The created/reinitialized SVG element + */ + Chartist.createSvg = function (container, width, height, className) { + var svg; + + width = width || '100%'; + height = height || '100%'; + + // Check if there is a previous SVG element in the container that contains the Chartist XML namespace and remove it + // Since the DOM API does not support namespaces we need to manually search the returned list http://www.w3.org/TR/selectors-api/ + Array.prototype.slice.call(container.querySelectorAll('svg')).filter(function filterChartistSvgObjects(svg) { + return svg.getAttribute(Chartist.xmlNs.qualifiedName); + }).forEach(function removePreviousElement(svg) { + container.removeChild(svg); + }); + + // Create svg object with width and height or use 100% as default + svg = new Chartist.Svg('svg').attr({ + width: width, + height: height + }).addClass(className).attr({ + style: 'width: ' + width + '; height: ' + height + ';' + }); + + // Add the DOM node to our container + container.appendChild(svg._node); + + return svg; + }; + + + /** + * Reverses the series, labels and series data arrays. + * + * @memberof Chartist.Core + * @param data + */ + Chartist.reverseData = function(data) { + data.labels.reverse(); + data.series.reverse(); + for (var i = 0; i < data.series.length; i++) { + if(typeof(data.series[i]) === 'object' && data.series[i].data !== undefined) { + data.series[i].data.reverse(); + } else { + data.series[i].reverse(); + } + } + }; + + /** + * Convert data series into plain array + * + * @memberof Chartist.Core + * @param {Object} data The series object that contains the data to be visualized in the chart + * @param {Boolean} reverse If true the whole data is reversed by the getDataArray call. This will modify the data object passed as first parameter. The labels as well as the series order is reversed. The whole series data arrays are reversed too. + * @return {Array} A plain array that contains the data to be visualized in the chart + */ + Chartist.getDataArray = function (data, reverse) { + var array = [], + value, + localData; + + // If the data should be reversed but isn't we need to reverse it + // If it's reversed but it shouldn't we need to reverse it back + // That's required to handle data updates correctly and to reflect the responsive configurations + if(reverse && !data.reversed || !reverse && data.reversed) { + Chartist.reverseData(data); + data.reversed = !data.reversed; + } + + for (var i = 0; i < data.series.length; i++) { + // If the series array contains an object with a data property we will use the property + // otherwise the value directly (array or number). + // We create a copy of the original data array with Array.prototype.push.apply + localData = typeof(data.series[i]) === 'object' && data.series[i].data !== undefined ? data.series[i].data : data.series[i]; + if(localData instanceof Array) { + array[i] = []; + Array.prototype.push.apply(array[i], localData); + } else { + array[i] = localData; + } + + // Convert object values to numbers + for (var j = 0; j < array[i].length; j++) { + value = array[i][j]; + value = value.value === 0 ? 0 : (value.value || value); + array[i][j] = +value; + } + } + + return array; + }; + + /** + * Adds missing values at the end of the array. This array contains the data, that will be visualized in the chart + * + * @memberof Chartist.Core + * @param {Array} dataArray The array that contains the data to be visualized in the chart. The array in this parameter will be modified by function. + * @param {Number} length The length of the x-axis data array. + * @return {Array} The array that got updated with missing values. + */ + Chartist.normalizeDataArray = function (dataArray, length) { + for (var i = 0; i < dataArray.length; i++) { + if (dataArray[i].length === length) { + continue; + } + + for (var j = dataArray[i].length; j < length; j++) { + dataArray[i][j] = 0; + } + } + + return dataArray; + }; + + Chartist.getMetaData = function(series, index) { + var value = series.data ? series.data[index] : series[index]; + return value ? Chartist.serialize(value.meta) : undefined; + }; + + /** + * Calculate the order of magnitude for the chart scale + * + * @memberof Chartist.Core + * @param {Number} value The value Range of the chart + * @return {Number} The order of magnitude + */ + Chartist.orderOfMagnitude = function (value) { + return Math.floor(Math.log(Math.abs(value)) / Math.LN10); + }; + + /** + * Project a data length into screen coordinates (pixels) + * + * @memberof Chartist.Core + * @param {Object} axisLength The svg element for the chart + * @param {Number} length Single data value from a series array + * @param {Object} bounds All the values to set the bounds of the chart + * @return {Number} The projected data length in pixels + */ + Chartist.projectLength = function (axisLength, length, bounds) { + return length / bounds.range * axisLength; + }; + + /** + * Get the height of the area in the chart for the data series + * + * @memberof Chartist.Core + * @param {Object} svg The svg element for the chart + * @param {Object} options The Object that contains all the optional values for the chart + * @return {Number} The height of the area in the chart for the data series + */ + Chartist.getAvailableHeight = function (svg, options) { + return Math.max((Chartist.stripUnit(options.height) || svg.height()) - (options.chartPadding * 2) - options.axisX.offset, 0); + }; + + /** + * Get highest and lowest value of data array. This Array contains the data that will be visualized in the chart. + * + * @memberof Chartist.Core + * @param {Array} dataArray The array that contains the data to be visualized in the chart + * @return {Object} An object that contains the highest and lowest value that will be visualized on the chart. + */ + Chartist.getHighLow = function (dataArray) { + var i, + j, + highLow = { + high: -Number.MAX_VALUE, + low: Number.MAX_VALUE + }; + + for (i = 0; i < dataArray.length; i++) { + for (j = 0; j < dataArray[i].length; j++) { + if (dataArray[i][j] > highLow.high) { + highLow.high = dataArray[i][j]; + } + + if (dataArray[i][j] < highLow.low) { + highLow.low = dataArray[i][j]; + } + } + } + + return highLow; + }; + + /** + * Calculate and retrieve all the bounds for the chart and return them in one array + * + * @memberof Chartist.Core + * @param {Number} axisLength The length of the Axis used for + * @param {Object} highLow An object containing a high and low property indicating the value range of the chart. + * @param {Number} scaleMinSpace The minimum projected length a step should result in + * @param {Number} referenceValue The reference value for the chart. + * @return {Object} All the values to set the bounds of the chart + */ + Chartist.getBounds = function (axisLength, highLow, scaleMinSpace, referenceValue) { + var i, + newMin, + newMax, + bounds = { + high: highLow.high, + low: highLow.low + }; + + // If high and low are the same because of misconfiguration or flat data (only the same value) we need + // to set the high or low to 0 depending on the polarity + if(bounds.high === bounds.low) { + // If both values are 0 we set high to 1 + if(bounds.low === 0) { + bounds.high = 1; + } else if(bounds.low < 0) { + // If we have the same negative value for the bounds we set bounds.high to 0 + bounds.high = 0; + } else { + // If we have the same positive value for the bounds we set bounds.low to 0 + bounds.low = 0; + } + } + + // Overrides of high / low based on reference value, it will make sure that the invisible reference value is + // used to generate the chart. This is useful when the chart always needs to contain the position of the + // invisible reference value in the view i.e. for bipolar scales. + if (referenceValue || referenceValue === 0) { + bounds.high = Math.max(referenceValue, bounds.high); + bounds.low = Math.min(referenceValue, bounds.low); + } + + bounds.valueRange = bounds.high - bounds.low; + bounds.oom = Chartist.orderOfMagnitude(bounds.valueRange); + bounds.min = Math.floor(bounds.low / Math.pow(10, bounds.oom)) * Math.pow(10, bounds.oom); + bounds.max = Math.ceil(bounds.high / Math.pow(10, bounds.oom)) * Math.pow(10, bounds.oom); + bounds.range = bounds.max - bounds.min; + bounds.step = Math.pow(10, bounds.oom); + bounds.numberOfSteps = Math.round(bounds.range / bounds.step); + + // Optimize scale step by checking if subdivision is possible based on horizontalGridMinSpace + // If we are already below the scaleMinSpace value we will scale up + var length = Chartist.projectLength(axisLength, bounds.step, bounds), + scaleUp = length < scaleMinSpace; + + while (true) { + if (scaleUp && Chartist.projectLength(axisLength, bounds.step, bounds) <= scaleMinSpace) { + bounds.step *= 2; + } else if (!scaleUp && Chartist.projectLength(axisLength, bounds.step / 2, bounds) >= scaleMinSpace) { + bounds.step /= 2; + } else { + break; + } + } + + // Narrow min and max based on new step + newMin = bounds.min; + newMax = bounds.max; + for (i = bounds.min; i <= bounds.max; i += bounds.step) { + if (i + bounds.step < bounds.low) { + newMin += bounds.step; + } + + if (i - bounds.step >= bounds.high) { + newMax -= bounds.step; + } + } + bounds.min = newMin; + bounds.max = newMax; + bounds.range = bounds.max - bounds.min; + + bounds.values = []; + for (i = bounds.min; i <= bounds.max; i += bounds.step) { + bounds.values.push(i); + } + + return bounds; + }; + + /** + * Calculate cartesian coordinates of polar coordinates + * + * @memberof Chartist.Core + * @param {Number} centerX X-axis coordinates of center point of circle segment + * @param {Number} centerY X-axis coordinates of center point of circle segment + * @param {Number} radius Radius of circle segment + * @param {Number} angleInDegrees Angle of circle segment in degrees + * @return {Number} Coordinates of point on circumference + */ + Chartist.polarToCartesian = function (centerX, centerY, radius, angleInDegrees) { + var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0; + + return { + x: centerX + (radius * Math.cos(angleInRadians)), + y: centerY + (radius * Math.sin(angleInRadians)) + }; + }; + + /** + * Initialize chart drawing rectangle (area where chart is drawn) x1,y1 = bottom left / x2,y2 = top right + * + * @memberof Chartist.Core + * @param {Object} svg The svg element for the chart + * @param {Object} options The Object that contains all the optional values for the chart + * @return {Object} The chart rectangles coordinates inside the svg element plus the rectangles measurements + */ + Chartist.createChartRect = function (svg, options) { + var yOffset = options.axisY ? options.axisY.offset || 0 : 0, + xOffset = options.axisX ? options.axisX.offset || 0 : 0, + w = Chartist.stripUnit(options.width) || svg.width(), + h = Chartist.stripUnit(options.height) || svg.height(); + + return { + x1: options.chartPadding + yOffset, + y1: Math.max(h - options.chartPadding - xOffset, options.chartPadding), + x2: Math.max(w - options.chartPadding, options.chartPadding + yOffset), + y2: options.chartPadding, + width: function () { + return this.x2 - this.x1; + }, + height: function () { + return this.y1 - this.y2; + } + }; + }; + + /** + * Creates a grid line based on a projected value. + * + * @memberof Chartist.Core + * @param projectedValue + * @param index + * @param axis + * @param offset + * @param length + * @param group + * @param classes + * @param eventEmitter + */ + Chartist.createGrid = function(projectedValue, index, axis, offset, length, group, classes, eventEmitter) { + var positionalData = {}; + positionalData[axis.units.pos + '1'] = projectedValue.pos; + positionalData[axis.units.pos + '2'] = projectedValue.pos; + positionalData[axis.counterUnits.pos + '1'] = offset; + positionalData[axis.counterUnits.pos + '2'] = offset + length; + + var gridElement = group.elem('line', positionalData, classes.join(' ')); + + // Event for grid draw + eventEmitter.emit('draw', + Chartist.extend({ + type: 'grid', + axis: axis.units.pos, + index: index, + group: group, + element: gridElement + }, positionalData) + ); + }; + + /** + * Creates a label based on a projected value and an axis. + * + * @memberof Chartist.Core + * @param projectedValue + * @param index + * @param labels + * @param axis + * @param axisOffset + * @param labelOffset + * @param group + * @param classes + * @param useForeignObject + * @param eventEmitter + */ + Chartist.createLabel = function(projectedValue, index, labels, axis, axisOffset, labelOffset, group, classes, useForeignObject, eventEmitter) { + var labelElement, + positionalData = {}; + positionalData[axis.units.pos] = projectedValue.pos + labelOffset[axis.units.pos]; + positionalData[axis.counterUnits.pos] = labelOffset[axis.counterUnits.pos]; + positionalData[axis.units.len] = projectedValue.len; + positionalData[axis.counterUnits.len] = axisOffset; + + if(useForeignObject) { + var content = '' + labels[index] + ''; + labelElement = group.foreignObject(content, Chartist.extend({ + style: 'overflow: visible;' + }, positionalData)); + } else { + labelElement = group.elem('text', positionalData, classes.join(' ')).text(labels[index]); + } + + eventEmitter.emit('draw', Chartist.extend({ + type: 'label', + axis: axis, + index: index, + group: group, + element: labelElement, + text: labels[index] + }, positionalData)); + }; + + /** + * This function creates a whole axis with its grid lines and labels based on an axis model and a chartRect. + * + * @memberof Chartist.Core + * @param axis + * @param data + * @param chartRect + * @param gridGroup + * @param labelGroup + * @param useForeignObject + * @param options + * @param eventEmitter + */ + Chartist.createAxis = function(axis, data, chartRect, gridGroup, labelGroup, useForeignObject, options, eventEmitter) { + var axisOptions = options['axis' + axis.units.pos.toUpperCase()], + projectedValues = data.map(axis.projectValue.bind(axis)).map(axis.transform), + labelValues = data.map(axisOptions.labelInterpolationFnc); + + projectedValues.forEach(function(projectedValue, index) { + // Skip grid lines and labels where interpolated label values are falsey (execpt for 0) + if(!labelValues[index] && labelValues[index] !== 0) { + return; + } + + if(axisOptions.showGrid) { + Chartist.createGrid(projectedValue, index, axis, axis.gridOffset, chartRect[axis.counterUnits.len](), gridGroup, [ + options.classNames.grid, + options.classNames[axis.units.dir] + ], eventEmitter); + } + + if(axisOptions.showLabel) { + Chartist.createLabel(projectedValue, index, labelValues, axis, axisOptions.offset, axis.labelOffset, labelGroup, [ + options.classNames.label, + options.classNames[axis.units.dir] + ], useForeignObject, eventEmitter); + } + }); + }; + + /** + * Provides options handling functionality with callback for options changes triggered by responsive options and media query matches + * + * @memberof Chartist.Core + * @param {Object} options Options set by user + * @param {Array} responsiveOptions Optional functions to add responsive behavior to chart + * @param {Object} eventEmitter The event emitter that will be used to emit the options changed events + * @return {Object} The consolidated options object from the defaults, base and matching responsive options + */ + Chartist.optionsProvider = function (options, responsiveOptions, eventEmitter) { + var baseOptions = Chartist.extend({}, options), + currentOptions, + mediaQueryListeners = [], + i; + + function updateCurrentOptions() { + var previousOptions = currentOptions; + currentOptions = Chartist.extend({}, baseOptions); + + if (responsiveOptions) { + for (i = 0; i < responsiveOptions.length; i++) { + var mql = window.matchMedia(responsiveOptions[i][0]); + if (mql.matches) { + currentOptions = Chartist.extend(currentOptions, responsiveOptions[i][1]); + } + } + } + + if(eventEmitter) { + eventEmitter.emit('optionsChanged', { + previousOptions: previousOptions, + currentOptions: currentOptions + }); + } + } + + function removeMediaQueryListeners() { + mediaQueryListeners.forEach(function(mql) { + mql.removeListener(updateCurrentOptions); + }); + } + + if (!window.matchMedia) { + throw 'window.matchMedia not found! Make sure you\'re using a polyfill.'; + } else if (responsiveOptions) { + + for (i = 0; i < responsiveOptions.length; i++) { + var mql = window.matchMedia(responsiveOptions[i][0]); + mql.addListener(updateCurrentOptions); + mediaQueryListeners.push(mql); + } + } + // Execute initially so we get the correct options + updateCurrentOptions(); + + return { + get currentOptions() { + return Chartist.extend({}, currentOptions); + }, + removeMediaQueryListeners: removeMediaQueryListeners + }; + }; + + //http://schepers.cc/getting-to-the-point + Chartist.catmullRom2bezier = function (crp, z) { + var d = []; + for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { + var p = [ + {x: +crp[i - 2], y: +crp[i - 1]}, + {x: +crp[i], y: +crp[i + 1]}, + {x: +crp[i + 2], y: +crp[i + 3]}, + {x: +crp[i + 4], y: +crp[i + 5]} + ]; + if (z) { + if (!i) { + p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]}; + } else if (iLen - 4 === i) { + p[3] = {x: +crp[0], y: +crp[1]}; + } else if (iLen - 2 === i) { + p[2] = {x: +crp[0], y: +crp[1]}; + p[3] = {x: +crp[2], y: +crp[3]}; + } + } else { + if (iLen - 4 === i) { + p[3] = p[2]; + } else if (!i) { + p[0] = {x: +crp[i], y: +crp[i + 1]}; + } + } + d.push( + [ + (-p[0].x + 6 * p[1].x + p[2].x) / 6, + (-p[0].y + 6 * p[1].y + p[2].y) / 6, + (p[1].x + 6 * p[2].x - p[3].x) / 6, + (p[1].y + 6 * p[2].y - p[3].y) / 6, + p[2].x, + p[2].y + ] + ); + } + + return d; + }; + + }(window, document, Chartist)); + ;/** + * Chartist path interpolation functions. + * + * @module Chartist.Interpolation + */ + /* global Chartist */ + (function(window, document, Chartist) { + 'use strict'; + + Chartist.Interpolation = {}; + + /** + * This interpolation function does not smooth the path and the result is only containing lines and no curves. + * + * @memberof Chartist.Interpolation + * @return {Function} + */ + Chartist.Interpolation.none = function() { + return function cardinal(pathCoordinates) { + var path = new Chartist.Svg.Path().move(pathCoordinates[0], pathCoordinates[1]); + + for(var i = 3; i < pathCoordinates.length; i += 2) { + path.line(pathCoordinates[i - 1], pathCoordinates[i]); + } + + return path; + }; + }; + + /** + * Simple smoothing creates horizontal handles that are positioned with a fraction of the length between two data points. You can use the divisor option to specify the amount of smoothing. + * + * Simple smoothing can be used instead of `Chartist.Smoothing.cardinal` if you'd like to get rid of the artifacts it produces sometimes. Simple smoothing produces less flowing lines but is accurate by hitting the points and it also doesn't swing below or above the given data point. + * + * All smoothing functions within Chartist are factory functions that accept an options parameter. The simple interpolation function accepts one configuration parameter `divisor`, between 1 and ∞, which controls the smoothing characteristics. + * + * @example + * var chart = new Chartist.Line('.ct-chart', { + * labels: [1, 2, 3, 4, 5], + * series: [[1, 2, 8, 1, 7]] + * }, { + * lineSmooth: Chartist.Interpolation.simple({ + * divisor: 2 + * }) + * }); + * + * + * @memberof Chartist.Interpolation + * @param {Object} options The options of the simple interpolation factory function. + * @return {Function} + */ + Chartist.Interpolation.simple = function(options) { + var defaultOptions = { + divisor: 2 + }; + options = Chartist.extend({}, defaultOptions, options); + + var d = 1 / Math.max(1, options.divisor); + + return function simple(pathCoordinates) { + var path = new Chartist.Svg.Path().move(pathCoordinates[0], pathCoordinates[1]); + + for(var i = 2; i < pathCoordinates.length; i += 2) { + var prevX = pathCoordinates[i - 2], + prevY = pathCoordinates[i - 1], + currX = pathCoordinates[i], + currY = pathCoordinates[i + 1], + length = (currX - prevX) * d; + + path.curve( + prevX + length, + prevY, + currX - length, + currY, + currX, + currY + ); + } + + return path; + }; + }; + + /** + * Cardinal / Catmull-Rome spline interpolation is the default smoothing function in Chartist. It produces nice results where the splines will always meet the points. It produces some artifacts though when data values are increased or decreased rapidly. The line may not follow a very accurate path and if the line should be accurate this smoothing function does not produce the best results. + * + * Cardinal splines can only be created if there are more than two data points. If this is not the case this smoothing will fallback to `Chartist.Smoothing.none`. + * + * All smoothing functions within Chartist are factory functions that accept an options parameter. The cardinal interpolation function accepts one configuration parameter `tension`, between 0 and 1, which controls the smoothing intensity. + * + * @example + * var chart = new Chartist.Line('.ct-chart', { + * labels: [1, 2, 3, 4, 5], + * series: [[1, 2, 8, 1, 7]] + * }, { + * lineSmooth: Chartist.Interpolation.cardinal({ + * tension: 1 + * }) + * }); + * + * @memberof Chartist.Interpolation + * @param {Object} options The options of the cardinal factory function. + * @return {Function} + */ + Chartist.Interpolation.cardinal = function(options) { + var defaultOptions = { + tension: 1 + }; + + options = Chartist.extend({}, defaultOptions, options); + + var t = Math.min(1, Math.max(0, options.tension)), + c = 1 - t; + + return function cardinal(pathCoordinates) { + // If less than two points we need to fallback to no smoothing + if(pathCoordinates.length <= 4) { + return Chartist.Interpolation.none()(pathCoordinates); + } + + var path = new Chartist.Svg.Path().move(pathCoordinates[0], pathCoordinates[1]), + z; + + for (var i = 0, iLen = pathCoordinates.length; iLen - 2 * !z > i; i += 2) { + var p = [ + {x: +pathCoordinates[i - 2], y: +pathCoordinates[i - 1]}, + {x: +pathCoordinates[i], y: +pathCoordinates[i + 1]}, + {x: +pathCoordinates[i + 2], y: +pathCoordinates[i + 3]}, + {x: +pathCoordinates[i + 4], y: +pathCoordinates[i + 5]} + ]; + if (z) { + if (!i) { + p[0] = {x: +pathCoordinates[iLen - 2], y: +pathCoordinates[iLen - 1]}; + } else if (iLen - 4 === i) { + p[3] = {x: +pathCoordinates[0], y: +pathCoordinates[1]}; + } else if (iLen - 2 === i) { + p[2] = {x: +pathCoordinates[0], y: +pathCoordinates[1]}; + p[3] = {x: +pathCoordinates[2], y: +pathCoordinates[3]}; + } + } else { + if (iLen - 4 === i) { + p[3] = p[2]; + } else if (!i) { + p[0] = {x: +pathCoordinates[i], y: +pathCoordinates[i + 1]}; + } + } + + path.curve( + (t * (-p[0].x + 6 * p[1].x + p[2].x) / 6) + (c * p[2].x), + (t * (-p[0].y + 6 * p[1].y + p[2].y) / 6) + (c * p[2].y), + (t * (p[1].x + 6 * p[2].x - p[3].x) / 6) + (c * p[2].x), + (t * (p[1].y + 6 * p[2].y - p[3].y) / 6) + (c * p[2].y), + p[2].x, + p[2].y + ); + } + + return path; + }; + }; + + }(window, document, Chartist)); + ;/** + * A very basic event module that helps to generate and catch events. + * + * @module Chartist.Event + */ + /* global Chartist */ + (function (window, document, Chartist) { + 'use strict'; + + Chartist.EventEmitter = function () { + var handlers = []; + + /** + * Add an event handler for a specific event + * + * @memberof Chartist.Event + * @param {String} event The event name + * @param {Function} handler A event handler function + */ + function addEventHandler(event, handler) { + handlers[event] = handlers[event] || []; + handlers[event].push(handler); + } + + /** + * Remove an event handler of a specific event name or remove all event handlers for a specific event. + * + * @memberof Chartist.Event + * @param {String} event The event name where a specific or all handlers should be removed + * @param {Function} [handler] An optional event handler function. If specified only this specific handler will be removed and otherwise all handlers are removed. + */ + function removeEventHandler(event, handler) { + // Only do something if there are event handlers with this name existing + if(handlers[event]) { + // If handler is set we will look for a specific handler and only remove this + if(handler) { + handlers[event].splice(handlers[event].indexOf(handler), 1); + if(handlers[event].length === 0) { + delete handlers[event]; + } + } else { + // If no handler is specified we remove all handlers for this event + delete handlers[event]; + } + } + } + + /** + * Use this function to emit an event. All handlers that are listening for this event will be triggered with the data parameter. + * + * @memberof Chartist.Event + * @param {String} event The event name that should be triggered + * @param {*} data Arbitrary data that will be passed to the event handler callback functions + */ + function emit(event, data) { + // Only do something if there are event handlers with this name existing + if(handlers[event]) { + handlers[event].forEach(function(handler) { + handler(data); + }); + } + + // Emit event to star event handlers + if(handlers['*']) { + handlers['*'].forEach(function(starHandler) { + starHandler(event, data); + }); + } + } + + return { + addEventHandler: addEventHandler, + removeEventHandler: removeEventHandler, + emit: emit + }; + }; + + }(window, document, Chartist)); + ;/** + * This module provides some basic prototype inheritance utilities. + * + * @module Chartist.Class + */ + /* global Chartist */ + (function(window, document, Chartist) { + 'use strict'; + + function listToArray(list) { + var arr = []; + if (list.length) { + for (var i = 0; i < list.length; i++) { + arr.push(list[i]); + } + } + return arr; + } + + /** + * Method to extend from current prototype. + * + * @memberof Chartist.Class + * @param {Object} properties The object that serves as definition for the prototype that gets created for the new class. This object should always contain a constructor property that is the desired constructor for the newly created class. + * @param {Object} [superProtoOverride] By default extens will use the current class prototype or Chartist.class. With this parameter you can specify any super prototype that will be used. + * @return {Function} Constructor function of the new class + * + * @example + * var Fruit = Class.extend({ + * color: undefined, + * sugar: undefined, + * + * constructor: function(color, sugar) { + * this.color = color; + * this.sugar = sugar; + * }, + * + * eat: function() { + * this.sugar = 0; + * return this; + * } + * }); + * + * var Banana = Fruit.extend({ + * length: undefined, + * + * constructor: function(length, sugar) { + * Banana.super.constructor.call(this, 'Yellow', sugar); + * this.length = length; + * } + * }); + * + * var banana = new Banana(20, 40); + * console.log('banana instanceof Fruit', banana instanceof Fruit); + * console.log('Fruit is prototype of banana', Fruit.prototype.isPrototypeOf(banana)); + * console.log('bananas prototype is Fruit', Object.getPrototypeOf(banana) === Fruit.prototype); + * console.log(banana.sugar); + * console.log(banana.eat().sugar); + * console.log(banana.color); + */ + function extend(properties, superProtoOverride) { + var superProto = superProtoOverride || this.prototype || Chartist.Class; + var proto = Object.create(superProto); + + Chartist.Class.cloneDefinitions(proto, properties); + + var constr = function() { + var fn = proto.constructor || function () {}, + instance; + + // If this is linked to the Chartist namespace the constructor was not called with new + // To provide a fallback we will instantiate here and return the instance + instance = this === Chartist ? Object.create(proto) : this; + fn.apply(instance, Array.prototype.slice.call(arguments, 0)); + + // If this constructor was not called with new we need to return the instance + // This will not harm when the constructor has been called with new as the returned value is ignored + return instance; + }; + + constr.prototype = proto; + constr.super = superProto; + constr.extend = this.extend; + + return constr; + } + + // Variable argument list clones args > 0 into args[0] and retruns modified args[0] + function cloneDefinitions() { + var args = listToArray(arguments); + var target = args[0]; + + args.splice(1, args.length - 1).forEach(function (source) { + Object.getOwnPropertyNames(source).forEach(function (propName) { + // If this property already exist in target we delete it first + delete target[propName]; + // Define the property with the descriptor from source + Object.defineProperty(target, propName, + Object.getOwnPropertyDescriptor(source, propName)); + }); + }); + + return target; + } + + Chartist.Class = { + extend: extend, + cloneDefinitions: cloneDefinitions + }; + + }(window, document, Chartist)); + ;/** + * Base for all chart types. The methods in Chartist.Base are inherited to all chart types. + * + * @module Chartist.Base + */ + /* global Chartist */ + (function(window, document, Chartist) { + 'use strict'; + + // TODO: Currently we need to re-draw the chart on window resize. This is usually very bad and will affect performance. + // This is done because we can't work with relative coordinates when drawing the chart because SVG Path does not + // work with relative positions yet. We need to check if we can do a viewBox hack to switch to percentage. + // See http://mozilla.6506.n7.nabble.com/Specyfing-paths-with-percentages-unit-td247474.html + // Update: can be done using the above method tested here: http://codepen.io/gionkunz/pen/KDvLj + // The problem is with the label offsets that can't be converted into percentage and affecting the chart container + /** + * Updates the chart which currently does a full reconstruction of the SVG DOM + * + * @param {Object} [data] Optional data you'd like to set for the chart before it will update. If not specified the update method will use the data that is already configured with the chart. + * @param {Object} [options] Optional options you'd like to add to the previous options for the chart before it will update. If not specified the update method will use the options that have been already configured with the chart. + * @param {Boolean} [extendObjects] If set to true, the passed options will be used to extend the options that have been configured already. + * @memberof Chartist.Base + */ + function update(data, options, extendObjects) { + if(data) { + this.data = data; + // Event for data transformation that allows to manipulate the data before it gets rendered in the charts + this.eventEmitter.emit('data', { + type: 'update', + data: this.data + }); + } + + if(options) { + this.options = Chartist.extend({}, extendObjects ? this.options : {}, options); + + // If chartist was not initialized yet, we just set the options and leave the rest to the initialization + if(!this.initializeTimeoutId) { + this.optionsProvider.removeMediaQueryListeners(); + this.optionsProvider = Chartist.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter); + } + } + + // Only re-created the chart if it has been initialized yet + if(!this.initializeTimeoutId) { + this.createChart(this.optionsProvider.currentOptions); + } + + // Return a reference to the chart object to chain up calls + return this; + } + + /** + * This method can be called on the API object of each chart and will un-register all event listeners that were added to other components. This currently includes a window.resize listener as well as media query listeners if any responsive options have been provided. Use this function if you need to destroy and recreate Chartist charts dynamically. + * + * @memberof Chartist.Base + */ + function detach() { + window.removeEventListener('resize', this.resizeListener); + this.optionsProvider.removeMediaQueryListeners(); + return this; + } + + /** + * Use this function to register event handlers. The handler callbacks are synchronous and will run in the main thread rather than the event loop. + * + * @memberof Chartist.Base + * @param {String} event Name of the event. Check the examples for supported events. + * @param {Function} handler The handler function that will be called when an event with the given name was emitted. This function will receive a data argument which contains event data. See the example for more details. + */ + function on(event, handler) { + this.eventEmitter.addEventHandler(event, handler); + return this; + } + + /** + * Use this function to un-register event handlers. If the handler function parameter is omitted all handlers for the given event will be un-registered. + * + * @memberof Chartist.Base + * @param {String} event Name of the event for which a handler should be removed + * @param {Function} [handler] The handler function that that was previously used to register a new event handler. This handler will be removed from the event handler list. If this parameter is omitted then all event handlers for the given event are removed from the list. + */ + function off(event, handler) { + this.eventEmitter.removeEventHandler(event, handler); + return this; + } + + function initialize() { + // Add window resize listener that re-creates the chart + window.addEventListener('resize', this.resizeListener); + + // Obtain current options based on matching media queries (if responsive options are given) + // This will also register a listener that is re-creating the chart based on media changes + this.optionsProvider = Chartist.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter); + // Register options change listener that will trigger a chart update + this.eventEmitter.addEventHandler('optionsChanged', function() { + this.update(); + }.bind(this)); + + // Before the first chart creation we need to register us with all plugins that are configured + // Initialize all relevant plugins with our chart object and the plugin options specified in the config + if(this.options.plugins) { + this.options.plugins.forEach(function(plugin) { + if(plugin instanceof Array) { + plugin[0](this, plugin[1]); + } else { + plugin(this); + } + }.bind(this)); + } + + // Event for data transformation that allows to manipulate the data before it gets rendered in the charts + this.eventEmitter.emit('data', { + type: 'initial', + data: this.data + }); + + // Create the first chart + this.createChart(this.optionsProvider.currentOptions); + + // As chart is initialized from the event loop now we can reset our timeout reference + // This is important if the chart gets initialized on the same element twice + this.initializeTimeoutId = undefined; + } + + /** + * Constructor of chart base class. + * + * @param query + * @param data + * @param options + * @param responsiveOptions + * @constructor + */ + function Base(query, data, options, responsiveOptions) { + this.container = Chartist.querySelector(query); + this.data = data; + this.options = options; + this.responsiveOptions = responsiveOptions; + this.eventEmitter = Chartist.EventEmitter(); + this.supportsForeignObject = Chartist.Svg.isSupported('Extensibility'); + this.supportsAnimations = Chartist.Svg.isSupported('AnimationEventsAttribute'); + this.resizeListener = function resizeListener(){ + this.update(); + }.bind(this); + + if(this.container) { + // If chartist was already initialized in this container we are detaching all event listeners first + if(this.container.__chartist__) { + if(this.container.__chartist__.initializeTimeoutId) { + // If the initializeTimeoutId is still set we can safely assume that the initialization function has not + // been called yet from the event loop. Therefore we should cancel the timeout and don't need to detach + window.clearTimeout(this.container.__chartist__.initializeTimeoutId); + } else { + // The timeout reference has already been reset which means we need to detach the old chart first + this.container.__chartist__.detach(); + } + } + + this.container.__chartist__ = this; + } + + // Using event loop for first draw to make it possible to register event listeners in the same call stack where + // the chart was created. + this.initializeTimeoutId = setTimeout(initialize.bind(this), 0); + } + + // Creating the chart base class + Chartist.Base = Chartist.Class.extend({ + constructor: Base, + optionsProvider: undefined, + container: undefined, + svg: undefined, + eventEmitter: undefined, + createChart: function() { + throw new Error('Base chart type can\'t be instantiated!'); + }, + update: update, + detach: detach, + on: on, + off: off, + version: Chartist.version, + supportsForeignObject: false + }); + + }(window, document, Chartist)); + ;/** + * Chartist SVG module for simple SVG DOM abstraction + * + * @module Chartist.Svg + */ + /* global Chartist */ + (function(window, document, Chartist) { + 'use strict'; + + var svgNs = 'http://www.w3.org/2000/svg', + xmlNs = 'http://www.w3.org/2000/xmlns/', + xhtmlNs = 'http://www.w3.org/1999/xhtml'; + + Chartist.xmlNs = { + qualifiedName: 'xmlns:ct', + prefix: 'ct', + uri: 'http://gionkunz.github.com/chartist-js/ct' + }; + + /** + * Chartist.Svg creates a new SVG object wrapper with a starting element. You can use the wrapper to fluently create sub-elements and modify them. + * + * @memberof Chartist.Svg + * @constructor + * @param {String|SVGElement} name The name of the SVG element to create or an SVG dom element which should be wrapped into Chartist.Svg + * @param {Object} attributes An object with properties that will be added as attributes to the SVG element that is created. Attributes with undefined values will not be added. + * @param {String} className This class or class list will be added to the SVG element + * @param {Object} parent The parent SVG wrapper object where this newly created wrapper and it's element will be attached to as child + * @param {Boolean} insertFirst If this param is set to true in conjunction with a parent element the newly created element will be added as first child element in the parent element + */ + function Svg(name, attributes, className, parent, insertFirst) { + // If Svg is getting called with an SVG element we just return the wrapper + if(name instanceof SVGElement) { + this._node = name; + } else { + this._node = document.createElementNS(svgNs, name); + + // If this is an SVG element created then custom namespace + if(name === 'svg') { + this._node.setAttributeNS(xmlNs, Chartist.xmlNs.qualifiedName, Chartist.xmlNs.uri); + } + + if(attributes) { + this.attr(attributes); + } + + if(className) { + this.addClass(className); + } + + if(parent) { + if (insertFirst && parent._node.firstChild) { + parent._node.insertBefore(this._node, parent._node.firstChild); + } else { + parent._node.appendChild(this._node); + } + } + } + } + + /** + * Set attributes on the current SVG element of the wrapper you're currently working on. + * + * @memberof Chartist.Svg + * @param {Object|String} attributes An object with properties that will be added as attributes to the SVG element that is created. Attributes with undefined values will not be added. If this parameter is a String then the function is used as a getter and will return the attribute value. + * @param {String} ns If specified, the attributes will be set as namespace attributes with ns as prefix. + * @return {Object|String} The current wrapper object will be returned so it can be used for chaining or the attribute value if used as getter function. + */ + function attr(attributes, ns) { + if(typeof attributes === 'string') { + if(ns) { + return this._node.getAttributeNS(ns, attributes); + } else { + return this._node.getAttribute(attributes); + } + } + + Object.keys(attributes).forEach(function(key) { + // If the attribute value is undefined we can skip this one + if(attributes[key] === undefined) { + return; + } + + if(ns) { + this._node.setAttributeNS(ns, [Chartist.xmlNs.prefix, ':', key].join(''), attributes[key]); + } else { + this._node.setAttribute(key, attributes[key]); + } + }.bind(this)); + + return this; + } + + /** + * Create a new SVG element whose wrapper object will be selected for further operations. This way you can also create nested groups easily. + * + * @memberof Chartist.Svg + * @param {String} name The name of the SVG element that should be created as child element of the currently selected element wrapper + * @param {Object} [attributes] An object with properties that will be added as attributes to the SVG element that is created. Attributes with undefined values will not be added. + * @param {String} [className] This class or class list will be added to the SVG element + * @param {Boolean} [insertFirst] If this param is set to true in conjunction with a parent element the newly created element will be added as first child element in the parent element + * @return {Chartist.Svg} Returns a Chartist.Svg wrapper object that can be used to modify the containing SVG data + */ + function elem(name, attributes, className, insertFirst) { + return new Chartist.Svg(name, attributes, className, this, insertFirst); + } + + /** + * Returns the parent Chartist.SVG wrapper object + * + * @return {Chartist.Svg} Returns a Chartist.Svg wrapper around the parent node of the current node. If the parent node is not existing or it's not an SVG node then this function will return null. + */ + function parent() { + return this._node.parentNode instanceof SVGElement ? new Chartist.Svg(this._node.parentNode) : null; + } + + /** + * This method returns a Chartist.Svg wrapper around the root SVG element of the current tree. + * + * @return {Chartist.Svg} The root SVG element wrapped in a Chartist.Svg element + */ + function root() { + var node = this._node; + while(node.nodeName !== 'svg') { + node = node.parentNode; + } + return new Chartist.Svg(node); + } + + /** + * Find the first child SVG element of the current element that matches a CSS selector. The returned object is a Chartist.Svg wrapper. + * + * @param {String} selector A CSS selector that is used to query for child SVG elements + * @return {Chartist.Svg} The SVG wrapper for the element found or null if no element was found + */ + function querySelector(selector) { + var foundNode = this._node.querySelector(selector); + return foundNode ? new Chartist.Svg(foundNode) : null; + } + + /** + * Find the all child SVG elements of the current element that match a CSS selector. The returned object is a Chartist.Svg.List wrapper. + * + * @param {String} selector A CSS selector that is used to query for child SVG elements + * @return {Chartist.Svg.List} The SVG wrapper list for the element found or null if no element was found + */ + function querySelectorAll(selector) { + var foundNodes = this._node.querySelectorAll(selector); + return foundNodes.length ? new Chartist.Svg.List(foundNodes) : null; + } + + /** + * This method creates a foreignObject (see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject) that allows to embed HTML content into a SVG graphic. With the help of foreignObjects you can enable the usage of regular HTML elements inside of SVG where they are subject for SVG positioning and transformation but the Browser will use the HTML rendering capabilities for the containing DOM. + * + * @memberof Chartist.Svg + * @param {Node|String} content The DOM Node, or HTML string that will be converted to a DOM Node, that is then placed into and wrapped by the foreignObject + * @param {String} [attributes] An object with properties that will be added as attributes to the foreignObject element that is created. Attributes with undefined values will not be added. + * @param {String} [className] This class or class list will be added to the SVG element + * @param {Boolean} [insertFirst] Specifies if the foreignObject should be inserted as first child + * @return {Chartist.Svg} New wrapper object that wraps the foreignObject element + */ + function foreignObject(content, attributes, className, insertFirst) { + // If content is string then we convert it to DOM + // TODO: Handle case where content is not a string nor a DOM Node + if(typeof content === 'string') { + var container = document.createElement('div'); + container.innerHTML = content; + content = container.firstChild; + } + + // Adding namespace to content element + content.setAttribute('xmlns', xhtmlNs); + + // Creating the foreignObject without required extension attribute (as described here + // http://www.w3.org/TR/SVG/extend.html#ForeignObjectElement) + var fnObj = this.elem('foreignObject', attributes, className, insertFirst); + + // Add content to foreignObjectElement + fnObj._node.appendChild(content); + + return fnObj; + } + + /** + * This method adds a new text element to the current Chartist.Svg wrapper. + * + * @memberof Chartist.Svg + * @param {String} t The text that should be added to the text element that is created + * @return {Chartist.Svg} The same wrapper object that was used to add the newly created element + */ + function text(t) { + this._node.appendChild(document.createTextNode(t)); + return this; + } + + /** + * This method will clear all child nodes of the current wrapper object. + * + * @memberof Chartist.Svg + * @return {Chartist.Svg} The same wrapper object that got emptied + */ + function empty() { + while (this._node.firstChild) { + this._node.removeChild(this._node.firstChild); + } + + return this; + } + + /** + * This method will cause the current wrapper to remove itself from its parent wrapper. Use this method if you'd like to get rid of an element in a given DOM structure. + * + * @memberof Chartist.Svg + * @return {Chartist.Svg} The parent wrapper object of the element that got removed + */ + function remove() { + this._node.parentNode.removeChild(this._node); + return this.parent(); + } + + /** + * This method will replace the element with a new element that can be created outside of the current DOM. + * + * @memberof Chartist.Svg + * @param {Chartist.Svg} newElement The new Chartist.Svg object that will be used to replace the current wrapper object + * @return {Chartist.Svg} The wrapper of the new element + */ + function replace(newElement) { + this._node.parentNode.replaceChild(newElement._node, this._node); + return newElement; + } + + /** + * This method will append an element to the current element as a child. + * + * @memberof Chartist.Svg + * @param {Chartist.Svg} element The Chartist.Svg element that should be added as a child + * @param {Boolean} [insertFirst] Specifies if the element should be inserted as first child + * @return {Chartist.Svg} The wrapper of the appended object + */ + function append(element, insertFirst) { + if(insertFirst && this._node.firstChild) { + this._node.insertBefore(element._node, this._node.firstChild); + } else { + this._node.appendChild(element._node); + } + + return this; + } + + /** + * Returns an array of class names that are attached to the current wrapper element. This method can not be chained further. + * + * @memberof Chartist.Svg + * @return {Array} A list of classes or an empty array if there are no classes on the current element + */ + function classes() { + return this._node.getAttribute('class') ? this._node.getAttribute('class').trim().split(/\s+/) : []; + } + + /** + * Adds one or a space separated list of classes to the current element and ensures the classes are only existing once. + * + * @memberof Chartist.Svg + * @param {String} names A white space separated list of class names + * @return {Chartist.Svg} The wrapper of the current element + */ + function addClass(names) { + this._node.setAttribute('class', + this.classes(this._node) + .concat(names.trim().split(/\s+/)) + .filter(function(elem, pos, self) { + return self.indexOf(elem) === pos; + }).join(' ') + ); + + return this; + } + + /** + * Removes one or a space separated list of classes from the current element. + * + * @memberof Chartist.Svg + * @param {String} names A white space separated list of class names + * @return {Chartist.Svg} The wrapper of the current element + */ + function removeClass(names) { + var removedClasses = names.trim().split(/\s+/); + + this._node.setAttribute('class', this.classes(this._node).filter(function(name) { + return removedClasses.indexOf(name) === -1; + }).join(' ')); + + return this; + } + + /** + * Removes all classes from the current element. + * + * @memberof Chartist.Svg + * @return {Chartist.Svg} The wrapper of the current element + */ + function removeAllClasses() { + this._node.setAttribute('class', ''); + + return this; + } + + /** + * Get element height with fallback to svg BoundingBox or parent container dimensions: + * See [bugzilla.mozilla.org](https://bugzilla.mozilla.org/show_bug.cgi?id=530985) + * + * @memberof Chartist.Svg + * @return {Number} The elements height in pixels + */ + function height() { + return this._node.clientHeight || Math.round(this._node.getBBox().height) || this._node.parentNode.clientHeight; + } + + /** + * Get element width with fallback to svg BoundingBox or parent container dimensions: + * See [bugzilla.mozilla.org](https://bugzilla.mozilla.org/show_bug.cgi?id=530985) + * + * @memberof Chartist.Core + * @return {Number} The elements width in pixels + */ + function width() { + return this._node.clientWidth || Math.round(this._node.getBBox().width) || this._node.parentNode.clientWidth; + } + + /** + * The animate function lets you animate the current element with SMIL animations. You can add animations for multiple attributes at the same time by using an animation definition object. This object should contain SMIL animation attributes. Please refer to http://www.w3.org/TR/SVG/animate.html for a detailed specification about the available animation attributes. Additionally an easing property can be passed in the animation definition object. This can be a string with a name of an easing function in `Chartist.Svg.Easing` or an array with four numbers specifying a cubic Bézier curve. + * **An animations object could look like this:** + * ```javascript + * element.animate({ + * opacity: { + * dur: 1000, + * from: 0, + * to: 1 + * }, + * x1: { + * dur: '1000ms', + * from: 100, + * to: 200, + * easing: 'easeOutQuart' + * }, + * y1: { + * dur: '2s', + * from: 0, + * to: 100 + * } + * }); + * ``` + * **Automatic unit conversion** + * For the `dur` and the `begin` animate attribute you can also omit a unit by passing a number. The number will automatically be converted to milli seconds. + * **Guided mode** + * The default behavior of SMIL animations with offset using the `begin` attribute is that the attribute will keep it's original value until the animation starts. Mostly this behavior is not desired as you'd like to have your element attributes already initialized with the animation `from` value even before the animation starts. Also if you don't specify `fill="freeze"` on an animate element or if you delete the animation after it's done (which is done in guided mode) the attribute will switch back to the initial value. This behavior is also not desired when performing simple one-time animations. For one-time animations you'd want to trigger animations immediately instead of relative to the document begin time. That's why in guided mode Chartist.Svg will also use the `begin` property to schedule a timeout and manually start the animation after the timeout. If you're using multiple SMIL definition objects for an attribute (in an array), guided mode will be disabled for this attribute, even if you explicitly enabled it. + * If guided mode is enabled the following behavior is added: + * - Before the animation starts (even when delayed with `begin`) the animated attribute will be set already to the `from` value of the animation + * - `begin` is explicitly set to `indefinite` so it can be started manually without relying on document begin time (creation) + * - The animate element will be forced to use `fill="freeze"` + * - The animation will be triggered with `beginElement()` in a timeout where `begin` of the definition object is interpreted in milli seconds. If no `begin` was specified the timeout is triggered immediately. + * - After the animation the element attribute value will be set to the `to` value of the animation + * - The animate element is deleted from the DOM + * + * @memberof Chartist.Svg + * @param {Object} animations An animations object where the property keys are the attributes you'd like to animate. The properties should be objects again that contain the SMIL animation attributes (usually begin, dur, from, and to). The property begin and dur is auto converted (see Automatic unit conversion). You can also schedule multiple animations for the same attribute by passing an Array of SMIL definition objects. Attributes that contain an array of SMIL definition objects will not be executed in guided mode. + * @param {Boolean} guided Specify if guided mode should be activated for this animation (see Guided mode). If not otherwise specified, guided mode will be activated. + * @param {Object} eventEmitter If specified, this event emitter will be notified when an animation starts or ends. + * @return {Chartist.Svg} The current element where the animation was added + */ + function animate(animations, guided, eventEmitter) { + if(guided === undefined) { + guided = true; + } + + Object.keys(animations).forEach(function createAnimateForAttributes(attribute) { + + function createAnimate(animationDefinition, guided) { + var attributeProperties = {}, + animate, + timeout, + easing; + + // Check if an easing is specified in the definition object and delete it from the object as it will not + // be part of the animate element attributes. + if(animationDefinition.easing) { + // If already an easing Bézier curve array we take it or we lookup a easing array in the Easing object + easing = animationDefinition.easing instanceof Array ? + animationDefinition.easing : + Chartist.Svg.Easing[animationDefinition.easing]; + delete animationDefinition.easing; + } + + // If numeric dur or begin was provided we assume milli seconds + animationDefinition.begin = Chartist.ensureUnit(animationDefinition.begin, 'ms'); + animationDefinition.dur = Chartist.ensureUnit(animationDefinition.dur, 'ms'); + + if(easing) { + animationDefinition.calcMode = 'spline'; + animationDefinition.keySplines = easing.join(' '); + animationDefinition.keyTimes = '0;1'; + } + + // Adding "fill: freeze" if we are in guided mode and set initial attribute values + if(guided) { + animationDefinition.fill = 'freeze'; + // Animated property on our element should already be set to the animation from value in guided mode + attributeProperties[attribute] = animationDefinition.from; + this.attr(attributeProperties); + + // In guided mode we also set begin to indefinite so we can trigger the start manually and put the begin + // which needs to be in ms aside + timeout = Chartist.stripUnit(animationDefinition.begin || 0); + animationDefinition.begin = 'indefinite'; + } + + animate = this.elem('animate', Chartist.extend({ + attributeName: attribute + }, animationDefinition)); + + if(guided) { + // If guided we take the value that was put aside in timeout and trigger the animation manually with a timeout + setTimeout(function() { + // If beginElement fails we set the animated attribute to the end position and remove the animate element + // This happens if the SMIL ElementTimeControl interface is not supported or any other problems occured in + // the browser. (Currently FF 34 does not support animate elements in foreignObjects) + try { + animate._node.beginElement(); + } catch(err) { + // Set animated attribute to current animated value + attributeProperties[attribute] = animationDefinition.to; + this.attr(attributeProperties); + // Remove the animate element as it's no longer required + animate.remove(); + } + }.bind(this), timeout); + } + + if(eventEmitter) { + animate._node.addEventListener('beginEvent', function handleBeginEvent() { + eventEmitter.emit('animationBegin', { + element: this, + animate: animate._node, + params: animationDefinition + }); + }.bind(this)); + } + + animate._node.addEventListener('endEvent', function handleEndEvent() { + if(eventEmitter) { + eventEmitter.emit('animationEnd', { + element: this, + animate: animate._node, + params: animationDefinition + }); + } + + if(guided) { + // Set animated attribute to current animated value + attributeProperties[attribute] = animationDefinition.to; + this.attr(attributeProperties); + // Remove the animate element as it's no longer required + animate.remove(); + } + }.bind(this)); + } + + // If current attribute is an array of definition objects we create an animate for each and disable guided mode + if(animations[attribute] instanceof Array) { + animations[attribute].forEach(function(animationDefinition) { + createAnimate.bind(this)(animationDefinition, false); + }.bind(this)); + } else { + createAnimate.bind(this)(animations[attribute], guided); + } + + }.bind(this)); + + return this; + } + + Chartist.Svg = Chartist.Class.extend({ + constructor: Svg, + attr: attr, + elem: elem, + parent: parent, + root: root, + querySelector: querySelector, + querySelectorAll: querySelectorAll, + foreignObject: foreignObject, + text: text, + empty: empty, + remove: remove, + replace: replace, + append: append, + classes: classes, + addClass: addClass, + removeClass: removeClass, + removeAllClasses: removeAllClasses, + height: height, + width: width, + animate: animate + }); + + /** + * This method checks for support of a given SVG feature like Extensibility, SVG-animation or the like. Check http://www.w3.org/TR/SVG11/feature for a detailed list. + * + * @memberof Chartist.Svg + * @param {String} feature The SVG 1.1 feature that should be checked for support. + * @return {Boolean} True of false if the feature is supported or not + */ + Chartist.Svg.isSupported = function(feature) { + return document.implementation.hasFeature('www.http://w3.org/TR/SVG11/feature#' + feature, '1.1'); + }; + + /** + * This Object contains some standard easing cubic bezier curves. Then can be used with their name in the `Chartist.Svg.animate`. You can also extend the list and use your own name in the `animate` function. Click the show code button to see the available bezier functions. + * + * @memberof Chartist.Svg + */ + var easingCubicBeziers = { + easeInSine: [0.47, 0, 0.745, 0.715], + easeOutSine: [0.39, 0.575, 0.565, 1], + easeInOutSine: [0.445, 0.05, 0.55, 0.95], + easeInQuad: [0.55, 0.085, 0.68, 0.53], + easeOutQuad: [0.25, 0.46, 0.45, 0.94], + easeInOutQuad: [0.455, 0.03, 0.515, 0.955], + easeInCubic: [0.55, 0.055, 0.675, 0.19], + easeOutCubic: [0.215, 0.61, 0.355, 1], + easeInOutCubic: [0.645, 0.045, 0.355, 1], + easeInQuart: [0.895, 0.03, 0.685, 0.22], + easeOutQuart: [0.165, 0.84, 0.44, 1], + easeInOutQuart: [0.77, 0, 0.175, 1], + easeInQuint: [0.755, 0.05, 0.855, 0.06], + easeOutQuint: [0.23, 1, 0.32, 1], + easeInOutQuint: [0.86, 0, 0.07, 1], + easeInExpo: [0.95, 0.05, 0.795, 0.035], + easeOutExpo: [0.19, 1, 0.22, 1], + easeInOutExpo: [1, 0, 0, 1], + easeInCirc: [0.6, 0.04, 0.98, 0.335], + easeOutCirc: [0.075, 0.82, 0.165, 1], + easeInOutCirc: [0.785, 0.135, 0.15, 0.86], + easeInBack: [0.6, -0.28, 0.735, 0.045], + easeOutBack: [0.175, 0.885, 0.32, 1.275], + easeInOutBack: [0.68, -0.55, 0.265, 1.55] + }; + + Chartist.Svg.Easing = easingCubicBeziers; + + /** + * This helper class is to wrap multiple `Chartist.Svg` elements into a list where you can call the `Chartist.Svg` functions on all elements in the list with one call. This is helpful when you'd like to perform calls with `Chartist.Svg` on multiple elements. + * An instance of this class is also returned by `Chartist.Svg.querySelectorAll`. + * + * @memberof Chartist.Svg + * @param {Array|NodeList} nodeList An Array of SVG DOM nodes or a SVG DOM NodeList (as returned by document.querySelectorAll) + * @constructor + */ + function SvgList(nodeList) { + var list = this; + + this.svgElements = []; + for(var i = 0; i < nodeList.length; i++) { + this.svgElements.push(new Chartist.Svg(nodeList[i])); + } + + // Add delegation methods for Chartist.Svg + Object.keys(Chartist.Svg.prototype).filter(function(prototypeProperty) { + return ['constructor', + 'parent', + 'querySelector', + 'querySelectorAll', + 'replace', + 'append', + 'classes', + 'height', + 'width'].indexOf(prototypeProperty) === -1; + }).forEach(function(prototypeProperty) { + list[prototypeProperty] = function() { + var args = Array.prototype.slice.call(arguments, 0); + list.svgElements.forEach(function(element) { + Chartist.Svg.prototype[prototypeProperty].apply(element, args); + }); + return list; + }; + }); + } + + Chartist.Svg.List = Chartist.Class.extend({ + constructor: SvgList + }); + }(window, document, Chartist)); + ;/** + * Chartist SVG path module for SVG path description creation and modification. + * + * @module Chartist.Svg.Path + */ + /* global Chartist */ + (function(window, document, Chartist) { + 'use strict'; + + /** + * Contains the descriptors of supported element types in a SVG path. Currently only move, line and curve are supported. + * + * @memberof Chartist.Svg.Path + * @type {Object} + */ + var elementDescriptions = { + m: ['x', 'y'], + l: ['x', 'y'], + c: ['x1', 'y1', 'x2', 'y2', 'x', 'y'] + }; + + /** + * Default options for newly created SVG path objects. + * + * @memberof Chartist.Svg.Path + * @type {Object} + */ + var defaultOptions = { + // The accuracy in digit count after the decimal point. This will be used to round numbers in the SVG path. If this option is set to false then no rounding will be performed. + accuracy: 3 + }; + + function element(command, params, pathElements, pos, relative) { + pathElements.splice(pos, 0, Chartist.extend({ + command: relative ? command.toLowerCase() : command.toUpperCase() + }, params)); + } + + function forEachParam(pathElements, cb) { + pathElements.forEach(function(pathElement, pathElementIndex) { + elementDescriptions[pathElement.command.toLowerCase()].forEach(function(paramName, paramIndex) { + cb(pathElement, paramName, pathElementIndex, paramIndex, pathElements); + }); + }); + } + + /** + * Used to construct a new path object. + * + * @memberof Chartist.Svg.Path + * @param {Boolean} close If set to true then this path will be closed when stringified (with a Z at the end) + * @param {Object} options Options object that overrides the default objects. See default options for more details. + * @constructor + */ + function SvgPath(close, options) { + this.pathElements = []; + this.pos = 0; + this.close = close; + this.options = Chartist.extend({}, defaultOptions, options); + } + + /** + * Gets or sets the current position (cursor) inside of the path. You can move around the cursor freely but limited to 0 or the count of existing elements. All modifications with element functions will insert new elements at the position of this cursor. + * + * @memberof Chartist.Svg.Path + * @param {Number} [position] If a number is passed then the cursor is set to this position in the path element array. + * @return {Chartist.Svg.Path|Number} If the position parameter was passed then the return value will be the path object for easy call chaining. If no position parameter was passed then the current position is returned. + */ + function position(pos) { + if(pos !== undefined) { + this.pos = Math.max(0, Math.min(this.pathElements.length, pos)); + return this; + } else { + return this.pos; + } + } + + /** + * Removes elements from the path starting at the current position. + * + * @memberof Chartist.Svg.Path + * @param {Number} count Number of path elements that should be removed from the current position. + * @return {Chartist.Svg.Path} The current path object for easy call chaining. + */ + function remove(count) { + this.pathElements.splice(this.pos, count); + return this; + } + + /** + * Use this function to add a new move SVG path element. + * + * @memberof Chartist.Svg.Path + * @param {Number} x The x coordinate for the move element. + * @param {Number} y The y coordinate for the move element. + * @param {Boolean} relative If set to true the move element will be created with relative coordinates (lowercase letter) + * @return {Chartist.Svg.Path} The current path object for easy call chaining. + */ + function move(x, y, relative) { + element('M', { + x: +x, + y: +y + }, this.pathElements, this.pos++, relative); + return this; + } + + /** + * Use this function to add a new line SVG path element. + * + * @memberof Chartist.Svg.Path + * @param {Number} x The x coordinate for the line element. + * @param {Number} y The y coordinate for the line element. + * @param {Boolean} relative If set to true the line element will be created with relative coordinates (lowercase letter) + * @return {Chartist.Svg.Path} The current path object for easy call chaining. + */ + function line(x, y, relative) { + element('L', { + x: +x, + y: +y + }, this.pathElements, this.pos++, relative); + return this; + } + + /** + * Use this function to add a new curve SVG path element. + * + * @memberof Chartist.Svg.Path + * @param {Number} x1 The x coordinate for the first control point of the bezier curve. + * @param {Number} y1 The y coordinate for the first control point of the bezier curve. + * @param {Number} x2 The x coordinate for the second control point of the bezier curve. + * @param {Number} y2 The y coordinate for the second control point of the bezier curve. + * @param {Number} x The x coordinate for the target point of the curve element. + * @param {Number} y The y coordinate for the target point of the curve element. + * @param {Boolean} relative If set to true the curve element will be created with relative coordinates (lowercase letter) + * @return {Chartist.Svg.Path} The current path object for easy call chaining. + */ + function curve(x1, y1, x2, y2, x, y, relative) { + element('C', { + x1: +x1, + y1: +y1, + x2: +x2, + y2: +y2, + x: +x, + y: +y + }, this.pathElements, this.pos++, relative); + return this; + } + + /** + * Parses an SVG path seen in the d attribute of path elements, and inserts the parsed elements into the existing path object at the current cursor position. Any closing path indicators (Z at the end of the path) will be ignored by the parser as this is provided by the close option in the options of the path object. + * + * @memberof Chartist.Svg.Path + * @param {String} path Any SVG path that contains move (m), line (l) or curve (c) components. + * @return {Chartist.Svg.Path} The current path object for easy call chaining. + */ + function parse(path) { + // Parsing the SVG path string into an array of arrays [['M', '10', '10'], ['L', '100', '100']] + var chunks = path.replace(/([A-Za-z])([0-9])/g, '$1 $2') + .replace(/([0-9])([A-Za-z])/g, '$1 $2') + .split(/[\s,]+/) + .reduce(function(result, element) { + if(element.match(/[A-Za-z]/)) { + result.push([]); + } + + result[result.length - 1].push(element); + return result; + }, []); + + // If this is a closed path we remove the Z at the end because this is determined by the close option + if(chunks[chunks.length - 1][0].toUpperCase() === 'Z') { + chunks.pop(); + } + + // Using svgPathElementDescriptions to map raw path arrays into objects that contain the command and the parameters + // For example {command: 'M', x: '10', y: '10'} + var elements = chunks.map(function(chunk) { + var command = chunk.shift(), + description = elementDescriptions[command.toLowerCase()]; + + return Chartist.extend({ + command: command + }, description.reduce(function(result, paramName, index) { + result[paramName] = +chunk[index]; + return result; + }, {})); + }); + + // Preparing a splice call with the elements array as var arg params and insert the parsed elements at the current position + var spliceArgs = [this.pos, 0]; + Array.prototype.push.apply(spliceArgs, elements); + Array.prototype.splice.apply(this.pathElements, spliceArgs); + // Increase the internal position by the element count + this.pos += elements.length; + + return this; + } + + /** + * This function renders to current SVG path object into a final SVG string that can be used in the d attribute of SVG path elements. It uses the accuracy option to round big decimals. If the close parameter was set in the constructor of this path object then a path closing Z will be appended to the output string. + * + * @memberof Chartist.Svg.Path + * @return {String} + */ + function stringify() { + var accuracyMultiplier = Math.pow(10, this.options.accuracy); + + return this.pathElements.reduce(function(path, pathElement) { + var params = elementDescriptions[pathElement.command.toLowerCase()].map(function(paramName) { + return this.options.accuracy ? + (Math.round(pathElement[paramName] * accuracyMultiplier) / accuracyMultiplier) : + pathElement[paramName]; + }.bind(this)); + + return path + pathElement.command + params.join(','); + }.bind(this), '') + (this.close ? 'Z' : ''); + } + + /** + * Scales all elements in the current SVG path object. There is an individual parameter for each coordinate. Scaling will also be done for control points of curves, affecting the given coordinate. + * + * @memberof Chartist.Svg.Path + * @param {Number} x The number which will be used to scale the x, x1 and x2 of all path elements. + * @param {Number} y The number which will be used to scale the y, y1 and y2 of all path elements. + * @return {Chartist.Svg.Path} The current path object for easy call chaining. + */ + function scale(x, y) { + forEachParam(this.pathElements, function(pathElement, paramName) { + pathElement[paramName] *= paramName[0] === 'x' ? x : y; + }); + return this; + } + + /** + * Translates all elements in the current SVG path object. The translation is relative and there is an individual parameter for each coordinate. Translation will also be done for control points of curves, affecting the given coordinate. + * + * @memberof Chartist.Svg.Path + * @param {Number} x The number which will be used to translate the x, x1 and x2 of all path elements. + * @param {Number} y The number which will be used to translate the y, y1 and y2 of all path elements. + * @return {Chartist.Svg.Path} The current path object for easy call chaining. + */ + function translate(x, y) { + forEachParam(this.pathElements, function(pathElement, paramName) { + pathElement[paramName] += paramName[0] === 'x' ? x : y; + }); + return this; + } + + /** + * This function will run over all existing path elements and then loop over their attributes. The callback function will be called for every path element attribute that exists in the current path. + * The method signature of the callback function looks like this: + * ```javascript + * function(pathElement, paramName, pathElementIndex, paramIndex, pathElements) + * ``` + * If something else than undefined is returned by the callback function, this value will be used to replace the old value. This allows you to build custom transformations of path objects that can't be achieved using the basic transformation functions scale and translate. + * + * @memberof Chartist.Svg.Path + * @param {Function} transformFnc The callback function for the transformation. Check the signature in the function description. + * @return {Chartist.Svg.Path} The current path object for easy call chaining. + */ + function transform(transformFnc) { + forEachParam(this.pathElements, function(pathElement, paramName, pathElementIndex, paramIndex, pathElements) { + var transformed = transformFnc(pathElement, paramName, pathElementIndex, paramIndex, pathElements); + if(transformed || transformed === 0) { + pathElement[paramName] = transformed; + } + }); + return this; + } + + /** + * This function clones a whole path object with all its properties. This is a deep clone and path element objects will also be cloned. + * + * @memberof Chartist.Svg.Path + * @return {Chartist.Svg.Path} + */ + function clone() { + var c = new Chartist.Svg.Path(this.close); + c.pos = this.pos; + c.pathElements = this.pathElements.slice().map(function cloneElements(pathElement) { + return Chartist.extend({}, pathElement); + }); + c.options = Chartist.extend({}, this.options); + return c; + } + + Chartist.Svg.Path = Chartist.Class.extend({ + constructor: SvgPath, + position: position, + remove: remove, + move: move, + line: line, + curve: curve, + scale: scale, + translate: translate, + transform: transform, + parse: parse, + stringify: stringify, + clone: clone + }); + + Chartist.Svg.Path.elementDescriptions = elementDescriptions; + }(window, document, Chartist)); + ;/** + * Axis base class used to implement different axis types + * + * @module Chartist.Axis + */ + /* global Chartist */ + (function (window, document, Chartist) { + 'use strict'; + + var axisUnits = { + x: { + pos: 'x', + len: 'width', + dir: 'horizontal', + rectStart: 'x1', + rectEnd: 'x2', + rectOffset: 'y2' + }, + y: { + pos: 'y', + len: 'height', + dir: 'vertical', + rectStart: 'y2', + rectEnd: 'y1', + rectOffset: 'x1' + } + }; + + function Axis(units, chartRect, transform, labelOffset, options) { + this.units = units; + this.counterUnits = units === axisUnits.x ? axisUnits.y : axisUnits.x; + this.chartRect = chartRect; + this.axisLength = chartRect[units.rectEnd] - chartRect[units.rectStart]; + this.gridOffset = chartRect[units.rectOffset]; + this.transform = transform; + this.labelOffset = labelOffset; + this.options = options; + } + + Chartist.Axis = Chartist.Class.extend({ + constructor: Axis, + projectValue: function(value, index, data) { + throw new Error('Base axis can\'t be instantiated!'); + } + }); + + Chartist.Axis.units = axisUnits; + + }(window, document, Chartist)); + ;/** + * The linear scale axis uses standard linear scale projection of values along an axis. + * + * @module Chartist.LinearScaleAxis + */ + /* global Chartist */ + (function (window, document, Chartist) { + 'use strict'; + + function LinearScaleAxis(axisUnit, chartRect, transform, labelOffset, options) { + Chartist.LinearScaleAxis.super.constructor.call(this, + axisUnit, + chartRect, + transform, + labelOffset, + options); + + this.bounds = Chartist.getBounds(this.axisLength, options.highLow, options.scaleMinSpace, options.referenceValue); + } + + function projectValue(value) { + return { + pos: this.axisLength * (value - this.bounds.min) / (this.bounds.range + this.bounds.step), + len: Chartist.projectLength(this.axisLength, this.bounds.step, this.bounds) + }; + } + + Chartist.LinearScaleAxis = Chartist.Axis.extend({ + constructor: LinearScaleAxis, + projectValue: projectValue + }); + + }(window, document, Chartist)); + ;/** + * Step axis for step based charts like bar chart or step based line chart + * + * @module Chartist.StepAxis + */ + /* global Chartist */ + (function (window, document, Chartist) { + 'use strict'; + + function StepAxis(axisUnit, chartRect, transform, labelOffset, options) { + Chartist.StepAxis.super.constructor.call(this, + axisUnit, + chartRect, + transform, + labelOffset, + options); + + this.stepLength = this.axisLength / (options.stepCount - (options.stretch ? 1 : 0)); + } + + function projectValue(value, index) { + return { + pos: this.stepLength * index, + len: this.stepLength + }; + } + + Chartist.StepAxis = Chartist.Axis.extend({ + constructor: StepAxis, + projectValue: projectValue + }); + + }(window, document, Chartist)); + ;/** + * The Chartist line chart can be used to draw Line or Scatter charts. If used in the browser you can access the global `Chartist` namespace where you find the `Line` function as a main entry point. + * + * For examples on how to use the line chart please check the examples of the `Chartist.Line` method. + * + * @module Chartist.Line + */ + /* global Chartist */ + (function(window, document, Chartist){ + 'use strict'; + + /** + * Default options in line charts. Expand the code view to see a detailed list of options with comments. + * + * @memberof Chartist.Line + */ + var defaultOptions = { + // Options for X-Axis + axisX: { + // The offset of the labels to the chart area + offset: 30, + // Allows you to correct label positioning on this axis by positive or negative x and y offset. + labelOffset: { + x: 0, + y: 0 + }, + // If labels should be shown or not + showLabel: true, + // If the axis grid should be drawn or not + showGrid: true, + // Interpolation function that allows you to intercept the value from the axis label + labelInterpolationFnc: Chartist.noop + }, + // Options for Y-Axis + axisY: { + // The offset of the labels to the chart area + offset: 40, + // Allows you to correct label positioning on this axis by positive or negative x and y offset. + labelOffset: { + x: 0, + y: 0 + }, + // If labels should be shown or not + showLabel: true, + // If the axis grid should be drawn or not + showGrid: true, + // Interpolation function that allows you to intercept the value from the axis label + labelInterpolationFnc: Chartist.noop, + // This value specifies the minimum height in pixel of the scale steps + scaleMinSpace: 20 + }, + // Specify a fixed width for the chart as a string (i.e. '100px' or '50%') + width: undefined, + // Specify a fixed height for the chart as a string (i.e. '100px' or '50%') + height: undefined, + // If the line should be drawn or not + showLine: true, + // If dots should be drawn or not + showPoint: true, + // If the line chart should draw an area + showArea: false, + // The base for the area chart that will be used to close the area shape (is normally 0) + areaBase: 0, + // Specify if the lines should be smoothed. This value can be true or false where true will result in smoothing using the default smoothing interpolation function Chartist.Interpolation.cardinal and false results in Chartist.Interpolation.none. You can also choose other smoothing / interpolation functions available in the Chartist.Interpolation module, or write your own interpolation function. Check the examples for a brief description. + lineSmooth: true, + // Overriding the natural low of the chart allows you to zoom in or limit the charts lowest displayed value + low: undefined, + // Overriding the natural high of the chart allows you to zoom in or limit the charts highest displayed value + high: undefined, + // Padding of the chart drawing area to the container element and labels + chartPadding: 5, + // When set to true, the last grid line on the x-axis is not drawn and the chart elements will expand to the full available width of the chart. For the last label to be drawn correctly you might need to add chart padding or offset the last label with a draw event handler. + fullWidth: false, + // If true the whole data is reversed including labels, the series order as well as the whole series data arrays. + reverseData: false, + // Override the class names that get used to generate the SVG structure of the chart + classNames: { + chart: 'ct-chart-line', + label: 'ct-label', + labelGroup: 'ct-labels', + series: 'ct-series', + line: 'ct-line', + point: 'ct-point', + area: 'ct-area', + grid: 'ct-grid', + gridGroup: 'ct-grids', + vertical: 'ct-vertical', + horizontal: 'ct-horizontal' + } + }; + + /** + * Creates a new chart + * + */ + function createChart(options) { + var seriesGroups = [], + normalizedData = Chartist.normalizeDataArray(Chartist.getDataArray(this.data, options.reverseData), this.data.labels.length); + + // Create new svg object + this.svg = Chartist.createSvg(this.container, options.width, options.height, options.classNames.chart); + + var chartRect = Chartist.createChartRect(this.svg, options); + + var highLow = Chartist.getHighLow(normalizedData); + // Overrides of high / low from settings + highLow.high = +options.high || (options.high === 0 ? 0 : highLow.high); + highLow.low = +options.low || (options.low === 0 ? 0 : highLow.low); + + var axisX = new Chartist.StepAxis( + Chartist.Axis.units.x, + chartRect, + function xAxisTransform(projectedValue) { + projectedValue.pos = chartRect.x1 + projectedValue.pos; + return projectedValue; + }, + { + x: options.axisX.labelOffset.x, + y: chartRect.y1 + options.axisX.labelOffset.y + (this.supportsForeignObject ? 5 : 20) + }, + { + stepCount: this.data.labels.length, + stretch: options.fullWidth + } + ); + + var axisY = new Chartist.LinearScaleAxis( + Chartist.Axis.units.y, + chartRect, + function yAxisTransform(projectedValue) { + projectedValue.pos = chartRect.y1 - projectedValue.pos; + return projectedValue; + }, + { + x: options.chartPadding + options.axisY.labelOffset.x + (this.supportsForeignObject ? -10 : 0), + y: options.axisY.labelOffset.y + (this.supportsForeignObject ? -15 : 0) + }, + { + highLow: highLow, + scaleMinSpace: options.axisY.scaleMinSpace + } + ); + + // Start drawing + var labelGroup = this.svg.elem('g').addClass(options.classNames.labelGroup), + gridGroup = this.svg.elem('g').addClass(options.classNames.gridGroup); + + Chartist.createAxis( + axisX, + this.data.labels, + chartRect, + gridGroup, + labelGroup, + this.supportsForeignObject, + options, + this.eventEmitter + ); + + Chartist.createAxis( + axisY, + axisY.bounds.values, + chartRect, + gridGroup, + labelGroup, + this.supportsForeignObject, + options, + this.eventEmitter + ); + + // Draw the series + this.data.series.forEach(function(series, seriesIndex) { + seriesGroups[seriesIndex] = this.svg.elem('g'); + + // Write attributes to series group element. If series name or meta is undefined the attributes will not be written + seriesGroups[seriesIndex].attr({ + 'series-name': series.name, + 'meta': Chartist.serialize(series.meta) + }, Chartist.xmlNs.uri); + + // Use series class from series data or if not set generate one + seriesGroups[seriesIndex].addClass([ + options.classNames.series, + (series.className || options.classNames.series + '-' + Chartist.alphaNumerate(seriesIndex)) + ].join(' ')); + + var pathCoordinates = []; + + normalizedData[seriesIndex].forEach(function(value, valueIndex) { + var p = { + x: chartRect.x1 + axisX.projectValue(value, valueIndex, normalizedData[seriesIndex]).pos, + y: chartRect.y1 - axisY.projectValue(value, valueIndex, normalizedData[seriesIndex]).pos + }; + pathCoordinates.push(p.x, p.y); + + //If we should show points we need to create them now to avoid secondary loop + // Small offset for Firefox to render squares correctly + if (options.showPoint) { + var point = seriesGroups[seriesIndex].elem('line', { + x1: p.x, + y1: p.y, + x2: p.x + 0.01, + y2: p.y + }, options.classNames.point).attr({ + 'value': value, + 'meta': Chartist.getMetaData(series, valueIndex) + }, Chartist.xmlNs.uri); + + this.eventEmitter.emit('draw', { + type: 'point', + value: value, + index: valueIndex, + group: seriesGroups[seriesIndex], + element: point, + x: p.x, + y: p.y + }); + } + }.bind(this)); + + // TODO: Nicer handling of conditions, maybe composition? + if (options.showLine || options.showArea) { + var smoothing = typeof options.lineSmooth === 'function' ? + options.lineSmooth : (options.lineSmooth ? Chartist.Interpolation.cardinal() : Chartist.Interpolation.none()), + path = smoothing(pathCoordinates); + + if(options.showLine) { + var line = seriesGroups[seriesIndex].elem('path', { + d: path.stringify() + }, options.classNames.line, true).attr({ + 'values': normalizedData[seriesIndex] + }, Chartist.xmlNs.uri); + + this.eventEmitter.emit('draw', { + type: 'line', + values: normalizedData[seriesIndex], + path: path.clone(), + chartRect: chartRect, + index: seriesIndex, + group: seriesGroups[seriesIndex], + element: line + }); + } + + if(options.showArea) { + // If areaBase is outside the chart area (< low or > high) we need to set it respectively so that + // the area is not drawn outside the chart area. + var areaBase = Math.max(Math.min(options.areaBase, axisY.bounds.max), axisY.bounds.min); + + // We project the areaBase value into screen coordinates + var areaBaseProjected = chartRect.y1 - axisY.projectValue(areaBase).pos; + + // Clone original path and splice our new area path to add the missing path elements to close the area shape + var areaPath = path.clone(); + // Modify line path and add missing elements for area + areaPath.position(0) + .remove(1) + .move(chartRect.x1, areaBaseProjected) + .line(pathCoordinates[0], pathCoordinates[1]) + .position(areaPath.pathElements.length) + .line(pathCoordinates[pathCoordinates.length - 2], areaBaseProjected); + + // Create the new path for the area shape with the area class from the options + var area = seriesGroups[seriesIndex].elem('path', { + d: areaPath.stringify() + }, options.classNames.area, true).attr({ + 'values': normalizedData[seriesIndex] + }, Chartist.xmlNs.uri); + + this.eventEmitter.emit('draw', { + type: 'area', + values: normalizedData[seriesIndex], + path: areaPath.clone(), + chartRect: chartRect, + index: seriesIndex, + group: seriesGroups[seriesIndex], + element: area + }); + } + } + }.bind(this)); + + this.eventEmitter.emit('created', { + bounds: axisY.bounds, + chartRect: chartRect, + svg: this.svg, + options: options + }); + } + + /** + * This method creates a new line chart. + * + * @memberof Chartist.Line + * @param {String|Node} query A selector query string or directly a DOM element + * @param {Object} data The data object that needs to consist of a labels and a series array + * @param {Object} [options] The options object with options that override the default options. Check the examples for a detailed list. + * @param {Array} [responsiveOptions] Specify an array of responsive option arrays which are a media query and options object pair => [[mediaQueryString, optionsObject],[more...]] + * @return {Object} An object which exposes the API for the created chart + * + * @example + * // Create a simple line chart + * var data = { + * // A labels array that can contain any sort of values + * labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'], + * // Our series array that contains series objects or in this case series data arrays + * series: [ + * [5, 2, 4, 2, 0] + * ] + * }; + * + * // As options we currently only set a static size of 300x200 px + * var options = { + * width: '300px', + * height: '200px' + * }; + * + * // In the global name space Chartist we call the Line function to initialize a line chart. As a first parameter we pass in a selector where we would like to get our chart created. Second parameter is the actual data object and as a third parameter we pass in our options + * new Chartist.Line('.ct-chart', data, options); + * + * @example + * // Use specific interpolation function with configuration from the Chartist.Interpolation module + * + * var chart = new Chartist.Line('.ct-chart', { + * labels: [1, 2, 3, 4, 5], + * series: [ + * [1, 1, 8, 1, 7] + * ] + * }, { + * lineSmooth: Chartist.Interpolation.cardinal({ + * tension: 0.2 + * }) + * }); + * + * @example + * // Create a line chart with responsive options + * + * var data = { + * // A labels array that can contain any sort of values + * labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'], + * // Our series array that contains series objects or in this case series data arrays + * series: [ + * [5, 2, 4, 2, 0] + * ] + * }; + * + * // In adition to the regular options we specify responsive option overrides that will override the default configutation based on the matching media queries. + * var responsiveOptions = [ + * ['screen and (min-width: 641px) and (max-width: 1024px)', { + * showPoint: false, + * axisX: { + * labelInterpolationFnc: function(value) { + * // Will return Mon, Tue, Wed etc. on medium screens + * return value.slice(0, 3); + * } + * } + * }], + * ['screen and (max-width: 640px)', { + * showLine: false, + * axisX: { + * labelInterpolationFnc: function(value) { + * // Will return M, T, W etc. on small screens + * return value[0]; + * } + * } + * }] + * ]; + * + * new Chartist.Line('.ct-chart', data, null, responsiveOptions); + * + */ + function Line(query, data, options, responsiveOptions) { + Chartist.Line.super.constructor.call(this, + query, + data, + Chartist.extend({}, defaultOptions, options), + responsiveOptions); + } + + // Creating line chart type in Chartist namespace + Chartist.Line = Chartist.Base.extend({ + constructor: Line, + createChart: createChart + }); + + }(window, document, Chartist)); + ;/** + * The bar chart module of Chartist that can be used to draw unipolar or bipolar bar and grouped bar charts. + * + * @module Chartist.Bar + */ + /* global Chartist */ + (function(window, document, Chartist){ + 'use strict'; + + /** + * Default options in bar charts. Expand the code view to see a detailed list of options with comments. + * + * @memberof Chartist.Bar + */ + var defaultOptions = { + // Options for X-Axis + axisX: { + // The offset of the chart drawing area to the border of the container + offset: 30, + // Allows you to correct label positioning on this axis by positive or negative x and y offset. + labelOffset: { + x: 0, + y: 0 + }, + // If labels should be shown or not + showLabel: true, + // If the axis grid should be drawn or not + showGrid: true, + // Interpolation function that allows you to intercept the value from the axis label + labelInterpolationFnc: Chartist.noop, + // This value specifies the minimum width in pixel of the scale steps + scaleMinSpace: 40 + }, + // Options for Y-Axis + axisY: { + // The offset of the chart drawing area to the border of the container + offset: 40, + // Allows you to correct label positioning on this axis by positive or negative x and y offset. + labelOffset: { + x: 0, + y: 0 + }, + // If labels should be shown or not + showLabel: true, + // If the axis grid should be drawn or not + showGrid: true, + // Interpolation function that allows you to intercept the value from the axis label + labelInterpolationFnc: Chartist.noop, + // This value specifies the minimum height in pixel of the scale steps + scaleMinSpace: 20 + }, + // Specify a fixed width for the chart as a string (i.e. '100px' or '50%') + width: undefined, + // Specify a fixed height for the chart as a string (i.e. '100px' or '50%') + height: undefined, + // Overriding the natural high of the chart allows you to zoom in or limit the charts highest displayed value + high: undefined, + // Overriding the natural low of the chart allows you to zoom in or limit the charts lowest displayed value + low: undefined, + // Padding of the chart drawing area to the container element and labels + chartPadding: 5, + // Specify the distance in pixel of bars in a group + seriesBarDistance: 15, + // If set to true this property will cause the series bars to be stacked and form a total for each series point. This will also influence the y-axis and the overall bounds of the chart. In stacked mode the seriesBarDistance property will have no effect. + stackBars: false, + // Inverts the axes of the bar chart in order to draw a horizontal bar chart. Be aware that you also need to invert your axis settings as the Y Axis will now display the labels and the X Axis the values. + horizontalBars: false, + // If true the whole data is reversed including labels, the series order as well as the whole series data arrays. + reverseData: false, + // Override the class names that get used to generate the SVG structure of the chart + classNames: { + chart: 'ct-chart-bar', + label: 'ct-label', + labelGroup: 'ct-labels', + series: 'ct-series', + bar: 'ct-bar', + grid: 'ct-grid', + gridGroup: 'ct-grids', + vertical: 'ct-vertical', + horizontal: 'ct-horizontal' + } + }; + + /** + * Creates a new chart + * + */ + function createChart(options) { + var seriesGroups = [], + normalizedData = Chartist.normalizeDataArray(Chartist.getDataArray(this.data, options.reverseData), this.data.labels.length), + highLow; + + // Create new svg element + this.svg = Chartist.createSvg(this.container, options.width, options.height, options.classNames.chart); + + if(options.stackBars) { + // If stacked bars we need to calculate the high low from stacked values from each series + var serialSums = Chartist.serialMap(normalizedData, function serialSums() { + return Array.prototype.slice.call(arguments).reduce(Chartist.sum, 0); + }); + + highLow = Chartist.getHighLow([serialSums]); + } else { + highLow = Chartist.getHighLow(normalizedData); + } + // Overrides of high / low from settings + highLow.high = +options.high || (options.high === 0 ? 0 : highLow.high); + highLow.low = +options.low || (options.low === 0 ? 0 : highLow.low); + + var chartRect = Chartist.createChartRect(this.svg, options); + + var valueAxis, + labelAxis; + + if(options.horizontalBars) { + labelAxis = new Chartist.StepAxis( + Chartist.Axis.units.y, + chartRect, + function timeAxisTransform(projectedValue) { + projectedValue.pos = chartRect.y1 - projectedValue.pos; + return projectedValue; + }, + { + x: options.chartPadding + options.axisY.labelOffset.x + (this.supportsForeignObject ? -10 : 0), + y: options.axisY.labelOffset.y - chartRect.height() / this.data.labels.length + }, + { + stepCount: this.data.labels.length, + stretch: options.fullHeight + } + ); + + valueAxis = new Chartist.LinearScaleAxis( + Chartist.Axis.units.x, + chartRect, + function valueAxisTransform(projectedValue) { + projectedValue.pos = chartRect.x1 + projectedValue.pos; + return projectedValue; + }, + { + x: options.axisX.labelOffset.x, + y: chartRect.y1 + options.axisX.labelOffset.y + (this.supportsForeignObject ? 5 : 20) + }, + { + highLow: highLow, + scaleMinSpace: options.axisX.scaleMinSpace, + referenceValue: 0 + } + ); + } else { + labelAxis = new Chartist.StepAxis( + Chartist.Axis.units.x, + chartRect, + function timeAxisTransform(projectedValue) { + projectedValue.pos = chartRect.x1 + projectedValue.pos; + return projectedValue; + }, + { + x: options.axisX.labelOffset.x, + y: chartRect.y1 + options.axisX.labelOffset.y + (this.supportsForeignObject ? 5 : 20) + }, + { + stepCount: this.data.labels.length + } + ); + + valueAxis = new Chartist.LinearScaleAxis( + Chartist.Axis.units.y, + chartRect, + function valueAxisTransform(projectedValue) { + projectedValue.pos = chartRect.y1 - projectedValue.pos; + return projectedValue; + }, + { + x: options.chartPadding + options.axisY.labelOffset.x + (this.supportsForeignObject ? -10 : 0), + y: options.axisY.labelOffset.y + (this.supportsForeignObject ? -15 : 0) + }, + { + highLow: highLow, + scaleMinSpace: options.axisY.scaleMinSpace, + referenceValue: 0 + } + ); + } + + // Start drawing + var labelGroup = this.svg.elem('g').addClass(options.classNames.labelGroup), + gridGroup = this.svg.elem('g').addClass(options.classNames.gridGroup), + // Projected 0 point + zeroPoint = options.horizontalBars ? (chartRect.x1 + valueAxis.projectValue(0).pos) : (chartRect.y1 - valueAxis.projectValue(0).pos), + // Used to track the screen coordinates of stacked bars + stackedBarValues = []; + + Chartist.createAxis( + labelAxis, + this.data.labels, + chartRect, + gridGroup, + labelGroup, + this.supportsForeignObject, + options, + this.eventEmitter + ); + + Chartist.createAxis( + valueAxis, + valueAxis.bounds.values, + chartRect, + gridGroup, + labelGroup, + this.supportsForeignObject, + options, + this.eventEmitter + ); + + // Draw the series + this.data.series.forEach(function(series, seriesIndex) { + // Calculating bi-polar value of index for seriesOffset. For i = 0..4 biPol will be -1.5, -0.5, 0.5, 1.5 etc. + var biPol = seriesIndex - (this.data.series.length - 1) / 2, + // Half of the period width between vertical grid lines used to position bars + periodHalfLength = chartRect[labelAxis.units.len]() / normalizedData[seriesIndex].length / 2; + + seriesGroups[seriesIndex] = this.svg.elem('g'); + + // Write attributes to series group element. If series name or meta is undefined the attributes will not be written + seriesGroups[seriesIndex].attr({ + 'series-name': series.name, + 'meta': Chartist.serialize(series.meta) + }, Chartist.xmlNs.uri); + + // Use series class from series data or if not set generate one + seriesGroups[seriesIndex].addClass([ + options.classNames.series, + (series.className || options.classNames.series + '-' + Chartist.alphaNumerate(seriesIndex)) + ].join(' ')); + + normalizedData[seriesIndex].forEach(function(value, valueIndex) { + var projected = { + x: chartRect.x1 + (options.horizontalBars ? valueAxis : labelAxis).projectValue(value, valueIndex, normalizedData[seriesIndex]).pos, + y: chartRect.y1 - (options.horizontalBars ? labelAxis : valueAxis).projectValue(value, valueIndex, normalizedData[seriesIndex]).pos + }, + bar, + previousStack; + + // Offset to center bar between grid lines + projected[labelAxis.units.pos] += periodHalfLength * (options.horizontalBars ? -1 : 1); + // Using bi-polar offset for multiple series if no stacked bars are used + projected[labelAxis.units.pos] += options.stackBars ? 0 : biPol * options.seriesBarDistance * (options.horizontalBars ? -1 : 1); + + // Enter value in stacked bar values used to remember previous screen value for stacking up bars + previousStack = stackedBarValues[valueIndex] || zeroPoint; + stackedBarValues[valueIndex] = previousStack - (zeroPoint - projected[labelAxis.counterUnits.pos]); + + var positions = {}; + positions[labelAxis.units.pos + '1'] = projected[labelAxis.units.pos]; + positions[labelAxis.units.pos + '2'] = projected[labelAxis.units.pos]; + // If bars are stacked we use the stackedBarValues reference and otherwise base all bars off the zero line + positions[labelAxis.counterUnits.pos + '1'] = options.stackBars ? previousStack : zeroPoint; + positions[labelAxis.counterUnits.pos + '2'] = options.stackBars ? stackedBarValues[valueIndex] : projected[labelAxis.counterUnits.pos]; + + bar = seriesGroups[seriesIndex].elem('line', positions, options.classNames.bar).attr({ + 'value': value, + 'meta': Chartist.getMetaData(series, valueIndex) + }, Chartist.xmlNs.uri); + + this.eventEmitter.emit('draw', Chartist.extend({ + type: 'bar', + value: value, + index: valueIndex, + chartRect: chartRect, + group: seriesGroups[seriesIndex], + element: bar + }, positions)); + }.bind(this)); + }.bind(this)); + + this.eventEmitter.emit('created', { + bounds: valueAxis.bounds, + chartRect: chartRect, + svg: this.svg, + options: options + }); + } + + /** + * This method creates a new bar chart and returns API object that you can use for later changes. + * + * @memberof Chartist.Bar + * @param {String|Node} query A selector query string or directly a DOM element + * @param {Object} data The data object that needs to consist of a labels and a series array + * @param {Object} [options] The options object with options that override the default options. Check the examples for a detailed list. + * @param {Array} [responsiveOptions] Specify an array of responsive option arrays which are a media query and options object pair => [[mediaQueryString, optionsObject],[more...]] + * @return {Object} An object which exposes the API for the created chart + * + * @example + * // Create a simple bar chart + * var data = { + * labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'], + * series: [ + * [5, 2, 4, 2, 0] + * ] + * }; + * + * // In the global name space Chartist we call the Bar function to initialize a bar chart. As a first parameter we pass in a selector where we would like to get our chart created and as a second parameter we pass our data object. + * new Chartist.Bar('.ct-chart', data); + * + * @example + * // This example creates a bipolar grouped bar chart where the boundaries are limitted to -10 and 10 + * new Chartist.Bar('.ct-chart', { + * labels: [1, 2, 3, 4, 5, 6, 7], + * series: [ + * [1, 3, 2, -5, -3, 1, -6], + * [-5, -2, -4, -1, 2, -3, 1] + * ] + * }, { + * seriesBarDistance: 12, + * low: -10, + * high: 10 + * }); + * + */ + function Bar(query, data, options, responsiveOptions) { + Chartist.Bar.super.constructor.call(this, + query, + data, + Chartist.extend({}, defaultOptions, options), + responsiveOptions); + } + + // Creating bar chart type in Chartist namespace + Chartist.Bar = Chartist.Base.extend({ + constructor: Bar, + createChart: createChart + }); + + }(window, document, Chartist)); + ;/** + * The pie chart module of Chartist that can be used to draw pie, donut or gauge charts + * + * @module Chartist.Pie + */ + /* global Chartist */ + (function(window, document, Chartist) { + 'use strict'; + + /** + * Default options in line charts. Expand the code view to see a detailed list of options with comments. + * + * @memberof Chartist.Pie + */ + var defaultOptions = { + // Specify a fixed width for the chart as a string (i.e. '100px' or '50%') + width: undefined, + // Specify a fixed height for the chart as a string (i.e. '100px' or '50%') + height: undefined, + // Padding of the chart drawing area to the container element and labels + chartPadding: 5, + // Override the class names that get used to generate the SVG structure of the chart + classNames: { + chart: 'ct-chart-pie', + series: 'ct-series', + slice: 'ct-slice', + donut: 'ct-donut', + label: 'ct-label' + }, + // The start angle of the pie chart in degrees where 0 points north. A higher value offsets the start angle clockwise. + startAngle: 0, + // An optional total you can specify. By specifying a total value, the sum of the values in the series must be this total in order to draw a full pie. You can use this parameter to draw only parts of a pie or gauge charts. + total: undefined, + // If specified the donut CSS classes will be used and strokes will be drawn instead of pie slices. + donut: false, + // Specify the donut stroke width, currently done in javascript for convenience. May move to CSS styles in the future. + donutWidth: 60, + // If a label should be shown or not + showLabel: true, + // Label position offset from the standard position which is half distance of the radius. This value can be either positive or negative. Positive values will position the label away from the center. + labelOffset: 0, + // An interpolation function for the label value + labelInterpolationFnc: Chartist.noop, + // Label direction can be 'neutral', 'explode' or 'implode'. The labels anchor will be positioned based on those settings as well as the fact if the labels are on the right or left side of the center of the chart. Usually explode is useful when labels are positioned far away from the center. + labelDirection: 'neutral', + // If true the whole data is reversed including labels, the series order as well as the whole series data arrays. + reverseData: false + }; + + /** + * Determines SVG anchor position based on direction and center parameter + * + * @param center + * @param label + * @param direction + * @return {string} + */ + function determineAnchorPosition(center, label, direction) { + var toTheRight = label.x > center.x; + + if(toTheRight && direction === 'explode' || + !toTheRight && direction === 'implode') { + return 'start'; + } else if(toTheRight && direction === 'implode' || + !toTheRight && direction === 'explode') { + return 'end'; + } else { + return 'middle'; + } + } + + /** + * Creates the pie chart + * + * @param options + */ + function createChart(options) { + var seriesGroups = [], + chartRect, + radius, + labelRadius, + totalDataSum, + startAngle = options.startAngle, + dataArray = Chartist.getDataArray(this.data, options.reverseData); + + // Create SVG.js draw + this.svg = Chartist.createSvg(this.container, options.width, options.height, options.classNames.chart); + // Calculate charting rect + chartRect = Chartist.createChartRect(this.svg, options, 0, 0); + // Get biggest circle radius possible within chartRect + radius = Math.min(chartRect.width() / 2, chartRect.height() / 2); + // Calculate total of all series to get reference value or use total reference from optional options + totalDataSum = options.total || dataArray.reduce(function(previousValue, currentValue) { + return previousValue + currentValue; + }, 0); + + // If this is a donut chart we need to adjust our radius to enable strokes to be drawn inside + // Unfortunately this is not possible with the current SVG Spec + // See this proposal for more details: http://lists.w3.org/Archives/Public/www-svg/2003Oct/0000.html + radius -= options.donut ? options.donutWidth / 2 : 0; + + // If a donut chart then the label position is at the radius, if regular pie chart it's half of the radius + // see https://github.com/gionkunz/chartist-js/issues/21 + labelRadius = options.donut ? radius : radius / 2; + // Add the offset to the labelRadius where a negative offset means closed to the center of the chart + labelRadius += options.labelOffset; + + // Calculate end angle based on total sum and current data value and offset with padding + var center = { + x: chartRect.x1 + chartRect.width() / 2, + y: chartRect.y2 + chartRect.height() / 2 + }; + + // Check if there is only one non-zero value in the series array. + var hasSingleValInSeries = this.data.series.filter(function(val) { + return val !== 0; + }).length === 1; + + // Draw the series + // initialize series groups + for (var i = 0; i < this.data.series.length; i++) { + seriesGroups[i] = this.svg.elem('g', null, null, true); + + // If the series is an object and contains a name we add a custom attribute + if(this.data.series[i].name) { + seriesGroups[i].attr({ + 'series-name': this.data.series[i].name, + 'meta': Chartist.serialize(this.data.series[i].meta) + }, Chartist.xmlNs.uri); + } + + // Use series class from series data or if not set generate one + seriesGroups[i].addClass([ + options.classNames.series, + (this.data.series[i].className || options.classNames.series + '-' + Chartist.alphaNumerate(i)) + ].join(' ')); + + var endAngle = startAngle + dataArray[i] / totalDataSum * 360; + // If we need to draw the arc for all 360 degrees we need to add a hack where we close the circle + // with Z and use 359.99 degrees + if(endAngle - startAngle === 360) { + endAngle -= 0.01; + } + + var start = Chartist.polarToCartesian(center.x, center.y, radius, startAngle - (i === 0 || hasSingleValInSeries ? 0 : 0.2)), + end = Chartist.polarToCartesian(center.x, center.y, radius, endAngle), + arcSweep = endAngle - startAngle <= 180 ? '0' : '1', + d = [ + // Start at the end point from the cartesian coordinates + 'M', end.x, end.y, + // Draw arc + 'A', radius, radius, 0, arcSweep, 0, start.x, start.y + ]; + + // If regular pie chart (no donut) we add a line to the center of the circle for completing the pie + if(options.donut === false) { + d.push('L', center.x, center.y); + } + + // Create the SVG path + // If this is a donut chart we add the donut class, otherwise just a regular slice + var path = seriesGroups[i].elem('path', { + d: d.join(' ') + }, options.classNames.slice + (options.donut ? ' ' + options.classNames.donut : '')); + + // Adding the pie series value to the path + path.attr({ + 'value': dataArray[i] + }, Chartist.xmlNs.uri); + + // If this is a donut, we add the stroke-width as style attribute + if(options.donut === true) { + path.attr({ + 'style': 'stroke-width: ' + (+options.donutWidth) + 'px' + }); + } + + // Fire off draw event + this.eventEmitter.emit('draw', { + type: 'slice', + value: dataArray[i], + totalDataSum: totalDataSum, + index: i, + group: seriesGroups[i], + element: path, + center: center, + radius: radius, + startAngle: startAngle, + endAngle: endAngle + }); + + // If we need to show labels we need to add the label for this slice now + if(options.showLabel) { + // Position at the labelRadius distance from center and between start and end angle + var labelPosition = Chartist.polarToCartesian(center.x, center.y, labelRadius, startAngle + (endAngle - startAngle) / 2), + interpolatedValue = options.labelInterpolationFnc(this.data.labels ? this.data.labels[i] : dataArray[i], i); + + var labelElement = seriesGroups[i].elem('text', { + dx: labelPosition.x, + dy: labelPosition.y, + 'text-anchor': determineAnchorPosition(center, labelPosition, options.labelDirection) + }, options.classNames.label).text('' + interpolatedValue); + + // Fire off draw event + this.eventEmitter.emit('draw', { + type: 'label', + index: i, + group: seriesGroups[i], + element: labelElement, + text: '' + interpolatedValue, + x: labelPosition.x, + y: labelPosition.y + }); + } + + // Set next startAngle to current endAngle. Use slight offset so there are no transparent hairline issues + // (except for last slice) + startAngle = endAngle; + } + + this.eventEmitter.emit('created', { + chartRect: chartRect, + svg: this.svg, + options: options + }); + } + + /** + * This method creates a new pie chart and returns an object that can be used to redraw the chart. + * + * @memberof Chartist.Pie + * @param {String|Node} query A selector query string or directly a DOM element + * @param {Object} data The data object in the pie chart needs to have a series property with a one dimensional data array. The values will be normalized against each other and don't necessarily need to be in percentage. The series property can also be an array of objects that contain a data property with the value and a className property to override the CSS class name for the series group. + * @param {Object} [options] The options object with options that override the default options. Check the examples for a detailed list. + * @param {Array} [responsiveOptions] Specify an array of responsive option arrays which are a media query and options object pair => [[mediaQueryString, optionsObject],[more...]] + * @return {Object} An object with a version and an update method to manually redraw the chart + * + * @example + * // Simple pie chart example with four series + * new Chartist.Pie('.ct-chart', { + * series: [10, 2, 4, 3] + * }); + * + * @example + * // Drawing a donut chart + * new Chartist.Pie('.ct-chart', { + * series: [10, 2, 4, 3] + * }, { + * donut: true + * }); + * + * @example + * // Using donut, startAngle and total to draw a gauge chart + * new Chartist.Pie('.ct-chart', { + * series: [20, 10, 30, 40] + * }, { + * donut: true, + * donutWidth: 20, + * startAngle: 270, + * total: 200 + * }); + * + * @example + * // Drawing a pie chart with padding and labels that are outside the pie + * new Chartist.Pie('.ct-chart', { + * series: [20, 10, 30, 40] + * }, { + * chartPadding: 30, + * labelOffset: 50, + * labelDirection: 'explode' + * }); + * + * @example + * // Overriding the class names for individual series + * new Chartist.Pie('.ct-chart', { + * series: [{ + * data: 20, + * className: 'my-custom-class-one' + * }, { + * data: 10, + * className: 'my-custom-class-two' + * }, { + * data: 70, + * className: 'my-custom-class-three' + * }] + * }); + */ + function Pie(query, data, options, responsiveOptions) { + Chartist.Pie.super.constructor.call(this, + query, + data, + Chartist.extend({}, defaultOptions, options), + responsiveOptions); + } + + // Creating pie chart type in Chartist namespace + Chartist.Pie = Chartist.Base.extend({ + constructor: Pie, + createChart: createChart, + determineAnchorPosition: determineAnchorPosition + }); + + }(window, document, Chartist)); + + return Chartist; + +})); \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/addon/edit/matchbrackets.js b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/addon/edit/matchbrackets.js new file mode 100644 index 0000000..576ec14 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/addon/edit/matchbrackets.js @@ -0,0 +1,108 @@ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + var ie_lt8 = /MSIE \d/.test(navigator.userAgent) && + (document.documentMode == null || document.documentMode < 8); + + var Pos = CodeMirror.Pos; + + var matching = {"(": ")>", ")": "(<", "[": "]>", "]": "[<", "{": "}>", "}": "{<"}; + + function findMatchingBracket(cm, where, strict, config) { + var line = cm.getLineHandle(where.line), pos = where.ch - 1; + var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)]; + if (!match) return null; + var dir = match.charAt(1) == ">" ? 1 : -1; + if (strict && (dir > 0) != (pos == where.ch)) return null; + var style = cm.getTokenTypeAt(Pos(where.line, pos + 1)); + + var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config); + return {from: Pos(where.line, pos), to: found && found.pos, + match: found && found.ch == match.charAt(0), forward: dir > 0}; + } + + function scanForBracket(cm, where, dir, style, config) { + var maxScanLen = (config && config.maxScanLineLength) || 10000; + var maxScanLines = (config && config.maxScanLines) || 500; + + var stack = [], re = /[(){}[\]]/; + var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1) + : Math.max(cm.firstLine() - 1, where.line - maxScanLines); + for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) { + var line = cm.getLine(lineNo); + if (!line) continue; + var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1; + if (line.length > maxScanLen) continue; + if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0); + for (; pos != end; pos += dir) { + var ch = line.charAt(pos); + if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) { + var match = matching[ch]; + if ((match.charAt(1) == ">") == (dir > 0)) stack.push(ch); + else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch}; + else stack.pop(); + } + } + } + } + + function matchBrackets(cm, autoclear, config) { + // Disable brace matching in long lines, since it'll cause hugely slow updates + var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000; + var marks = [], ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config); + if (match && cm.getLine(match.from.line).length <= maxHighlightLen && + match.to && cm.getLine(match.to.line).length <= maxHighlightLen) { + var style = match.match ? "CodeMirror-matchingbracket" : "CodeMirror-nonmatchingbracket"; + marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style})); + if (match.to) + marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style})); + } + } + + if (marks.length) { + // Kludge to work around the IE bug from issue #1193, where text + // input stops going to the textare whever this fires. + if (ie_lt8 && cm.state.focused) cm.display.input.focus(); + + var clear = function() { + cm.operation(function() { + for (var i = 0; i < marks.length; i++) marks[i].clear(); + }); + }; + if (autoclear) setTimeout(clear, 800); + else return clear; + } + } + + var currentlyHighlighted = null; + function doMatchBrackets(cm) { + cm.operation(function() { + if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;} + currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets); + }); + } + + CodeMirror.defineOption("matchBrackets", false, function(cm, val, old) { + if (old && old != CodeMirror.Init) + cm.off("cursorActivity", doMatchBrackets); + if (val) { + cm.state.matchBrackets = typeof val == "object" ? val : {}; + cm.on("cursorActivity", doMatchBrackets); + } + }); + + CodeMirror.defineExtension("matchBrackets", function() {matchBrackets(this, true);}); + CodeMirror.defineExtension("findMatchingBracket", function(pos, strict){ + return findMatchingBracket(this, pos, strict); + }); + CodeMirror.defineExtension("scanForBracket", function(pos, dir, style){ + return scanForBracket(this, pos, dir, style); + }); +}); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/addon/selection/active-line.js b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/addon/selection/active-line.js new file mode 100644 index 0000000..a818f10 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/addon/selection/active-line.js @@ -0,0 +1,66 @@ +// Because sometimes you need to style the cursor's line. +// +// Adds an option 'styleActiveLine' which, when enabled, gives the +// active line's wrapping the CSS class "CodeMirror-activeline", +// and gives its background');D=F.group;}F.er(this,E,B);}B.push('');x.setHtml(B.join(''));if(this.parent)this.parent._.panel.rA(w,this.id,q,r,s,t);else w.gf(this.id,q,r,s,t);v.oW('menuShow',[w]);},hide:function(){this._.panel&&this._.panel.hide();}}});function p(q){q.sort(function(r,s){if(r.groupthe class "CodeMirror-activeline-background". + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + var WRAP_CLASS = "CodeMirror-activeline"; + var BACK_CLASS = "CodeMirror-activeline-background"; + + CodeMirror.defineOption("styleActiveLine", false, function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.state.activeLines = []; + updateActiveLines(cm, cm.listSelections()); + cm.on("beforeSelectionChange", selectionChange); + } else if (!val && prev) { + cm.off("beforeSelectionChange", selectionChange); + clearActiveLines(cm); + delete cm.state.activeLines; + } + }); + + function clearActiveLines(cm) { + for (var i = 0; i < cm.state.activeLines.length; i++) { + cm.removeLineClass(cm.state.activeLines[i], "wrap", WRAP_CLASS); + cm.removeLineClass(cm.state.activeLines[i], "background", BACK_CLASS); + } + } + + function sameArray(a, b) { + if (a.length != b.length) return false; + for (var i = 0; i < a.length; i++) + if (a[i] != b[i]) return false; + return true; + } + + function updateActiveLines(cm, ranges) { + var active = []; + for (var i = 0; i < ranges.length; i++) { + var line = cm.getLineHandleVisualStart(ranges[i].head.line); + if (active[active.length - 1] != line) active.push(line); + } + if (sameArray(cm.state.activeLines, active)) return; + cm.operation(function() { + clearActiveLines(cm); + for (var i = 0; i < active.length; i++) { + cm.addLineClass(active[i], "wrap", WRAP_CLASS); + cm.addLineClass(active[i], "background", BACK_CLASS); + } + cm.state.activeLines = active; + }); + } + + function selectionChange(cm, sel) { + updateActiveLines(cm, sel.ranges); + } +}); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/lib/codemirror.css b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/lib/codemirror.css new file mode 100644 index 0000000..d263e44 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/lib/codemirror.css @@ -0,0 +1,270 @@ +/* BASICS */ + +.CodeMirror { + /* Set height, width, borders, and global font properties here */ + font-family: monospace; + height: 300px; +} +.CodeMirror-scroll { + /* Set scrolling behaviour here */ + overflow: auto; +} + +/* PADDING */ + +.CodeMirror-lines { + padding: 4px 0; /* Vertical padding around content */ +} +.CodeMirror pre { + padding: 0 4px; /* Horizontal padding of content */ +} + +.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + background-color: white; /* The little square between H and V scrollbars */ +} + +/* GUTTER */ + +.CodeMirror-gutters { + border-right: 1px solid #ddd; + background-color: #f7f7f7; + white-space: nowrap; +} +.CodeMirror-linenumbers {} +.CodeMirror-linenumber { + padding: 0 3px 0 5px; + min-width: 20px; + text-align: right; + color: #999; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +/* CURSOR */ + +.CodeMirror div.CodeMirror-cursor { + border-left: 1px solid black; +} +/* Shown when moving in bi-directional text */ +.CodeMirror div.CodeMirror-secondarycursor { + border-left: 1px solid silver; +} +.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { + width: auto; + border: 0; + background: #7e7; +} +/* Can style cursor different in overwrite (non-insert) mode */ +div.CodeMirror-overwrite div.CodeMirror-cursor {} + +.cm-tab { display: inline-block; } + +.CodeMirror-ruler { + border-left: 1px solid #ccc; + position: absolute; +} + +/* DEFAULT THEME */ + +.cm-s-default .cm-keyword {color: #708;} +.cm-s-default .cm-atom {color: #219;} +.cm-s-default .cm-number {color: #164;} +.cm-s-default .cm-def {color: #00f;} +.cm-s-default .cm-variable {color: black;} +.cm-s-default .cm-variable-2 {color: #05a;} +.cm-s-default .cm-variable-3 {color: #085;} +.cm-s-default .cm-property {color: black;} +.cm-s-default .cm-operator {color: black;} +.cm-s-default .cm-comment {color: #a50;} +.cm-s-default .cm-string {color: #a11;} +.cm-s-default .cm-string-2 {color: #f50;} +.cm-s-default .cm-meta {color: #555;} +.cm-s-default .cm-qualifier {color: #555;} +.cm-s-default .cm-builtin {color: #30a;} +.cm-s-default .cm-bracket {color: #997;} +.cm-s-default .cm-tag {color: #170;} +.cm-s-default .cm-attribute {color: #00c;} +.cm-s-default .cm-header {color: blue;} +.cm-s-default .cm-quote {color: #090;} +.cm-s-default .cm-hr {color: #999;} +.cm-s-default .cm-link {color: #00c;} + +.cm-negative {color: #d44;} +.cm-positive {color: #292;} +.cm-header, .cm-strong {font-weight: bold;} +.cm-em {font-style: italic;} +.cm-link {text-decoration: underline;} + +.cm-s-default .cm-error {color: #f00;} +.cm-invalidchar {color: #f00;} + +div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} +div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} +.CodeMirror-activeline-background {background: #e8f2ff;} + +/* STOP */ + +/* The rest of this file contains styles related to the mechanics of + the editor. You probably shouldn't touch them. */ + +.CodeMirror { + line-height: 1; + position: relative; + overflow: hidden; + background: white; + color: black; +} + +.CodeMirror-scroll { + /* 30px is the magic margin used to hide the element's real scrollbars */ + /* See overflow: hidden in .CodeMirror */ + margin-bottom: -30px; margin-right: -30px; + padding-bottom: 30px; + height: 100%; + outline: none; /* Prevent dragging from highlighting the element */ + position: relative; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +.CodeMirror-sizer { + position: relative; + border-right: 30px solid transparent; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +/* The fake, visible scrollbars. Used to force redraw during scrolling + before actuall scrolling happens, thus preventing shaking and + flickering artifacts. */ +.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { + position: absolute; + z-index: 6; + display: none; +} +.CodeMirror-vscrollbar { + right: 0; top: 0; + overflow-x: hidden; + overflow-y: scroll; +} +.CodeMirror-hscrollbar { + bottom: 0; left: 0; + overflow-y: hidden; + overflow-x: scroll; +} +.CodeMirror-scrollbar-filler { + right: 0; bottom: 0; +} +.CodeMirror-gutter-filler { + left: 0; bottom: 0; +} + +.CodeMirror-gutters { + position: absolute; left: 0; top: 0; + padding-bottom: 30px; + z-index: 3; +} +.CodeMirror-gutter { + white-space: normal; + height: 100%; + -moz-box-sizing: content-box; + box-sizing: content-box; + padding-bottom: 30px; + margin-bottom: -32px; + display: inline-block; + /* Hack to make IE7 behave */ + *zoom:1; + *display:inline; +} +.CodeMirror-gutter-elt { + position: absolute; + cursor: default; + z-index: 4; +} + +.CodeMirror-lines { + cursor: text; +} +.CodeMirror pre { + /* Reset some styles that the rest of the page might have set */ + -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; + border-width: 0; + background: transparent; + font-family: inherit; + font-size: inherit; + margin: 0; + white-space: pre; + word-wrap: normal; + line-height: inherit; + color: inherit; + z-index: 2; + position: relative; + overflow: visible; +} +.CodeMirror-wrap pre { + word-wrap: break-word; + white-space: pre-wrap; + word-break: normal; +} + +.CodeMirror-linebackground { + position: absolute; + left: 0; right: 0; top: 0; bottom: 0; + z-index: 0; +} + +.CodeMirror-linewidget { + position: relative; + z-index: 2; + overflow: auto; +} + +.CodeMirror-widget {} + +.CodeMirror-wrap .CodeMirror-scroll { + overflow-x: hidden; +} + +.CodeMirror-measure { + position: absolute; + width: 100%; + height: 0; + overflow: hidden; + visibility: hidden; +} +.CodeMirror-measure pre { position: static; } + +.CodeMirror div.CodeMirror-cursor { + position: absolute; + border-right: none; + width: 0; +} + +div.CodeMirror-cursors { + visibility: hidden; + position: relative; + z-index: 1; +} +.CodeMirror-focused div.CodeMirror-cursors { + visibility: visible; +} + +.CodeMirror-selected { background: #d9d9d9; } +.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } + +.cm-searching { + background: #ffa; + background: rgba(255, 255, 0, .4); +} + +/* IE7 hack to prevent it from returning funny offsetTops on the spans */ +.CodeMirror span { *vertical-align: text-bottom; } + +/* Used to force a border model for a node */ +.cm-force-border { padding-right: .1px; } + +@media print { + /* Hide the cursor when printing */ + .CodeMirror div.CodeMirror-cursors { + visibility: hidden; + } +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/lib/codemirror.js b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/lib/codemirror.js new file mode 100644 index 0000000..c3205cc --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/lib/codemirror.js @@ -0,0 +1,7339 @@ +// This is CodeMirror (http://codemirror.net), a code editor +// implemented in JavaScript on top of the browser's DOM. +// +// You can find some technical background for some of the code below +// at http://marijnhaverbeke.nl/blog/#cm-internals . + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + module.exports = mod(); + else if (typeof define == "function" && define.amd) // AMD + return define([], mod); + else // Plain browser env + this.CodeMirror = mod(); +})(function() { + "use strict"; + + // BROWSER SNIFFING + + // Kludges for bugs and behavior differences that can't be feature + // detected are enabled based on userAgent etc sniffing. + + var gecko = /gecko\/\d/i.test(navigator.userAgent); + // ie_uptoN means Internet Explorer version N or lower + var ie_upto10 = /MSIE \d/.test(navigator.userAgent); + var ie_upto7 = ie_upto10 && (document.documentMode == null || document.documentMode < 8); + var ie_upto8 = ie_upto10 && (document.documentMode == null || document.documentMode < 9); + var ie_upto9 = ie_upto10 && (document.documentMode == null || document.documentMode < 10); + var ie_11up = /Trident\/([7-9]|\d{2,})\./.test(navigator.userAgent); + var ie = ie_upto10 || ie_11up; + var webkit = /WebKit\//.test(navigator.userAgent); + var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); + var chrome = /Chrome\//.test(navigator.userAgent); + var presto = /Opera\//.test(navigator.userAgent); + var safari = /Apple Computer/.test(navigator.vendor); + var khtml = /KHTML\//.test(navigator.userAgent); + var mac_geLion = /Mac OS X 1\d\D([7-9]|\d\d)\D/.test(navigator.userAgent); + var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent); + var phantom = /PhantomJS/.test(navigator.userAgent); + + var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); + // This is woefully incomplete. Suggestions for alternative methods welcome. + var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); + var mac = ios || /Mac/.test(navigator.platform); + var windows = /win/i.test(navigator.platform); + + var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/); + if (presto_version) presto_version = Number(presto_version[1]); + if (presto_version && presto_version >= 15) { presto = false; webkit = true; } + // Some browsers use the wrong event properties to signal cmd/ctrl on OS X + var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); + var captureRightClick = gecko || (ie && !ie_upto8); + + // Optimize some code when these features are not used. + var sawReadOnlySpans = false, sawCollapsedSpans = false; + + // EDITOR CONSTRUCTOR + + // A CodeMirror instance represents an editor. This is the object + // that user code is usually dealing with. + + function CodeMirror(place, options) { + if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); + + this.options = options = options || {}; + // Determine effective options based on given values and defaults. + for (var opt in defaults) if (!options.hasOwnProperty(opt)) + options[opt] = defaults[opt]; + setGuttersForLineNumbers(options); + + var doc = options.value; + if (typeof doc == "string") doc = new Doc(doc, options.mode); + this.doc = doc; + + var display = this.display = new Display(place, doc); + display.wrapper.CodeMirror = this; + updateGutters(this); + themeChanged(this); + if (options.lineWrapping) + this.display.wrapper.className += " CodeMirror-wrap"; + if (options.autofocus && !mobile) focusInput(this); + + this.state = { + keyMaps: [], // stores maps added by addKeyMap + overlays: [], // highlighting overlays, as added by addOverlay + modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info + overwrite: false, focused: false, + suppressEdits: false, // used to disable editing during key handlers when in readOnly mode + pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput + draggingText: false, + highlight: new Delayed() // stores highlight worker timeout + }; + + // Override magic textarea content restore that IE sometimes does + // on our hidden textarea on reload + if (ie_upto10) setTimeout(bind(resetInput, this, true), 20); + + registerEventHandlers(this); + + var cm = this; + runInOp(this, function() { + cm.curOp.forceUpdate = true; + attachDoc(cm, doc); + + if ((options.autofocus && !mobile) || activeElt() == display.input) + setTimeout(bind(onFocus, cm), 20); + else + onBlur(cm); + + for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) + optionHandlers[opt](cm, options[opt], Init); + for (var i = 0; i < initHooks.length; ++i) initHooks[i](cm); + }); + } + + // DISPLAY CONSTRUCTOR + + // The display handles the DOM integration, both for input reading + // and content drawing. It holds references to DOM nodes and + // display-related state. + + function Display(place, doc) { + var d = this; + + // The semihidden textarea that is focused when the editor is + // focused, and receives input. + var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none"); + // The textarea is kept positioned near the cursor to prevent the + // fact that it'll be scrolled into view on input from scrolling + // our fake cursor out of view. On webkit, when wrap=off, paste is + // very slow. So make the area wide instead. + if (webkit) input.style.width = "1000px"; + else input.setAttribute("wrap", "off"); + // If border: 0; -- iOS fails to open keyboard (issue #1287) + if (ios) input.style.border = "1px solid black"; + input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false"); + + // Wraps and hides input textarea + d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); + // The fake scrollbar elements. + d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); + d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); + // Covers bottom-right square when both scrollbars are present. + d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); + // Covers bottom of gutter when coverGutterNextToScrollbar is on + // and h scrollbar is present. + d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); + // Will contain the actual code, positioned to cover the viewport. + d.lineDiv = elt("div", null, "CodeMirror-code"); + // Elements are added to these to represent selection and cursors. + d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); + d.cursorDiv = elt("div", null, "CodeMirror-cursors"); + // A visibility: hidden element used to find the size of things. + d.measure = elt("div", null, "CodeMirror-measure"); + // When lines outside of the viewport are measured, they are drawn in this. + d.lineMeasure = elt("div", null, "CodeMirror-measure"); + // Wraps everything that needs to exist inside the vertically-padded coordinate system + d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], + null, "position: relative; outline: none"); + // Moved around its parent to cover visible view. + d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); + // Set to the height of the document, allowing scrolling. + d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); + // Behavior of elts with overflow: auto and padding is + // inconsistent across browsers. This is used to ensure the + // scrollable area is big enough. + d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;"); + // Will contain the gutters, if any. + d.gutters = elt("div", null, "CodeMirror-gutters"); + d.lineGutter = null; + // Actual scrollable element. + d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); + d.scroller.setAttribute("tabIndex", "-1"); + // The element in which the editor lives. + d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV, + d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); + + // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) + if (ie_upto7) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } + // Needed to hide big blue blinking cursor on Mobile Safari + if (ios) input.style.width = "0px"; + if (!webkit) d.scroller.draggable = true; + // Needed to handle Tab key in KHTML + if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; } + // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). + if (ie_upto7) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px"; + + if (place.appendChild) place.appendChild(d.wrapper); + else place(d.wrapper); + + // Current rendered range (may be bigger than the view window). + d.viewFrom = d.viewTo = doc.first; + // Information about the rendered lines. + d.view = []; + // Holds info about a single rendered line when it was rendered + // for measurement, while not in view. + d.externalMeasured = null; + // Empty space (in pixels) above the view + d.viewOffset = 0; + d.lastSizeC = 0; + d.updateLineNumbers = null; + + // Used to only resize the line number gutter when necessary (when + // the amount of lines crosses a boundary that makes its width change) + d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; + // See readInput and resetInput + d.prevInput = ""; + // Set to true when a non-horizontal-scrolling line widget is + // added. As an optimization, line widget aligning is skipped when + // this is false. + d.alignWidgets = false; + // Flag that indicates whether we expect input to appear real soon + // now (after some event like 'keypress' or 'input') and are + // polling intensively. + d.pollingFast = false; + // Self-resetting timeout for the poller + d.poll = new Delayed(); + + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; + + // Tracks when resetInput has punted to just putting a short + // string into the textarea instead of the full selection. + d.inaccurateSelection = false; + + // Tracks the maximum line length so that the horizontal scrollbar + // can be kept static when scrolling. + d.maxLine = null; + d.maxLineLength = 0; + d.maxLineChanged = false; + + // Used for measuring wheel scrolling granularity + d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; + + // True when shift is held down. + d.shift = false; + } + + // STATE UPDATES + + // Used to get the editor into a consistent state again when options change. + + function loadMode(cm) { + cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); + resetModeState(cm); + } + + function resetModeState(cm) { + cm.doc.iter(function(line) { + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + }); + cm.doc.frontier = cm.doc.first; + startWorker(cm, 100); + cm.state.modeGen++; + if (cm.curOp) regChange(cm); + } + + function wrappingChanged(cm) { + if (cm.options.lineWrapping) { + cm.display.wrapper.className += " CodeMirror-wrap"; + cm.display.sizer.style.minWidth = ""; + } else { + cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-wrap", ""); + findMaxLine(cm); + } + estimateLineHeights(cm); + regChange(cm); + clearCaches(cm); + setTimeout(function(){updateScrollbars(cm);}, 100); + } + + // Returns a function that estimates the height of a line, to use as + // first approximation until the line becomes visible (and is thus + // properly measurable). + function estimateHeight(cm) { + var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; + var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); + return function(line) { + if (lineIsHidden(cm.doc, line)) return 0; + + var widgetsHeight = 0; + if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { + if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; + } + + if (wrapping) + return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; + else + return widgetsHeight + th; + }; + } + + function estimateLineHeights(cm) { + var doc = cm.doc, est = estimateHeight(cm); + doc.iter(function(line) { + var estHeight = est(line); + if (estHeight != line.height) updateLineHeight(line, estHeight); + }); + } + + function keyMapChanged(cm) { + var map = keyMap[cm.options.keyMap], style = map.style; + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") + + (style ? " cm-keymap-" + style : ""); + } + + function themeChanged(cm) { + cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + + cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); + clearCaches(cm); + } + + function guttersChanged(cm) { + updateGutters(cm); + regChange(cm); + setTimeout(function(){alignHorizontally(cm);}, 20); + } + + // Rebuild the gutter elements, ensure the margin to the left of the + // code matches their width. + function updateGutters(cm) { + var gutters = cm.display.gutters, specs = cm.options.gutters; + removeChildren(gutters); + for (var i = 0; i < specs.length; ++i) { + var gutterClass = specs[i]; + var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); + if (gutterClass == "CodeMirror-linenumbers") { + cm.display.lineGutter = gElt; + gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; + } + } + gutters.style.display = i ? "" : "none"; + var width = gutters.offsetWidth; + cm.display.sizer.style.marginLeft = width + "px"; + if (i) cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0; + } + + // Compute the character length of a line, taking into account + // collapsed ranges (see markText) that might hide parts, and join + // other lines onto it. + function lineLength(line) { + if (line.height == 0) return 0; + var len = line.text.length, merged, cur = line; + while (merged = collapsedSpanAtStart(cur)) { + var found = merged.find(0, true); + cur = found.from.line; + len += found.from.ch - found.to.ch; + } + cur = line; + while (merged = collapsedSpanAtEnd(cur)) { + var found = merged.find(0, true); + len -= cur.text.length - found.from.ch; + cur = found.to.line; + len += cur.text.length - found.to.ch; + } + return len; + } + + // Find the longest line in the document. + function findMaxLine(cm) { + var d = cm.display, doc = cm.doc; + d.maxLine = getLine(doc, doc.first); + d.maxLineLength = lineLength(d.maxLine); + d.maxLineChanged = true; + doc.iter(function(line) { + var len = lineLength(line); + if (len > d.maxLineLength) { + d.maxLineLength = len; + d.maxLine = line; + } + }); + } + + // Make sure the gutters options contains the element + // "CodeMirror-linenumbers" when the lineNumbers option is true. + function setGuttersForLineNumbers(options) { + var found = indexOf(options.gutters, "CodeMirror-linenumbers"); + if (found == -1 && options.lineNumbers) { + options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); + } else if (found > -1 && !options.lineNumbers) { + options.gutters = options.gutters.slice(0); + options.gutters.splice(found, 1); + } + } + + // SCROLLBARS + + // Prepare DOM reads needed to update the scrollbars. Done in one + // shot to minimize update/measure roundtrips. + function measureForScrollbars(cm) { + var scroll = cm.display.scroller; + return { + clientHeight: scroll.clientHeight, + barHeight: cm.display.scrollbarV.clientHeight, + scrollWidth: scroll.scrollWidth, clientWidth: scroll.clientWidth, + barWidth: cm.display.scrollbarH.clientWidth, + docHeight: Math.round(cm.doc.height + paddingVert(cm.display)) + }; + } + + // Re-synchronize the fake scrollbars with the actual size of the + // content. + function updateScrollbars(cm, measure) { + if (!measure) measure = measureForScrollbars(cm); + var d = cm.display; + var scrollHeight = measure.docHeight + scrollerCutOff; + var needsH = measure.scrollWidth > measure.clientWidth; + var needsV = scrollHeight > measure.clientHeight; + if (needsV) { + d.scrollbarV.style.display = "block"; + d.scrollbarV.style.bottom = needsH ? scrollbarWidth(d.measure) + "px" : "0"; + // A bug in IE8 can cause this value to be negative, so guard it. + d.scrollbarV.firstChild.style.height = + Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px"; + } else { + d.scrollbarV.style.display = ""; + d.scrollbarV.firstChild.style.height = "0"; + } + if (needsH) { + d.scrollbarH.style.display = "block"; + d.scrollbarH.style.right = needsV ? scrollbarWidth(d.measure) + "px" : "0"; + d.scrollbarH.firstChild.style.width = + (measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px"; + } else { + d.scrollbarH.style.display = ""; + d.scrollbarH.firstChild.style.width = "0"; + } + if (needsH && needsV) { + d.scrollbarFiller.style.display = "block"; + d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = scrollbarWidth(d.measure) + "px"; + } else d.scrollbarFiller.style.display = ""; + if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { + d.gutterFiller.style.display = "block"; + d.gutterFiller.style.height = scrollbarWidth(d.measure) + "px"; + d.gutterFiller.style.width = d.gutters.offsetWidth + "px"; + } else d.gutterFiller.style.display = ""; + + if (mac_geLion && scrollbarWidth(d.measure) === 0) { + d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = mac_geMountainLion ? "18px" : "12px"; + var barMouseDown = function(e) { + if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH) + operation(cm, onMouseDown)(e); + }; + on(d.scrollbarV, "mousedown", barMouseDown); + on(d.scrollbarH, "mousedown", barMouseDown); + } + } + + // Compute the lines that are visible in a given viewport (defaults + // the the current scroll position). viewPort may contain top, + // height, and ensure (see op.scrollToPos) properties. + function visibleLines(display, doc, viewPort) { + var top = viewPort && viewPort.top != null ? viewPort.top : display.scroller.scrollTop; + top = Math.floor(top - paddingTop(display)); + var bottom = viewPort && viewPort.bottom != null ? viewPort.bottom : top + display.wrapper.clientHeight; + + var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); + // Ensure is a {from: {line, ch}, to: {line, ch}} object, and + // forces those lines into the viewport (if possible). + if (viewPort && viewPort.ensure) { + var ensureFrom = viewPort.ensure.from.line, ensureTo = viewPort.ensure.to.line; + if (ensureFrom < from) + return {from: ensureFrom, + to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)}; + if (Math.min(ensureTo, doc.lastLine()) >= to) + return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight), + to: ensureTo}; + } + return {from: from, to: to}; + } + + // LINE NUMBERS + + // Re-align line numbers and gutter marks to compensate for + // horizontal scrolling. + function alignHorizontally(cm) { + var display = cm.display, view = display.view; + if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; + var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; + var gutterW = display.gutters.offsetWidth, left = comp + "px"; + for (var i = 0; i < view.length; i++) if (!view[i].hidden) { + if (cm.options.fixedGutter && view[i].gutter) + view[i].gutter.style.left = left; + var align = view[i].alignable; + if (align) for (var j = 0; j < align.length; j++) + align[j].style.left = left; + } + if (cm.options.fixedGutter) + display.gutters.style.left = (comp + gutterW) + "px"; + } + + // Used to ensure that the line number gutter is still the right + // size for the current document size. Returns true when an update + // is needed. + function maybeUpdateLineNumberWidth(cm) { + if (!cm.options.lineNumbers) return false; + var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; + if (last.length != display.lineNumChars) { + var test = display.measure.appendChild(elt("div", [elt("div", last)], + "CodeMirror-linenumber CodeMirror-gutter-elt")); + var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; + display.lineGutter.style.width = ""; + display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding); + display.lineNumWidth = display.lineNumInnerWidth + padding; + display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; + display.lineGutter.style.width = display.lineNumWidth + "px"; + var width = display.gutters.offsetWidth; + display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0; + display.sizer.style.marginLeft = width + "px"; + return true; + } + return false; + } + + function lineNumberFor(options, i) { + return String(options.lineNumberFormatter(i + options.firstLineNumber)); + } + + // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, + // but using getBoundingClientRect to get a sub-pixel-accurate + // result. + function compensateForHScroll(display) { + return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; + } + + // DISPLAY DRAWING + + // Updates the display, selection, and scrollbars, using the + // information in display.view to find out which nodes are no longer + // up-to-date. Tries to bail out early when no changes are needed, + // unless forced is true. + // Returns true if an actual update happened, false otherwise. + function updateDisplay(cm, viewPort, forced) { + var oldFrom = cm.display.viewFrom, oldTo = cm.display.viewTo, updated; + var visible = visibleLines(cm.display, cm.doc, viewPort); + for (var first = true;; first = false) { + var oldWidth = cm.display.scroller.clientWidth; + if (!updateDisplayInner(cm, visible, forced)) break; + updated = true; + + // If the max line changed since it was last measured, measure it, + // and ensure the document's width matches it. + if (cm.display.maxLineChanged && !cm.options.lineWrapping) + adjustContentWidth(cm); + + var barMeasure = measureForScrollbars(cm); + updateSelection(cm); + setDocumentHeight(cm, barMeasure); + updateScrollbars(cm, barMeasure); + if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) { + forced = true; + continue; + } + forced = false; + + // Clip forced viewport to actual scrollable area. + if (viewPort && viewPort.top != null) + viewPort = {top: Math.min(barMeasure.docHeight - scrollerCutOff - barMeasure.clientHeight, viewPort.top)}; + // Updated line heights might result in the drawn area not + // actually covering the viewport. Keep looping until it does. + visible = visibleLines(cm.display, cm.doc, viewPort); + if (visible.from >= cm.display.viewFrom && visible.to <= cm.display.viewTo) + break; + } + + cm.display.updateLineNumbers = null; + if (updated) { + signalLater(cm, "update", cm); + if (cm.display.viewFrom != oldFrom || cm.display.viewTo != oldTo) + signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); + } + return updated; + } + + // Does the actual updating of the line display. Bails out + // (returning false) when there is nothing to be done and forced is + // false. + function updateDisplayInner(cm, visible, forced) { + var display = cm.display, doc = cm.doc; + if (!display.wrapper.offsetWidth) { + resetView(cm); + return; + } + + // Bail out if the visible area is already rendered and nothing changed. + if (!forced && visible.from >= display.viewFrom && visible.to <= display.viewTo && + countDirtyView(cm) == 0) + return; + + if (maybeUpdateLineNumberWidth(cm)) + resetView(cm); + var dims = getDimensions(cm); + + // Compute a suitable new viewport (from & to) + var end = doc.first + doc.size; + var from = Math.max(visible.from - cm.options.viewportMargin, doc.first); + var to = Math.min(end, visible.to + cm.options.viewportMargin); + if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); + if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); + if (sawCollapsedSpans) { + from = visualLineNo(cm.doc, from); + to = visualLineEndNo(cm.doc, to); + } + + var different = from != display.viewFrom || to != display.viewTo || + display.lastSizeC != display.wrapper.clientHeight; + adjustView(cm, from, to); + + display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); + // Position the mover div to align with the current scroll position + cm.display.mover.style.top = display.viewOffset + "px"; + + var toUpdate = countDirtyView(cm); + if (!different && toUpdate == 0 && !forced) return; + + // For big changes, we hide the enclosing element during the + // update, since that speeds up the operations on most browsers. + var focused = activeElt(); + if (toUpdate > 4) display.lineDiv.style.display = "none"; + patchDisplay(cm, display.updateLineNumbers, dims); + if (toUpdate > 4) display.lineDiv.style.display = ""; + // There might have been a widget with a focused element that got + // hidden or updated, if so re-focus it. + if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); + + // Prevent selection and cursors from interfering with the scroll + // width. + removeChildren(display.cursorDiv); + removeChildren(display.selectionDiv); + + if (different) { + display.lastSizeC = display.wrapper.clientHeight; + startWorker(cm, 400); + } + + updateHeightsInViewport(cm); + + return true; + } + + function adjustContentWidth(cm) { + var display = cm.display; + var width = measureChar(cm, display.maxLine, display.maxLine.text.length).left; + display.maxLineChanged = false; + var minWidth = Math.max(0, width + 3); + var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + minWidth + scrollerCutOff - display.scroller.clientWidth); + display.sizer.style.minWidth = minWidth + "px"; + if (maxScrollLeft < cm.doc.scrollLeft) + setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true); + } + + function setDocumentHeight(cm, measure) { + cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px"; + cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px"; + } + + // Read the actual heights of the rendered lines, and update their + // stored heights to match. + function updateHeightsInViewport(cm) { + var display = cm.display; + var prevBottom = display.lineDiv.offsetTop; + for (var i = 0; i < display.view.length; i++) { + var cur = display.view[i], height; + if (cur.hidden) continue; + if (ie_upto7) { + var bot = cur.node.offsetTop + cur.node.offsetHeight; + height = bot - prevBottom; + prevBottom = bot; + } else { + var box = cur.node.getBoundingClientRect(); + height = box.bottom - box.top; + } + var diff = cur.line.height - height; + if (height < 2) height = textHeight(display); + if (diff > .001 || diff < -.001) { + updateLineHeight(cur.line, height); + updateWidgetHeight(cur.line); + if (cur.rest) for (var j = 0; j < cur.rest.length; j++) + updateWidgetHeight(cur.rest[j]); + } + } + } + + // Read and store the height of line widgets associated with the + // given line. + function updateWidgetHeight(line) { + if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) + line.widgets[i].height = line.widgets[i].node.offsetHeight; + } + + // Do a bulk-read of the DOM positions and sizes needed to draw the + // view, so that we don't interleave reading and writing to the DOM. + function getDimensions(cm) { + var d = cm.display, left = {}, width = {}; + for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { + left[cm.options.gutters[i]] = n.offsetLeft; + width[cm.options.gutters[i]] = n.offsetWidth; + } + return {fixedPos: compensateForHScroll(d), + gutterTotalWidth: d.gutters.offsetWidth, + gutterLeft: left, + gutterWidth: width, + wrapperWidth: d.wrapper.clientWidth}; + } + + // Sync the actual display DOM structure with display.view, removing + // nodes for lines that are no longer in view, and creating the ones + // that are not there yet, and updating the ones that are out of + // date. + function patchDisplay(cm, updateNumbersFrom, dims) { + var display = cm.display, lineNumbers = cm.options.lineNumbers; + var container = display.lineDiv, cur = container.firstChild; + + function rm(node) { + var next = node.nextSibling; + // Works around a throw-scroll bug in OS X Webkit + if (webkit && mac && cm.display.currentWheelTarget == node) + node.style.display = "none"; + else + node.parentNode.removeChild(node); + return next; + } + + var view = display.view, lineN = display.viewFrom; + // Loop over the elements in the view, syncing cur (the DOM nodes + // in display.lineDiv) with the view as we go. + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (lineView.hidden) { + } else if (!lineView.node) { // Not drawn yet + var node = buildLineElement(cm, lineView, lineN, dims); + container.insertBefore(node, cur); + } else { // Already drawn + while (cur != lineView.node) cur = rm(cur); + var updateNumber = lineNumbers && updateNumbersFrom != null && + updateNumbersFrom <= lineN && lineView.lineNumber; + if (lineView.changes) { + if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; + updateLineForChanges(cm, lineView, lineN, dims); + } + if (updateNumber) { + removeChildren(lineView.lineNumber); + lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); + } + cur = lineView.node.nextSibling; + } + lineN += lineView.size; + } + while (cur) cur = rm(cur); + } + + // When an aspect of a line changes, a string is added to + // lineView.changes. This updates the relevant part of the line's + // DOM structure. + function updateLineForChanges(cm, lineView, lineN, dims) { + for (var j = 0; j < lineView.changes.length; j++) { + var type = lineView.changes[j]; + if (type == "text") updateLineText(cm, lineView); + else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); + else if (type == "class") updateLineClasses(lineView); + else if (type == "widget") updateLineWidgets(lineView, dims); + } + lineView.changes = null; + } + + // Lines with gutter elements, widgets or a background class need to + // be wrapped, and have the extra elements added to the wrapper div + function ensureLineWrapped(lineView) { + if (lineView.node == lineView.text) { + lineView.node = elt("div", null, null, "position: relative"); + if (lineView.text.parentNode) + lineView.text.parentNode.replaceChild(lineView.node, lineView.text); + lineView.node.appendChild(lineView.text); + if (ie_upto7) lineView.node.style.zIndex = 2; + } + return lineView.node; + } + + function updateLineBackground(lineView) { + var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; + if (cls) cls += " CodeMirror-linebackground"; + if (lineView.background) { + if (cls) lineView.background.className = cls; + else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } + } else if (cls) { + var wrap = ensureLineWrapped(lineView); + lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); + } + } + + // Wrapper around buildLineContent which will reuse the structure + // in display.externalMeasured when possible. + function getLineContent(cm, lineView) { + var ext = cm.display.externalMeasured; + if (ext && ext.line == lineView.line) { + cm.display.externalMeasured = null; + lineView.measure = ext.measure; + return ext.built; + } + return buildLineContent(cm, lineView); + } + + // Redraw the line's text. Interacts with the background and text + // classes because the mode may output tokens that influence these + // classes. + function updateLineText(cm, lineView) { + var cls = lineView.text.className; + var built = getLineContent(cm, lineView); + if (lineView.text == lineView.node) lineView.node = built.pre; + lineView.text.parentNode.replaceChild(built.pre, lineView.text); + lineView.text = built.pre; + if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { + lineView.bgClass = built.bgClass; + lineView.textClass = built.textClass; + updateLineClasses(lineView); + } else if (cls) { + lineView.text.className = cls; + } + } + + function updateLineClasses(lineView) { + updateLineBackground(lineView); + if (lineView.line.wrapClass) + ensureLineWrapped(lineView).className = lineView.line.wrapClass; + else if (lineView.node != lineView.text) + lineView.node.className = ""; + var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; + lineView.text.className = textClass || ""; + } + + function updateLineGutter(cm, lineView, lineN, dims) { + if (lineView.gutter) { + lineView.node.removeChild(lineView.gutter); + lineView.gutter = null; + } + var markers = lineView.line.gutterMarkers; + if (cm.options.lineNumbers || markers) { + var wrap = ensureLineWrapped(lineView); + var gutterWrap = lineView.gutter = + wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " + + (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"), + lineView.text); + if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) + lineView.lineNumber = gutterWrap.appendChild( + elt("div", lineNumberFor(cm.options, lineN), + "CodeMirror-linenumber CodeMirror-gutter-elt", + "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " + + cm.display.lineNumInnerWidth + "px")); + if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { + var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; + if (found) + gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + + dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); + } + } + } + + function updateLineWidgets(lineView, dims) { + if (lineView.alignable) lineView.alignable = null; + for (var node = lineView.node.firstChild, next; node; node = next) { + var next = node.nextSibling; + if (node.className == "CodeMirror-linewidget") + lineView.node.removeChild(node); + } + insertLineWidgets(lineView, dims); + } + + // Build a line's DOM representation from scratch + function buildLineElement(cm, lineView, lineN, dims) { + var built = getLineContent(cm, lineView); + lineView.text = lineView.node = built.pre; + if (built.bgClass) lineView.bgClass = built.bgClass; + if (built.textClass) lineView.textClass = built.textClass; + + updateLineClasses(lineView); + updateLineGutter(cm, lineView, lineN, dims); + insertLineWidgets(lineView, dims); + return lineView.node; + } + + // A lineView may contain multiple logical lines (when merged by + // collapsed spans). The widgets for all of them need to be drawn. + function insertLineWidgets(lineView, dims) { + insertLineWidgetsFor(lineView.line, lineView, dims, true); + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + insertLineWidgetsFor(lineView.rest[i], lineView, dims, false); + } + + function insertLineWidgetsFor(line, lineView, dims, allowAbove) { + if (!line.widgets) return; + var wrap = ensureLineWrapped(lineView); + for (var i = 0, ws = line.widgets; i < ws.length; ++i) { + var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); + if (!widget.handleMouseEvents) node.ignoreEvents = true; + positionLineWidget(widget, node, lineView, dims); + if (allowAbove && widget.above) + wrap.insertBefore(node, lineView.gutter || lineView.text); + else + wrap.appendChild(node); + signalLater(widget, "redraw"); + } + } + + function positionLineWidget(widget, node, lineView, dims) { + if (widget.noHScroll) { + (lineView.alignable || (lineView.alignable = [])).push(node); + var width = dims.wrapperWidth; + node.style.left = dims.fixedPos + "px"; + if (!widget.coverGutter) { + width -= dims.gutterTotalWidth; + node.style.paddingLeft = dims.gutterTotalWidth + "px"; + } + node.style.width = width + "px"; + } + if (widget.coverGutter) { + node.style.zIndex = 5; + node.style.position = "relative"; + if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; + } + } + + // POSITION OBJECT + + // A Pos instance represents a position within the text. + var Pos = CodeMirror.Pos = function(line, ch) { + if (!(this instanceof Pos)) return new Pos(line, ch); + this.line = line; this.ch = ch; + }; + + // Compare two positions, return 0 if they are the same, a negative + // number when a is less, and a positive number otherwise. + var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; }; + + function copyPos(x) {return Pos(x.line, x.ch);} + function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } + function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } + + // SELECTION / CURSOR + + // Selection objects are immutable. A new one is created every time + // the selection changes. A selection is one or more non-overlapping + // (and non-touching) ranges, sorted, and an integer that indicates + // which one is the primary selection (the one that's scrolled into + // view, that getCursor returns, etc). + function Selection(ranges, primIndex) { + this.ranges = ranges; + this.primIndex = primIndex; + } + + Selection.prototype = { + primary: function() { return this.ranges[this.primIndex]; }, + equals: function(other) { + if (other == this) return true; + if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; + for (var i = 0; i < this.ranges.length; i++) { + var here = this.ranges[i], there = other.ranges[i]; + if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; + } + return true; + }, + deepCopy: function() { + for (var out = [], i = 0; i < this.ranges.length; i++) + out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); + return new Selection(out, this.primIndex); + }, + somethingSelected: function() { + for (var i = 0; i < this.ranges.length; i++) + if (!this.ranges[i].empty()) return true; + return false; + }, + contains: function(pos, end) { + if (!end) end = pos; + for (var i = 0; i < this.ranges.length; i++) { + var range = this.ranges[i]; + if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) + return i; + } + return -1; + } + }; + + function Range(anchor, head) { + this.anchor = anchor; this.head = head; + } + + Range.prototype = { + from: function() { return minPos(this.anchor, this.head); }, + to: function() { return maxPos(this.anchor, this.head); }, + empty: function() { + return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; + } + }; + + // Take an unsorted, potentially overlapping set of ranges, and + // build a selection out of it. 'Consumes' ranges array (modifying + // it). + function normalizeSelection(ranges, primIndex) { + var prim = ranges[primIndex]; + ranges.sort(function(a, b) { return cmp(a.from(), b.from()); }); + primIndex = indexOf(ranges, prim); + for (var i = 1; i < ranges.length; i++) { + var cur = ranges[i], prev = ranges[i - 1]; + if (cmp(prev.to(), cur.from()) >= 0) { + var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); + var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; + if (i <= primIndex) --primIndex; + ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); + } + } + return new Selection(ranges, primIndex); + } + + function simpleSelection(anchor, head) { + return new Selection([new Range(anchor, head || anchor)], 0); + } + + // Most of the external API clips given positions to make sure they + // actually exist within the document. + function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} + function clipPos(doc, pos) { + if (pos.line < doc.first) return Pos(doc.first, 0); + var last = doc.first + doc.size - 1; + if (pos.line > last) return Pos(last, getLine(doc, last).text.length); + return clipToLen(pos, getLine(doc, pos.line).text.length); + } + function clipToLen(pos, linelen) { + var ch = pos.ch; + if (ch == null || ch > linelen) return Pos(pos.line, linelen); + else if (ch < 0) return Pos(pos.line, 0); + else return pos; + } + function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} + function clipPosArray(doc, array) { + for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); + return out; + } + + // SELECTION UPDATES + + // The 'scroll' parameter given to many of these indicated whether + // the new cursor position should be scrolled into view after + // modifying the selection. + + // If shift is held or the extend flag is set, extends a range to + // include a given position (and optionally a second position). + // Otherwise, simply returns the range between the given positions. + // Used for cursor motion and such. + function extendRange(doc, range, head, other) { + if (doc.cm && doc.cm.display.shift || doc.extend) { + var anchor = range.anchor; + if (other) { + var posBefore = cmp(head, anchor) < 0; + if (posBefore != (cmp(other, anchor) < 0)) { + anchor = head; + head = other; + } else if (posBefore != (cmp(head, other) < 0)) { + head = other; + } + } + return new Range(anchor, head); + } else { + return new Range(other || head, head); + } + } + + // Extend the primary selection range, discard the rest. + function extendSelection(doc, head, other, options) { + setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); + } + + // Extend all selections (pos is an array of selections with length + // equal the number of selections) + function extendSelections(doc, heads, options) { + for (var out = [], i = 0; i < doc.sel.ranges.length; i++) + out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); + var newSel = normalizeSelection(out, doc.sel.primIndex); + setSelection(doc, newSel, options); + } + + // Updates a single range in the selection. + function replaceOneSelection(doc, i, range, options) { + var ranges = doc.sel.ranges.slice(0); + ranges[i] = range; + setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); + } + + // Reset the selection to a single range. + function setSimpleSelection(doc, anchor, head, options) { + setSelection(doc, simpleSelection(anchor, head), options); + } + + // Give beforeSelectionChange handlers a change to influence a + // selection update. + function filterSelectionChange(doc, sel) { + var obj = { + ranges: sel.ranges, + update: function(ranges) { + this.ranges = []; + for (var i = 0; i < ranges.length; i++) + this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), + clipPos(doc, ranges[i].head)); + } + }; + signal(doc, "beforeSelectionChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); + if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); + else return sel; + } + + function setSelectionReplaceHistory(doc, sel, options) { + var done = doc.history.done, last = lst(done); + if (last && last.ranges) { + done[done.length - 1] = sel; + setSelectionNoUndo(doc, sel, options); + } else { + setSelection(doc, sel, options); + } + } + + // Set a new selection. + function setSelection(doc, sel, options) { + setSelectionNoUndo(doc, sel, options); + addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); + } + + function setSelectionNoUndo(doc, sel, options) { + if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) + sel = filterSelectionChange(doc, sel); + + var bias = cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1; + setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); + + if (!(options && options.scroll === false) && doc.cm) + ensureCursorVisible(doc.cm); + } + + function setSelectionInner(doc, sel) { + if (sel.equals(doc.sel)) return; + + doc.sel = sel; + + if (doc.cm) + doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = + doc.cm.curOp.cursorActivity = true; + signalLater(doc, "cursorActivity", doc); + } + + // Verify that the selection does not partially select any atomic + // marked ranges. + function reCheckSelection(doc) { + setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); + } + + // Return a selection that does not partially select any atomic + // ranges. + function skipAtomicInSelection(doc, sel, bias, mayClear) { + var out; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear); + var newHead = skipAtomic(doc, range.head, bias, mayClear); + if (out || newAnchor != range.anchor || newHead != range.head) { + if (!out) out = sel.ranges.slice(0, i); + out[i] = new Range(newAnchor, newHead); + } + } + return out ? normalizeSelection(out, sel.primIndex) : sel; + } + + // Ensure a given position is not inside an atomic range. + function skipAtomic(doc, pos, bias, mayClear) { + var flipped = false, curPos = pos; + var dir = bias || 1; + doc.cantEdit = false; + search: for (;;) { + var line = getLine(doc, curPos.line); + if (line.markedSpans) { + for (var i = 0; i < line.markedSpans.length; ++i) { + var sp = line.markedSpans[i], m = sp.marker; + if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) && + (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) { + if (mayClear) { + signal(m, "beforeCursorEnter"); + if (m.explicitlyCleared) { + if (!line.markedSpans) break; + else {--i; continue;} + } + } + if (!m.atomic) continue; + var newPos = m.find(dir < 0 ? -1 : 1); + if (cmp(newPos, curPos) == 0) { + newPos.ch += dir; + if (newPos.ch < 0) { + if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1)); + else newPos = null; + } else if (newPos.ch > line.text.length) { + if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0); + else newPos = null; + } + if (!newPos) { + if (flipped) { + // Driven in a corner -- no valid cursor position found at all + // -- try again *with* clearing, if we didn't already + if (!mayClear) return skipAtomic(doc, pos, bias, true); + // Otherwise, turn off editing until further notice, and return the start of the doc + doc.cantEdit = true; + return Pos(doc.first, 0); + } + flipped = true; newPos = pos; dir = -dir; + } + } + curPos = newPos; + continue search; + } + } + } + return curPos; + } + } + + // SELECTION DRAWING + + // Redraw the selection and/or cursor + function updateSelection(cm) { + var display = cm.display, doc = cm.doc; + var curFragment = document.createDocumentFragment(); + var selFragment = document.createDocumentFragment(); + + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + var collapsed = range.empty(); + if (collapsed || cm.options.showCursorWhenSelecting) + updateSelectionCursor(cm, range, curFragment); + if (!collapsed) + updateSelectionRange(cm, range, selFragment); + } + + // Move the hidden textarea near the cursor to prevent scrolling artifacts + if (cm.options.moveInputWithCursor) { + var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); + var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); + var top = Math.max(0, Math.min(display.wrapper.clientHeight - 10, + headPos.top + lineOff.top - wrapOff.top)); + var left = Math.max(0, Math.min(display.wrapper.clientWidth - 10, + headPos.left + lineOff.left - wrapOff.left)); + display.inputDiv.style.top = top + "px"; + display.inputDiv.style.left = left + "px"; + } + + removeChildrenAndAdd(display.cursorDiv, curFragment); + removeChildrenAndAdd(display.selectionDiv, selFragment); + } + + // Draws a cursor for the given range + function updateSelectionCursor(cm, range, output) { + var pos = cursorCoords(cm, range.head, "div"); + + var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); + cursor.style.left = pos.left + "px"; + cursor.style.top = pos.top + "px"; + cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; + + if (pos.other) { + // Secondary cursor, shown when on a 'jump' in bi-directional text + var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); + otherCursor.style.display = ""; + otherCursor.style.left = pos.other.left + "px"; + otherCursor.style.top = pos.other.top + "px"; + otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; + } + } + + // Draws the given range as a highlighted selection + function updateSelectionRange(cm, range, output) { + var display = cm.display, doc = cm.doc; + var fragment = document.createDocumentFragment(); + var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right; + + function add(left, top, width, bottom) { + if (top < 0) top = 0; + fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + + "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) + + "px; height: " + (bottom - top) + "px")); + } + + function drawForLine(line, fromArg, toArg) { + var lineObj = getLine(doc, line); + var lineLen = lineObj.text.length; + var start, end; + function coords(ch, bias) { + return charCoords(cm, Pos(line, ch), "div", lineObj, bias); + } + + iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { + var leftPos = coords(from, "left"), rightPos, left, right; + if (from == to) { + rightPos = leftPos; + left = right = leftPos.left; + } else { + rightPos = coords(to - 1, "right"); + if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } + left = leftPos.left; + right = rightPos.right; + } + if (fromArg == null && from == 0) left = leftSide; + if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part + add(left, leftPos.top, null, leftPos.bottom); + left = leftSide; + if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); + } + if (toArg == null && to == lineLen) right = rightSide; + if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) + start = leftPos; + if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) + end = rightPos; + if (left < leftSide + 1) left = leftSide; + add(left, rightPos.top, right - left, rightPos.bottom); + }); + return {start: start, end: end}; + } + + var sFrom = range.from(), sTo = range.to(); + if (sFrom.line == sTo.line) { + drawForLine(sFrom.line, sFrom.ch, sTo.ch); + } else { + var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); + var singleVLine = visualLine(fromLine) == visualLine(toLine); + var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; + var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; + if (singleVLine) { + if (leftEnd.top < rightStart.top - 2) { + add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); + add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); + } else { + add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); + } + } + if (leftEnd.bottom < rightStart.top) + add(leftSide, leftEnd.bottom, null, rightStart.top); + } + + output.appendChild(fragment); + } + + // Cursor-blinking + function restartBlink(cm) { + if (!cm.state.focused) return; + var display = cm.display; + clearInterval(display.blinker); + var on = true; + display.cursorDiv.style.visibility = ""; + if (cm.options.cursorBlinkRate > 0) + display.blinker = setInterval(function() { + display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; + }, cm.options.cursorBlinkRate); + } + + // HIGHLIGHT WORKER + + function startWorker(cm, time) { + if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) + cm.state.highlight.set(time, bind(highlightWorker, cm)); + } + + function highlightWorker(cm) { + var doc = cm.doc; + if (doc.frontier < doc.first) doc.frontier = doc.first; + if (doc.frontier >= cm.display.viewTo) return; + var end = +new Date + cm.options.workTime; + var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); + + runInOp(cm, function() { + doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) { + if (doc.frontier >= cm.display.viewFrom) { // Visible + var oldStyles = line.styles; + line.styles = highlightLine(cm, line, state, true); + var ischange = !oldStyles || oldStyles.length != line.styles.length; + for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; + if (ischange) regLineChange(cm, doc.frontier, "text"); + line.stateAfter = copyState(doc.mode, state); + } else { + processLine(cm, line.text, state); + line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; + } + ++doc.frontier; + if (+new Date > end) { + startWorker(cm, cm.options.workDelay); + return true; + } + }); + }); + } + + // Finds the line to start with when starting a parse. Tries to + // find a line with a stateAfter, so that it can start with a + // valid state. If that fails, it returns the line with the + // smallest indentation, which tends to need the least context to + // parse correctly. + function findStartLine(cm, n, precise) { + var minindent, minline, doc = cm.doc; + var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); + for (var search = n; search > lim; --search) { + if (search <= doc.first) return doc.first; + var line = getLine(doc, search - 1); + if (line.stateAfter && (!precise || search <= doc.frontier)) return search; + var indented = countColumn(line.text, null, cm.options.tabSize); + if (minline == null || minindent > indented) { + minline = search - 1; + minindent = indented; + } + } + return minline; + } + + function getStateBefore(cm, n, precise) { + var doc = cm.doc, display = cm.display; + if (!doc.mode.startState) return true; + var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; + if (!state) state = startState(doc.mode); + else state = copyState(doc.mode, state); + doc.iter(pos, n, function(line) { + processLine(cm, line.text, state); + var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; + line.stateAfter = save ? copyState(doc.mode, state) : null; + ++pos; + }); + if (precise) doc.frontier = pos; + return state; + } + + // POSITION MEASUREMENT + + function paddingTop(display) {return display.lineSpace.offsetTop;} + function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} + function paddingH(display) { + if (display.cachedPaddingH) return display.cachedPaddingH; + var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); + var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; + return display.cachedPaddingH = {left: parseInt(style.paddingLeft), + right: parseInt(style.paddingRight)}; + } + + // Ensure the lineView.wrapping.heights array is populated. This is + // an array of bottom offsets for the lines that make up a drawn + // line. When lineWrapping is on, there might be more than one + // height. + function ensureLineHeights(cm, lineView, rect) { + var wrapping = cm.options.lineWrapping; + var curWidth = wrapping && cm.display.scroller.clientWidth; + if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { + var heights = lineView.measure.heights = []; + if (wrapping) { + lineView.measure.width = curWidth; + var rects = lineView.text.firstChild.getClientRects(); + for (var i = 0; i < rects.length - 1; i++) { + var cur = rects[i], next = rects[i + 1]; + if (Math.abs(cur.bottom - next.bottom) > 2) + heights.push((cur.bottom + next.top) / 2 - rect.top); + } + } + heights.push(rect.bottom - rect.top); + } + } + + // Find a line map (mapping character offsets to text nodes) and a + // measurement cache for the given line number. (A line view might + // contain multiple lines when collapsed ranges are present.) + function mapFromLineView(lineView, line, lineN) { + if (lineView.line == line) + return {map: lineView.measure.map, cache: lineView.measure.cache}; + for (var i = 0; i < lineView.rest.length; i++) + if (lineView.rest[i] == line) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}; + for (var i = 0; i < lineView.rest.length; i++) + if (lineNo(lineView.rest[i]) > lineN) + return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}; + } + + // Render a line into the hidden node display.externalMeasured. Used + // when measurement is needed for a line that's not in the viewport. + function updateExternalMeasurement(cm, line) { + line = visualLine(line); + var lineN = lineNo(line); + var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); + view.lineN = lineN; + var built = view.built = buildLineContent(cm, view); + view.text = built.pre; + removeChildrenAndAdd(cm.display.lineMeasure, built.pre); + return view; + } + + // Get a {top, bottom, left, right} box (in line-local coordinates) + // for a given character. + function measureChar(cm, line, ch, bias) { + return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); + } + + // Find a line view that corresponds to the given line number. + function findViewForLine(cm, lineN) { + if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) + return cm.display.view[findViewIndex(cm, lineN)]; + var ext = cm.display.externalMeasured; + if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) + return ext; + } + + // Measurement can be split in two steps, the set-up work that + // applies to the whole line, and the measurement of the actual + // character. Functions like coordsChar, that need to do a lot of + // measurements in a row, can thus ensure that the set-up work is + // only done once. + function prepareMeasureForLine(cm, line) { + var lineN = lineNo(line); + var view = findViewForLine(cm, lineN); + if (view && !view.text) + view = null; + else if (view && view.changes) + updateLineForChanges(cm, view, lineN, getDimensions(cm)); + if (!view) + view = updateExternalMeasurement(cm, line); + + var info = mapFromLineView(view, line, lineN); + return { + line: line, view: view, rect: null, + map: info.map, cache: info.cache, before: info.before, + hasHeights: false + }; + } + + // Given a prepared measurement object, measures the position of an + // actual character (or fetches it from the cache). + function measureCharPrepared(cm, prepared, ch, bias) { + if (prepared.before) ch = -1; + var key = ch + (bias || ""), found; + if (prepared.cache.hasOwnProperty(key)) { + found = prepared.cache[key]; + } else { + if (!prepared.rect) + prepared.rect = prepared.view.text.getBoundingClientRect(); + if (!prepared.hasHeights) { + ensureLineHeights(cm, prepared.view, prepared.rect); + prepared.hasHeights = true; + } + found = measureCharInner(cm, prepared, ch, bias); + if (!found.bogus) prepared.cache[key] = found; + } + return {left: found.left, right: found.right, top: found.top, bottom: found.bottom}; + } + + var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; + + function measureCharInner(cm, prepared, ch, bias) { + var map = prepared.map; + + var node, start, end, collapse; + // First, search the line map for the text node corresponding to, + // or closest to, the target character. + for (var i = 0; i < map.length; i += 3) { + var mStart = map[i], mEnd = map[i + 1]; + if (ch < mStart) { + start = 0; end = 1; + collapse = "left"; + } else if (ch < mEnd) { + start = ch - mStart; + end = start + 1; + } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { + end = mEnd - mStart; + start = end - 1; + if (ch >= mEnd) collapse = "right"; + } + if (start != null) { + node = map[i + 2]; + if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) + collapse = bias; + if (bias == "left" && start == 0) + while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { + node = map[(i -= 3) + 2]; + collapse = "left"; + } + if (bias == "right" && start == mEnd - mStart) + while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { + node = map[(i += 3) + 2]; + collapse = "right"; + } + break; + } + } + + var rect; + if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. + while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start; + while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end; + if (ie_upto8 && start == 0 && end == mEnd - mStart) { + rect = node.parentNode.getBoundingClientRect(); + } else if (ie && cm.options.lineWrapping) { + var rects = range(node, start, end).getClientRects(); + if (rects.length) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = nullRect; + } else { + rect = range(node, start, end).getBoundingClientRect(); + } + } else { // If it is a widget, simply get the box for the whole widget. + if (start > 0) collapse = bias = "right"; + var rects; + if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) + rect = rects[bias == "right" ? rects.length - 1 : 0]; + else + rect = node.getBoundingClientRect(); + } + if (ie_upto8 && !start && (!rect || !rect.left && !rect.right)) { + var rSpan = node.parentNode.getClientRects()[0]; + if (rSpan) + rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; + else + rect = nullRect; + } + + var top, bot = (rect.bottom + rect.top) / 2 - prepared.rect.top; + var heights = prepared.view.measure.heights; + for (var i = 0; i < heights.length - 1; i++) + if (bot < heights[i]) break; + top = i ? heights[i - 1] : 0; bot = heights[i]; + var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, + right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, + top: top, bottom: bot}; + if (!rect.left && !rect.right) result.bogus = true; + return result; + } + + function clearLineMeasurementCacheFor(lineView) { + if (lineView.measure) { + lineView.measure.cache = {}; + lineView.measure.heights = null; + if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) + lineView.measure.caches[i] = {}; + } + } + + function clearLineMeasurementCache(cm) { + cm.display.externalMeasure = null; + removeChildren(cm.display.lineMeasure); + for (var i = 0; i < cm.display.view.length; i++) + clearLineMeasurementCacheFor(cm.display.view[i]); + } + + function clearCaches(cm) { + clearLineMeasurementCache(cm); + cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; + if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; + cm.display.lineNumChars = null; + } + + function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } + function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } + + // Converts a {top, bottom, left, right} box from line-local + // coordinates into another coordinate system. Context may be one of + // "line", "div" (display.lineDiv), "local"/null (editor), or "page". + function intoCoordSystem(cm, lineObj, rect, context) { + if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { + var size = widgetHeight(lineObj.widgets[i]); + rect.top += size; rect.bottom += size; + } + if (context == "line") return rect; + if (!context) context = "local"; + var yOff = heightAtLine(lineObj); + if (context == "local") yOff += paddingTop(cm.display); + else yOff -= cm.display.viewOffset; + if (context == "page" || context == "window") { + var lOff = cm.display.lineSpace.getBoundingClientRect(); + yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); + var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); + rect.left += xOff; rect.right += xOff; + } + rect.top += yOff; rect.bottom += yOff; + return rect; + } + + // Coverts a box from "div" coords to another coordinate system. + // Context may be "window", "page", "div", or "local"/null. + function fromCoordSystem(cm, coords, context) { + if (context == "div") return coords; + var left = coords.left, top = coords.top; + // First move into "page" coordinate system + if (context == "page") { + left -= pageScrollX(); + top -= pageScrollY(); + } else if (context == "local" || !context) { + var localBox = cm.display.sizer.getBoundingClientRect(); + left += localBox.left; + top += localBox.top; + } + + var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); + return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; + } + + function charCoords(cm, pos, context, lineObj, bias) { + if (!lineObj) lineObj = getLine(cm.doc, pos.line); + return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); + } + + // Returns a box for a given cursor position, which may have an + // 'other' property containing the position of the secondary cursor + // on a bidi boundary. + function cursorCoords(cm, pos, context, lineObj, preparedMeasure) { + lineObj = lineObj || getLine(cm.doc, pos.line); + if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); + function get(ch, right) { + var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left"); + if (right) m.left = m.right; else m.right = m.left; + return intoCoordSystem(cm, lineObj, m, context); + } + function getBidi(ch, partPos) { + var part = order[partPos], right = part.level % 2; + if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { + part = order[--partPos]; + ch = bidiRight(part) - (part.level % 2 ? 0 : 1); + right = true; + } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { + part = order[++partPos]; + ch = bidiLeft(part) - part.level % 2; + right = false; + } + if (right && ch == part.to && ch > part.from) return get(ch - 1); + return get(ch, right); + } + var order = getOrder(lineObj), ch = pos.ch; + if (!order) return get(ch); + var partPos = getBidiPartAt(order, ch); + var val = getBidi(ch, partPos); + if (bidiOther != null) val.other = getBidi(ch, bidiOther); + return val; + } + + // Used to cheaply estimate the coordinates for a position. Used for + // intermediate scroll updates. + function estimateCoords(cm, pos) { + var left = 0, pos = clipPos(cm.doc, pos); + if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; + var lineObj = getLine(cm.doc, pos.line); + var top = heightAtLine(lineObj) + paddingTop(cm.display); + return {left: left, right: left, top: top, bottom: top + lineObj.height}; + } + + // Positions returned by coordsChar contain some extra information. + // xRel is the relative x position of the input coordinates compared + // to the found position (so xRel > 0 means the coordinates are to + // the right of the character position, for example). When outside + // is true, that means the coordinates lie outside the line's + // vertical range. + function PosWithInfo(line, ch, outside, xRel) { + var pos = Pos(line, ch); + pos.xRel = xRel; + if (outside) pos.outside = true; + return pos; + } + + // Compute the character position closest to the given coordinates. + // Input must be lineSpace-local ("div" coordinate system). + function coordsChar(cm, x, y) { + var doc = cm.doc; + y += cm.display.viewOffset; + if (y < 0) return PosWithInfo(doc.first, 0, true, -1); + var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; + if (lineN > last) + return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); + if (x < 0) x = 0; + + var lineObj = getLine(doc, lineN); + for (;;) { + var found = coordsCharInner(cm, lineObj, lineN, x, y); + var merged = collapsedSpanAtEnd(lineObj); + var mergedPos = merged && merged.find(0, true); + if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) + lineN = lineNo(lineObj = mergedPos.to.line); + else + return found; + } + } + + function coordsCharInner(cm, lineObj, lineNo, x, y) { + var innerOff = y - heightAtLine(lineObj); + var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; + var preparedMeasure = prepareMeasureForLine(cm, lineObj); + + function getX(ch) { + var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); + wrongLine = true; + if (innerOff > sp.bottom) return sp.left - adjust; + else if (innerOff < sp.top) return sp.left + adjust; + else wrongLine = false; + return sp.left; + } + + var bidi = getOrder(lineObj), dist = lineObj.text.length; + var from = lineLeft(lineObj), to = lineRight(lineObj); + var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; + + if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); + // Do a binary search between these bounds. + for (;;) { + if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { + var ch = x < fromX || x - fromX <= toX - x ? from : to; + var xDiff = x - (ch == from ? fromX : toX); + while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; + var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, + xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); + return pos; + } + var step = Math.ceil(dist / 2), middle = from + step; + if (bidi) { + middle = from; + for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); + } + var middleX = getX(middle); + if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} + else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} + } + } + + var measureText; + // Compute the default text height. + function textHeight(display) { + if (display.cachedTextHeight != null) return display.cachedTextHeight; + if (measureText == null) { + measureText = elt("pre"); + // Measure a bunch of lines, for browsers that compute + // fractional heights. + for (var i = 0; i < 49; ++i) { + measureText.appendChild(document.createTextNode("x")); + measureText.appendChild(elt("br")); + } + measureText.appendChild(document.createTextNode("x")); + } + removeChildrenAndAdd(display.measure, measureText); + var height = measureText.offsetHeight / 50; + if (height > 3) display.cachedTextHeight = height; + removeChildren(display.measure); + return height || 1; + } + + // Compute the default character width. + function charWidth(display) { + if (display.cachedCharWidth != null) return display.cachedCharWidth; + var anchor = elt("span", "xxxxxxxxxx"); + var pre = elt("pre", [anchor]); + removeChildrenAndAdd(display.measure, pre); + var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; + if (width > 2) display.cachedCharWidth = width; + return width || 10; + } + + // OPERATIONS + + // Operations are used to wrap a series of changes to the editor + // state in such a way that each change won't have to update the + // cursor and display (which would be awkward, slow, and + // error-prone). Instead, display updates are batched and then all + // combined and executed at once. + + var nextOpId = 0; + // Start a new operation. + function startOperation(cm) { + cm.curOp = { + viewChanged: false, // Flag that indicates that lines might need to be redrawn + startHeight: cm.doc.height, // Used to detect need to update scrollbar + forceUpdate: false, // Used to force a redraw + updateInput: null, // Whether to reset the input textarea + typing: false, // Whether this reset should be careful to leave existing text (for compositing) + changeObjs: null, // Accumulated changes, for firing change events + cursorActivity: false, // Whether to fire a cursorActivity event + selectionChanged: false, // Whether the selection needs to be redrawn + updateMaxLine: false, // Set when the widest line needs to be determined anew + scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet + scrollToPos: null, // Used to scroll to a specific position + id: ++nextOpId // Unique ID + }; + if (!delayedCallbackDepth++) delayedCallbacks = []; + } + + // Finish an operation, updating the display and signalling delayed events + function endOperation(cm) { + var op = cm.curOp, doc = cm.doc, display = cm.display; + cm.curOp = null; + + if (op.updateMaxLine) findMaxLine(cm); + + // If it looks like an update might be needed, call updateDisplay + if (op.viewChanged || op.forceUpdate || op.scrollTop != null || + op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || + op.scrollToPos.to.line >= display.viewTo) || + display.maxLineChanged && cm.options.lineWrapping) { + var updated = updateDisplay(cm, {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); + if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop; + } + // If no update was run, but the selection changed, redraw that. + if (!updated && op.selectionChanged) updateSelection(cm); + if (!updated && op.startHeight != cm.doc.height) updateScrollbars(cm); + + // Propagate the scroll position to the actual DOM scroller + if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) { + var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); + display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top; + } + if (op.scrollLeft != null && display.scroller.scrollLeft != op.scrollLeft) { + var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft)); + display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left; + alignHorizontally(cm); + } + // If we need to scroll a specific position into view, do so. + if (op.scrollToPos) { + var coords = scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from), + clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin); + if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); + } + + if (op.selectionChanged) restartBlink(cm); + + if (cm.state.focused && op.updateInput) + resetInput(cm, op.typing); + + // Fire events for markers that are hidden/unidden by editing or + // undoing + var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; + if (hidden) for (var i = 0; i < hidden.length; ++i) + if (!hidden[i].lines.length) signal(hidden[i], "hide"); + if (unhidden) for (var i = 0; i < unhidden.length; ++i) + if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); + + var delayed; + if (!--delayedCallbackDepth) { + delayed = delayedCallbacks; + delayedCallbacks = null; + } + // Fire change events, and delayed event handlers + if (op.changeObjs) { + for (var i = 0; i < op.changeObjs.length; i++) + signal(cm, "change", cm, op.changeObjs[i]); + signal(cm, "changes", cm, op.changeObjs); + } + if (op.cursorActivity) signal(cm, "cursorActivity", cm); + if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i](); + } + + // Run the given function in an operation + function runInOp(cm, f) { + if (cm.curOp) return f(); + startOperation(cm); + try { return f(); } + finally { endOperation(cm); } + } + // Wraps a function in an operation. Returns the wrapped function. + function operation(cm, f) { + return function() { + if (cm.curOp) return f.apply(cm, arguments); + startOperation(cm); + try { return f.apply(cm, arguments); } + finally { endOperation(cm); } + }; + } + // Used to add methods to editor and doc instances, wrapping them in + // operations. + function methodOp(f) { + return function() { + if (this.curOp) return f.apply(this, arguments); + startOperation(this); + try { return f.apply(this, arguments); } + finally { endOperation(this); } + }; + } + function docMethodOp(f) { + return function() { + var cm = this.cm; + if (!cm || cm.curOp) return f.apply(this, arguments); + startOperation(cm); + try { return f.apply(this, arguments); } + finally { endOperation(cm); } + }; + } + + // VIEW TRACKING + + // These objects are used to represent the visible (currently drawn) + // part of the document. A LineView may correspond to multiple + // logical lines, if those are connected by collapsed ranges. + function LineView(doc, line, lineN) { + // The starting line + this.line = line; + // Continuing lines, if any + this.rest = visualLineContinued(line); + // Number of logical lines in this visual line + this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; + this.node = this.text = null; + this.hidden = lineIsHidden(doc, line); + } + + // Create a range of LineView objects for the given lines. + function buildViewArray(cm, from, to) { + var array = [], nextPos; + for (var pos = from; pos < to; pos = nextPos) { + var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); + nextPos = pos + view.size; + array.push(view); + } + return array; + } + + // Updates the display.view data structure for a given change to the + // document. From and to are in pre-change coordinates. Lendiff is + // the amount of lines added or subtracted by the change. This is + // used for changes that span multiple lines, or change the way + // lines are divided into visual lines. regLineChange (below) + // registers single-line changes. + function regChange(cm, from, to, lendiff) { + if (from == null) from = cm.doc.first; + if (to == null) to = cm.doc.first + cm.doc.size; + if (!lendiff) lendiff = 0; + + var display = cm.display; + if (lendiff && to < display.viewTo && + (display.updateLineNumbers == null || display.updateLineNumbers > from)) + display.updateLineNumbers = from; + + cm.curOp.viewChanged = true; + + if (from >= display.viewTo) { // Change after + if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) + resetView(cm); + } else if (to <= display.viewFrom) { // Change before + if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { + resetView(cm); + } else { + display.viewFrom += lendiff; + display.viewTo += lendiff; + } + } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap + resetView(cm); + } else if (from <= display.viewFrom) { // Top overlap + var cut = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cut) { + display.view = display.view.slice(cut.index); + display.viewFrom = cut.lineN; + display.viewTo += lendiff; + } else { + resetView(cm); + } + } else if (to >= display.viewTo) { // Bottom overlap + var cut = viewCuttingPoint(cm, from, from, -1); + if (cut) { + display.view = display.view.slice(0, cut.index); + display.viewTo = cut.lineN; + } else { + resetView(cm); + } + } else { // Gap in the middle + var cutTop = viewCuttingPoint(cm, from, from, -1); + var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); + if (cutTop && cutBot) { + display.view = display.view.slice(0, cutTop.index) + .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) + .concat(display.view.slice(cutBot.index)); + display.viewTo += lendiff; + } else { + resetView(cm); + } + } + + var ext = display.externalMeasured; + if (ext) { + if (to < ext.lineN) + ext.lineN += lendiff; + else if (from < ext.lineN + ext.size) + display.externalMeasured = null; + } + } + + // Register a change to a single line. Type must be one of "text", + // "gutter", "class", "widget" + function regLineChange(cm, line, type) { + cm.curOp.viewChanged = true; + var display = cm.display, ext = cm.display.externalMeasured; + if (ext && line >= ext.lineN && line < ext.lineN + ext.size) + display.externalMeasured = null; + + if (line < display.viewFrom || line >= display.viewTo) return; + var lineView = display.view[findViewIndex(cm, line)]; + if (lineView.node == null) return; + var arr = lineView.changes || (lineView.changes = []); + if (indexOf(arr, type) == -1) arr.push(type); + } + + // Clear the view. + function resetView(cm) { + cm.display.viewFrom = cm.display.viewTo = cm.doc.first; + cm.display.view = []; + cm.display.viewOffset = 0; + } + + // Find the view element corresponding to a given line. Return null + // when the line isn't visible. + function findViewIndex(cm, n) { + if (n >= cm.display.viewTo) return null; + n -= cm.display.viewFrom; + if (n < 0) return null; + var view = cm.display.view; + for (var i = 0; i < view.length; i++) { + n -= view[i].size; + if (n < 0) return i; + } + } + + function viewCuttingPoint(cm, oldN, newN, dir) { + var index = findViewIndex(cm, oldN), diff, view = cm.display.view; + if (!sawCollapsedSpans) return {index: index, lineN: newN}; + for (var i = 0, n = cm.display.viewFrom; i < index; i++) + n += view[i].size; + if (n != oldN) { + if (dir > 0) { + if (index == view.length - 1) return null; + diff = (n + view[index].size) - oldN; + index++; + } else { + diff = n - oldN; + } + oldN += diff; newN += diff; + } + while (visualLineNo(cm.doc, newN) != newN) { + if (index == (dir < 0 ? 0 : view.length - 1)) return null; + newN += dir * view[index - (dir < 0 ? 1 : 0)].size; + index += dir; + } + return {index: index, lineN: newN}; + } + + // Force the view to cover a given range, adding empty view element + // or clipping off existing ones as needed. + function adjustView(cm, from, to) { + var display = cm.display, view = display.view; + if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { + display.view = buildViewArray(cm, from, to); + display.viewFrom = from; + } else { + if (display.viewFrom > from) + display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); + else if (display.viewFrom < from) + display.view = display.view.slice(findViewIndex(cm, from)); + display.viewFrom = from; + if (display.viewTo < to) + display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); + else if (display.viewTo > to) + display.view = display.view.slice(0, findViewIndex(cm, to)); + } + display.viewTo = to; + } + + // Count the number of lines in the view whose DOM representation is + // out of date (or nonexistent). + function countDirtyView(cm) { + var view = cm.display.view, dirty = 0; + for (var i = 0; i < view.length; i++) { + var lineView = view[i]; + if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; + } + return dirty; + } + + // INPUT HANDLING + + // Poll for input changes, using the normal rate of polling. This + // runs as long as the editor is focused. + function slowPoll(cm) { + if (cm.display.pollingFast) return; + cm.display.poll.set(cm.options.pollInterval, function() { + readInput(cm); + if (cm.state.focused) slowPoll(cm); + }); + } + + // When an event has just come in that is likely to add or change + // something in the input textarea, we poll faster, to ensure that + // the change appears on the screen quickly. + function fastPoll(cm) { + var missed = false; + cm.display.pollingFast = true; + function p() { + var changed = readInput(cm); + if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);} + else {cm.display.pollingFast = false; slowPoll(cm);} + } + cm.display.poll.set(20, p); + } + + // Read input from the textarea, and update the document to match. + // When something is selected, it is present in the textarea, and + // selected (unless it is huge, in which case a placeholder is + // used). When nothing is selected, the cursor sits after previously + // seen text (can be empty), which is stored in prevInput (we must + // not reset the textarea when typing, because that breaks IME). + function readInput(cm) { + var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc; + // Since this is called a *lot*, try to bail out as cheaply as + // possible when it is clear that nothing happened. hasSelection + // will be the case when there is a lot of text in the textarea, + // in which case reading its value would be expensive. + if (!cm.state.focused || hasSelection(input) || isReadOnly(cm) || cm.options.disableInput) return false; + var text = input.value; + // If nothing changed, bail. + if (text == prevInput && !cm.somethingSelected()) return false; + // Work around nonsensical selection resetting in IE9/10 + if (ie && !ie_upto8 && cm.display.inputHasSelection === text) { + resetInput(cm); + return false; + } + + var withOp = !cm.curOp; + if (withOp) startOperation(cm); + cm.display.shift = false; + + // Find the part of the input that is actually new + var same = 0, l = Math.min(prevInput.length, text.length); + while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; + var inserted = text.slice(same), textLines = splitLines(inserted); + + // When pasing N lines into N selections, insert one line per selection + var multiPaste = cm.state.pasteIncoming && textLines.length > 1 && doc.sel.ranges.length == textLines.length; + + // Normal behavior is to insert the new text into every selection + for (var i = doc.sel.ranges.length - 1; i >= 0; i--) { + var range = doc.sel.ranges[i]; + var from = range.from(), to = range.to(); + // Handle deletion + if (same < prevInput.length) + from = Pos(from.line, from.ch - (prevInput.length - same)); + // Handle overwrite + else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming) + to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); + var updateInput = cm.curOp.updateInput; + var changeEvent = {from: from, to: to, text: multiPaste ? [textLines[i]] : textLines, + origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"}; + makeChange(cm.doc, changeEvent); + signalLater(cm, "inputRead", cm, changeEvent); + // When an 'electric' character is inserted, immediately trigger a reindent + if (inserted && !cm.state.pasteIncoming && cm.options.electricChars && + cm.options.smartIndent && range.head.ch < 100 && + (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) { + var electric = cm.getModeAt(range.head).electricChars; + if (electric) for (var j = 0; j < electric.length; j++) + if (inserted.indexOf(electric.charAt(j)) > -1) { + indentLine(cm, range.head.line, "smart"); + break; + } + } + } + ensureCursorVisible(cm); + cm.curOp.updateInput = updateInput; + cm.curOp.typing = true; + + // Don't leave long text in the textarea, since it makes further polling slow + if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = ""; + else cm.display.prevInput = text; + if (withOp) endOperation(cm); + cm.state.pasteIncoming = cm.state.cutIncoming = false; + return true; + } + + // Reset the input to correspond to the selection (or to be empty, + // when not typing and nothing is selected) + function resetInput(cm, typing) { + var minimal, selected, doc = cm.doc; + if (cm.somethingSelected()) { + cm.display.prevInput = ""; + var range = doc.sel.primary(); + minimal = hasCopyEvent && + (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); + var content = minimal ? "-" : selected || cm.getSelection(); + cm.display.input.value = content; + if (cm.state.focused) selectInput(cm.display.input); + if (ie && !ie_upto8) cm.display.inputHasSelection = content; + } else if (!typing) { + cm.display.prevInput = cm.display.input.value = ""; + if (ie && !ie_upto8) cm.display.inputHasSelection = null; + } + cm.display.inaccurateSelection = minimal; + } + + function focusInput(cm) { + if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input)) + cm.display.input.focus(); + } + + function ensureFocus(cm) { + if (!cm.state.focused) { focusInput(cm); onFocus(cm); } + } + + function isReadOnly(cm) { + return cm.options.readOnly || cm.doc.cantEdit; + } + + // EVENT HANDLERS + + // Attach the necessary event handlers when initializing the editor + function registerEventHandlers(cm) { + var d = cm.display; + on(d.scroller, "mousedown", operation(cm, onMouseDown)); + // Older IE's will not fire a second mousedown for a double click + if (ie_upto10) + on(d.scroller, "dblclick", operation(cm, function(e) { + if (signalDOMEvent(cm, e)) return; + var pos = posFromMouse(cm, e); + if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; + e_preventDefault(e); + var word = findWordAt(cm.doc, pos); + extendSelection(cm.doc, word.anchor, word.head); + })); + else + on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); + // Prevent normal selection in the editor (we handle our own) + on(d.lineSpace, "selectstart", function(e) { + if (!eventInWidget(d, e)) e_preventDefault(e); + }); + // Some browsers fire contextmenu *after* opening the menu, at + // which point we can't mess with it anymore. Context menu is + // handled in onMouseDown for these browsers. + if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); + + // Sync scrolling between fake scrollbars and real scrollable + // area, ensure viewport is updated when scrolling. + on(d.scroller, "scroll", function() { + if (d.scroller.clientHeight) { + setScrollTop(cm, d.scroller.scrollTop); + setScrollLeft(cm, d.scroller.scrollLeft, true); + signal(cm, "scroll", cm); + } + }); + on(d.scrollbarV, "scroll", function() { + if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop); + }); + on(d.scrollbarH, "scroll", function() { + if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft); + }); + + // Listen to wheel events in order to try and update the viewport on time. + on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); + on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); + + // Prevent clicks in the scrollbars from killing focus + function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); } + on(d.scrollbarH, "mousedown", reFocus); + on(d.scrollbarV, "mousedown", reFocus); + // Prevent wrapper from ever scrolling + on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); + + // When the window resizes, we need to refresh active editors. + var resizeTimer; + function onResize() { + if (resizeTimer == null) resizeTimer = setTimeout(function() { + resizeTimer = null; + // Might be a text scaling operation, clear size caches. + d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = knownScrollbarWidth = null; + cm.setSize(); + }, 100); + } + on(window, "resize", onResize); + // The above handler holds on to the editor and its data + // structures. Here we poll to unregister it when the editor is no + // longer in the document, so that it can be garbage-collected. + function unregister() { + if (contains(document.body, d.wrapper)) setTimeout(unregister, 5000); + else off(window, "resize", onResize); + } + setTimeout(unregister, 5000); + + on(d.input, "keyup", operation(cm, onKeyUp)); + on(d.input, "input", function() { + if (ie && !ie_upto8 && cm.display.inputHasSelection) cm.display.inputHasSelection = null; + fastPoll(cm); + }); + on(d.input, "keydown", operation(cm, onKeyDown)); + on(d.input, "keypress", operation(cm, onKeyPress)); + on(d.input, "focus", bind(onFocus, cm)); + on(d.input, "blur", bind(onBlur, cm)); + + function drag_(e) { + if (!signalDOMEvent(cm, e)) e_stop(e); + } + if (cm.options.dragDrop) { + on(d.scroller, "dragstart", function(e){onDragStart(cm, e);}); + on(d.scroller, "dragenter", drag_); + on(d.scroller, "dragover", drag_); + on(d.scroller, "drop", operation(cm, onDrop)); + } + on(d.scroller, "paste", function(e) { + if (eventInWidget(d, e)) return; + cm.state.pasteIncoming = true; + focusInput(cm); + fastPoll(cm); + }); + on(d.input, "paste", function() { + cm.state.pasteIncoming = true; + fastPoll(cm); + }); + + function prepareCopy(e) { + if (d.inaccurateSelection) { + d.prevInput = ""; + d.inaccurateSelection = false; + d.input.value = cm.getSelection(); + selectInput(d.input); + } + if (e.type == "cut") cm.state.cutIncoming = true; + } + on(d.input, "cut", prepareCopy); + on(d.input, "copy", prepareCopy); + + // Needed to handle Tab key in KHTML + if (khtml) on(d.sizer, "mouseup", function() { + if (activeElt() == d.input) d.input.blur(); + focusInput(cm); + }); + } + + // MOUSE EVENTS + + // Return true when the given mouse event happened in a widget + function eventInWidget(display, e) { + for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { + if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true; + } + } + + // Given a mouse event, find the corresponding position. If liberal + // is false, it checks whether a gutter or scrollbar was clicked, + // and returns null if it was. forRect is used by rectangular + // selections, and tries to estimate a character position even for + // coordinates beyond the right of the text. + function posFromMouse(cm, e, liberal, forRect) { + var display = cm.display; + if (!liberal) { + var target = e_target(e); + if (target == display.scrollbarH || target == display.scrollbarV || + target == display.scrollbarFiller || target == display.gutterFiller) return null; + } + var x, y, space = display.lineSpace.getBoundingClientRect(); + // Fails unpredictably on IE[67] when mouse is dragged around quickly. + try { x = e.clientX - space.left; y = e.clientY - space.top; } + catch (e) { return null; } + var coords = coordsChar(cm, x, y), line; + if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { + var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; + coords = Pos(coords.line, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff); + } + return coords; + } + + // A mouse down can be a single click, double click, triple click, + // start of selection drag, start of text drag, new cursor + // (ctrl-click), rectangle drag (alt-drag), or xwin + // middle-click-paste. Or it might be a click on something we should + // not interfere with, such as a scrollbar or widget. + function onMouseDown(e) { + if (signalDOMEvent(this, e)) return; + var cm = this, display = cm.display; + display.shift = e.shiftKey; + + if (eventInWidget(display, e)) { + if (!webkit) { + // Briefly turn off draggability, to allow widgets to do + // normal dragging things. + display.scroller.draggable = false; + setTimeout(function(){display.scroller.draggable = true;}, 100); + } + return; + } + if (clickInGutter(cm, e)) return; + var start = posFromMouse(cm, e); + window.focus(); + + switch (e_button(e)) { + case 1: + if (start) + leftButtonDown(cm, e, start); + else if (e_target(e) == display.scroller) + e_preventDefault(e); + break; + case 2: + if (webkit) cm.state.lastMiddleDown = +new Date; + if (start) extendSelection(cm.doc, start); + setTimeout(bind(focusInput, cm), 20); + e_preventDefault(e); + break; + case 3: + if (captureRightClick) onContextMenu(cm, e); + break; + } + } + + var lastClick, lastDoubleClick; + function leftButtonDown(cm, e, start) { + setTimeout(bind(ensureFocus, cm), 0); + + var now = +new Date, type; + if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { + type = "triple"; + } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { + type = "double"; + lastDoubleClick = {time: now, pos: start}; + } else { + type = "single"; + lastClick = {time: now, pos: start}; + } + + var sel = cm.doc.sel, addNew = mac ? e.metaKey : e.ctrlKey; + if (cm.options.dragDrop && dragAndDrop && !addNew && !isReadOnly(cm) && + type == "single" && sel.contains(start) > -1 && sel.somethingSelected()) + leftButtonStartDrag(cm, e, start); + else + leftButtonSelect(cm, e, start, type, addNew); + } + + // Start a text drag. When it ends, see if any dragging actually + // happen, and treat as a click if it didn't. + function leftButtonStartDrag(cm, e, start) { + var display = cm.display; + var dragEnd = operation(cm, function(e2) { + if (webkit) display.scroller.draggable = false; + cm.state.draggingText = false; + off(document, "mouseup", dragEnd); + off(display.scroller, "drop", dragEnd); + if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { + e_preventDefault(e2); + extendSelection(cm.doc, start); + focusInput(cm); + // Work around unexplainable focus problem in IE9 (#2127) + if (ie_upto10 && !ie_upto8) + setTimeout(function() {document.body.focus(); focusInput(cm);}, 20); + } + }); + // Let the drag handler handle this. + if (webkit) display.scroller.draggable = true; + cm.state.draggingText = dragEnd; + // IE's approach to draggable + if (display.scroller.dragDrop) display.scroller.dragDrop(); + on(document, "mouseup", dragEnd); + on(display.scroller, "drop", dragEnd); + } + + // Normal selection, as opposed to text dragging. + function leftButtonSelect(cm, e, start, type, addNew) { + var display = cm.display, doc = cm.doc; + e_preventDefault(e); + + var ourRange, ourIndex, startSel = doc.sel; + if (addNew) { + ourIndex = doc.sel.contains(start); + if (ourIndex > -1) + ourRange = doc.sel.ranges[ourIndex]; + else + ourRange = new Range(start, start); + } else { + ourRange = doc.sel.primary(); + } + + if (e.altKey) { + type = "rect"; + if (!addNew) ourRange = new Range(start, start); + start = posFromMouse(cm, e, true, true); + ourIndex = -1; + } else if (type == "double") { + var word = findWordAt(doc, start); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, word.anchor, word.head); + else + ourRange = word; + } else if (type == "triple") { + var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); + if (cm.display.shift || doc.extend) + ourRange = extendRange(doc, ourRange, line.anchor, line.head); + else + ourRange = line; + } else { + ourRange = extendRange(doc, ourRange, start); + } + + if (!addNew) { + ourIndex = 0; + setSelection(doc, new Selection([ourRange], 0), sel_mouse); + } else if (ourIndex > -1) { + replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); + } else { + ourIndex = doc.sel.ranges.length; + setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex), + {scroll: false, origin: "*mouse"}); + } + + var lastPos = start; + function extendTo(pos) { + if (cmp(lastPos, pos) == 0) return; + lastPos = pos; + + if (type == "rect") { + var ranges = [], tabSize = cm.options.tabSize; + var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); + var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); + var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); + for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); + line <= end; line++) { + var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); + if (left == right) + ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); + else if (text.length > leftPos) + ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); + } + if (!ranges.length) ranges.push(new Range(start, start)); + setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), sel_mouse); + } else { + var oldRange = ourRange; + var anchor = oldRange.anchor, head = pos; + if (type != "single") { + if (type == "double") + var range = findWordAt(doc, pos); + else + var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); + if (cmp(range.anchor, anchor) > 0) { + head = range.head; + anchor = minPos(oldRange.from(), range.anchor); + } else { + head = range.anchor; + anchor = maxPos(oldRange.to(), range.head); + } + } + var ranges = startSel.ranges.slice(0); + ranges[ourIndex] = new Range(clipPos(doc, anchor), head); + setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); + } + } + + var editorSize = display.wrapper.getBoundingClientRect(); + // Used to ensure timeout re-tries don't fire when another extend + // happened in the meantime (clearTimeout isn't reliable -- at + // least on Chrome, the timeouts still happen even when cleared, + // if the clear happens after their scheduled firing time). + var counter = 0; + + function extend(e) { + var curCount = ++counter; + var cur = posFromMouse(cm, e, true, type == "rect"); + if (!cur) return; + if (cmp(cur, lastPos) != 0) { + ensureFocus(cm); + extendTo(cur); + var visible = visibleLines(display, doc); + if (cur.line >= visible.to || cur.line < visible.from) + setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); + } else { + var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; + if (outside) setTimeout(operation(cm, function() { + if (counter != curCount) return; + display.scroller.scrollTop += outside; + extend(e); + }), 50); + } + } + + function done(e) { + counter = Infinity; + e_preventDefault(e); + focusInput(cm); + off(document, "mousemove", move); + off(document, "mouseup", up); + doc.history.lastSelOrigin = null; + } + + var move = operation(cm, function(e) { + if ((ie && !ie_upto9) ? !e.buttons : !e_button(e)) done(e); + else extend(e); + }); + var up = operation(cm, done); + on(document, "mousemove", move); + on(document, "mouseup", up); + } + + // Determines whether an event happened in the gutter, and fires the + // handlers for the corresponding event. + function gutterEvent(cm, e, type, prevent, signalfn) { + try { var mX = e.clientX, mY = e.clientY; } + catch(e) { return false; } + if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; + if (prevent) e_preventDefault(e); + + var display = cm.display; + var lineBox = display.lineDiv.getBoundingClientRect(); + + if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); + mY -= lineBox.top - display.viewOffset; + + for (var i = 0; i < cm.options.gutters.length; ++i) { + var g = display.gutters.childNodes[i]; + if (g && g.getBoundingClientRect().right >= mX) { + var line = lineAtHeight(cm.doc, mY); + var gutter = cm.options.gutters[i]; + signalfn(cm, type, cm, line, gutter, e); + return e_defaultPrevented(e); + } + } + } + + function clickInGutter(cm, e) { + return gutterEvent(cm, e, "gutterClick", true, signalLater); + } + + // Kludge to work around strange IE behavior where it'll sometimes + // re-fire a series of drag-related events right after the drop (#1551) + var lastDrop = 0; + + function onDrop(e) { + var cm = this; + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) + return; + e_preventDefault(e); + if (ie_upto10) lastDrop = +new Date; + var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; + if (!pos || isReadOnly(cm)) return; + // Might be a file drop, in which case we simply extract the text + // and insert it. + if (files && files.length && window.FileReader && window.File) { + var n = files.length, text = Array(n), read = 0; + var loadFile = function(file, i) { + var reader = new FileReader; + reader.onload = function() { + text[i] = reader.result; + if (++read == n) { + pos = clipPos(cm.doc, pos); + var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}; + makeChange(cm.doc, change); + setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); + } + }; + reader.readAsText(file); + }; + for (var i = 0; i < n; ++i) loadFile(files[i], i); + } else { // Normal drop + // Don't do a replace if the drop happened inside of the selected text. + if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { + cm.state.draggingText(e); + // Ensure the editor is re-focused + setTimeout(bind(focusInput, cm), 20); + return; + } + try { + var text = e.dataTransfer.getData("Text"); + if (text) { + var selected = cm.state.draggingText && cm.listSelections(); + setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); + if (selected) for (var i = 0; i < selected.length; ++i) + replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); + cm.replaceSelection(text, "around", "paste"); + focusInput(cm); + } + } + catch(e){} + } + } + + function onDragStart(cm, e) { + if (ie_upto10 && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } + if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; + + e.dataTransfer.setData("Text", cm.getSelection()); + + // Use dummy image instead of default browsers image. + // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. + if (e.dataTransfer.setDragImage && !safari) { + var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); + img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; + if (presto) { + img.width = img.height = 1; + cm.display.wrapper.appendChild(img); + // Force a relayout, or Opera won't use our image for some obscure reason + img._top = img.offsetTop; + } + e.dataTransfer.setDragImage(img, 0, 0); + if (presto) img.parentNode.removeChild(img); + } + } + + // SCROLL EVENTS + + // Sync the scrollable area and scrollbars, ensure the viewport + // covers the visible area. + function setScrollTop(cm, val) { + if (Math.abs(cm.doc.scrollTop - val) < 2) return; + cm.doc.scrollTop = val; + if (!gecko) updateDisplay(cm, {top: val}); + if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; + if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val; + if (gecko) updateDisplay(cm); + startWorker(cm, 100); + } + // Sync scroller and scrollbar, ensure the gutter elements are + // aligned. + function setScrollLeft(cm, val, isScroller) { + if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; + val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); + cm.doc.scrollLeft = val; + alignHorizontally(cm); + if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; + if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val; + } + + // Since the delta values reported on mouse wheel events are + // unstandardized between browsers and even browser versions, and + // generally horribly unpredictable, this code starts by measuring + // the scroll effect that the first few mouse wheel events have, + // and, from that, detects the way it can convert deltas to pixel + // offsets afterwards. + // + // The reason we want to know the amount a wheel event will scroll + // is that it gives us a chance to update the display before the + // actual scrolling happens, reducing flickering. + + var wheelSamples = 0, wheelPixelsPerUnit = null; + // Fill in a browser-detected starting value on browsers where we + // know one. These don't have to be accurate -- the result of them + // being wrong would just be a slight flicker on the first wheel + // scroll (if it is large enough). + if (ie) wheelPixelsPerUnit = -.53; + else if (gecko) wheelPixelsPerUnit = 15; + else if (chrome) wheelPixelsPerUnit = -.7; + else if (safari) wheelPixelsPerUnit = -1/3; + + function onScrollWheel(cm, e) { + var dx = e.wheelDeltaX, dy = e.wheelDeltaY; + if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; + if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; + else if (dy == null) dy = e.wheelDelta; + + var display = cm.display, scroll = display.scroller; + // Quit if there's nothing to scroll here + if (!(dx && scroll.scrollWidth > scroll.clientWidth || + dy && scroll.scrollHeight > scroll.clientHeight)) return; + + // Webkit browsers on OS X abort momentum scrolls when the target + // of the scroll event is removed from the scrollable element. + // This hack (see related code in patchDisplay) makes sure the + // element is kept around. + if (dy && mac && webkit) { + outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { + for (var i = 0; i < view.length; i++) { + if (view[i].node == cur) { + cm.display.currentWheelTarget = cur; + break outer; + } + } + } + } + + // On some browsers, horizontal scrolling will cause redraws to + // happen before the gutter has been realigned, causing it to + // wriggle around in a most unseemly way. When we have an + // estimated pixels/delta value, we just handle horizontal + // scrolling entirely here. It'll be slightly off from native, but + // better than glitching out. + if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { + if (dy) + setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); + setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); + e_preventDefault(e); + display.wheelStartX = null; // Abort measurement, if in progress + return; + } + + // 'Project' the visible viewport to cover the area that is being + // scrolled into view (if we know enough to estimate it). + if (dy && wheelPixelsPerUnit != null) { + var pixels = dy * wheelPixelsPerUnit; + var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; + if (pixels < 0) top = Math.max(0, top + pixels - 50); + else bot = Math.min(cm.doc.height, bot + pixels + 50); + updateDisplay(cm, {top: top, bottom: bot}); + } + + if (wheelSamples < 20) { + if (display.wheelStartX == null) { + display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; + display.wheelDX = dx; display.wheelDY = dy; + setTimeout(function() { + if (display.wheelStartX == null) return; + var movedX = scroll.scrollLeft - display.wheelStartX; + var movedY = scroll.scrollTop - display.wheelStartY; + var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || + (movedX && display.wheelDX && movedX / display.wheelDX); + display.wheelStartX = display.wheelStartY = null; + if (!sample) return; + wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); + ++wheelSamples; + }, 200); + } else { + display.wheelDX += dx; display.wheelDY += dy; + } + } + } + + // KEY EVENTS + + // Run a handler that was bound to a key. + function doHandleBinding(cm, bound, dropShift) { + if (typeof bound == "string") { + bound = commands[bound]; + if (!bound) return false; + } + // Ensure previous input has been read, so that the handler sees a + // consistent view of the document + if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false; + var prevShift = cm.display.shift, done = false; + try { + if (isReadOnly(cm)) cm.state.suppressEdits = true; + if (dropShift) cm.display.shift = false; + done = bound(cm) != Pass; + } finally { + cm.display.shift = prevShift; + cm.state.suppressEdits = false; + } + return done; + } + + // Collect the currently active keymaps. + function allKeyMaps(cm) { + var maps = cm.state.keyMaps.slice(0); + if (cm.options.extraKeys) maps.push(cm.options.extraKeys); + maps.push(cm.options.keyMap); + return maps; + } + + var maybeTransition; + // Handle a key from the keydown event. + function handleKeyBinding(cm, e) { + // Handle automatic keymap transitions + var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto; + clearTimeout(maybeTransition); + if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() { + if (getKeyMap(cm.options.keyMap) == startMap) { + cm.options.keyMap = (next.call ? next.call(null, cm) : next); + keyMapChanged(cm); + } + }, 50); + + var name = keyName(e, true), handled = false; + if (!name) return false; + var keymaps = allKeyMaps(cm); + + if (e.shiftKey) { + // First try to resolve full name (including 'Shift-'). Failing + // that, see if there is a cursor-motion command (starting with + // 'go') bound to the keyname without 'Shift-'. + handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);}) + || lookupKey(name, keymaps, function(b) { + if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) + return doHandleBinding(cm, b); + }); + } else { + handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); }); + } + + if (handled) { + e_preventDefault(e); + restartBlink(cm); + signalLater(cm, "keyHandled", cm, name, e); + } + return handled; + } + + // Handle a key from the keypress event + function handleCharBinding(cm, e, ch) { + var handled = lookupKey("'" + ch + "'", allKeyMaps(cm), + function(b) { return doHandleBinding(cm, b, true); }); + if (handled) { + e_preventDefault(e); + restartBlink(cm); + signalLater(cm, "keyHandled", cm, "'" + ch + "'", e); + } + return handled; + } + + var lastStoppedKey = null; + function onKeyDown(e) { + var cm = this; + ensureFocus(cm); + if (signalDOMEvent(cm, e)) return; + // IE does strange things with escape. + if (ie_upto10 && e.keyCode == 27) e.returnValue = false; + var code = e.keyCode; + cm.display.shift = code == 16 || e.shiftKey; + var handled = handleKeyBinding(cm, e); + if (presto) { + lastStoppedKey = handled ? code : null; + // Opera has no cut event... we try to at least catch the key combo + if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) + cm.replaceSelection("", null, "cut"); + } + } + + function onKeyUp(e) { + if (signalDOMEvent(this, e)) return; + if (e.keyCode == 16) this.doc.sel.shift = false; + } + + function onKeyPress(e) { + var cm = this; + if (signalDOMEvent(cm, e)) return; + var keyCode = e.keyCode, charCode = e.charCode; + if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} + if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return; + var ch = String.fromCharCode(charCode == null ? keyCode : charCode); + if (handleCharBinding(cm, e, ch)) return; + if (ie && !ie_upto8) cm.display.inputHasSelection = null; + fastPoll(cm); + } + + // FOCUS/BLUR EVENTS + + function onFocus(cm) { + if (cm.options.readOnly == "nocursor") return; + if (!cm.state.focused) { + signal(cm, "focus", cm); + cm.state.focused = true; + if (cm.display.wrapper.className.search(/\bCodeMirror-focused\b/) == -1) + cm.display.wrapper.className += " CodeMirror-focused"; + if (!cm.curOp) { + resetInput(cm); + if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730 + } + } + slowPoll(cm); + restartBlink(cm); + } + function onBlur(cm) { + if (cm.state.focused) { + signal(cm, "blur", cm); + cm.state.focused = false; + cm.display.wrapper.className = cm.display.wrapper.className.replace(" CodeMirror-focused", ""); + } + clearInterval(cm.display.blinker); + setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150); + } + + // CONTEXT MENU HANDLING + + var detectingSelectAll; + // To make the context menu work, we need to briefly unhide the + // textarea (making it as unobtrusive as possible) to let the + // right-click take effect on it. + function onContextMenu(cm, e) { + if (signalDOMEvent(cm, e, "contextmenu")) return; + var display = cm.display; + if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return; + + var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; + if (!pos || presto) return; // Opera is difficult. + + // Reset the current text selection only if the click is done outside of the selection + // and 'resetSelectionOnContextMenu' option is true. + var reset = cm.options.resetSelectionOnContextMenu; + if (reset && cm.doc.sel.contains(pos) == -1) + operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); + + var oldCSS = display.input.style.cssText; + display.inputDiv.style.position = "absolute"; + display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) + + "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " + + (ie ? "rgba(255, 255, 255, .05)" : "transparent") + + "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; + focusInput(cm); + resetInput(cm); + // Adds "Select all" to context menu in FF + if (!cm.somethingSelected()) display.input.value = display.prevInput = " "; + + // Select-all will be greyed out if there's nothing to select, so + // this adds a zero-width space so that we can later check whether + // it got selected. + function prepareSelectAllHack() { + if (display.input.selectionStart != null) { + var extval = display.input.value = "\u200b" + (cm.somethingSelected() ? display.input.value : ""); + display.prevInput = "\u200b"; + display.input.selectionStart = 1; display.input.selectionEnd = extval.length; + } + } + function rehide() { + display.inputDiv.style.position = "relative"; + display.input.style.cssText = oldCSS; + if (ie_upto8) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos; + slowPoll(cm); + + // Try to detect the user choosing select-all + if (display.input.selectionStart != null) { + if (!ie || ie_upto8) prepareSelectAllHack(); + clearTimeout(detectingSelectAll); + var i = 0, poll = function(){ + if (display.prevInput == "\u200b" && display.input.selectionStart == 0) + operation(cm, commands.selectAll)(cm); + else if (i++ < 10) detectingSelectAll = setTimeout(poll, 500); + else resetInput(cm); + }; + detectingSelectAll = setTimeout(poll, 200); + } + } + + if (ie && !ie_upto8) prepareSelectAllHack(); + if (captureRightClick) { + e_stop(e); + var mouseup = function() { + off(window, "mouseup", mouseup); + setTimeout(rehide, 20); + }; + on(window, "mouseup", mouseup); + } else { + setTimeout(rehide, 50); + } + } + + function contextMenuInGutter(cm, e) { + if (!hasHandler(cm, "gutterContextMenu")) return false; + return gutterEvent(cm, e, "gutterContextMenu", false, signal); + } + + // UPDATING + + // Compute the position of the end of a change (its 'to' property + // refers to the pre-change end). + var changeEnd = CodeMirror.changeEnd = function(change) { + if (!change.text) return change.to; + return Pos(change.from.line + change.text.length - 1, + lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); + }; + + // Adjust a position to refer to the post-change position of the + // same text, or the end of the change if the change covers it. + function adjustForChange(pos, change) { + if (cmp(pos, change.from) < 0) return pos; + if (cmp(pos, change.to) <= 0) return changeEnd(change); + + var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; + if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; + return Pos(line, ch); + } + + function computeSelAfterChange(doc, change) { + var out = []; + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + out.push(new Range(adjustForChange(range.anchor, change), + adjustForChange(range.head, change))); + } + return normalizeSelection(out, doc.sel.primIndex); + } + + function offsetPos(pos, old, nw) { + if (pos.line == old.line) + return Pos(nw.line, pos.ch - old.ch + nw.ch); + else + return Pos(nw.line + (pos.line - old.line), pos.ch); + } + + // Used by replaceSelections to allow moving the selection to the + // start or around the replaced test. Hint may be "start" or "around". + function computeReplacedSel(doc, changes, hint) { + var out = []; + var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; + for (var i = 0; i < changes.length; i++) { + var change = changes[i]; + var from = offsetPos(change.from, oldPrev, newPrev); + var to = offsetPos(changeEnd(change), oldPrev, newPrev); + oldPrev = change.to; + newPrev = to; + if (hint == "around") { + var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; + out[i] = new Range(inv ? to : from, inv ? from : to); + } else { + out[i] = new Range(from, from); + } + } + return new Selection(out, doc.sel.primIndex); + } + + // Allow "beforeChange" event handlers to influence a change + function filterChange(doc, change, update) { + var obj = { + canceled: false, + from: change.from, + to: change.to, + text: change.text, + origin: change.origin, + cancel: function() { this.canceled = true; } + }; + if (update) obj.update = function(from, to, text, origin) { + if (from) this.from = clipPos(doc, from); + if (to) this.to = clipPos(doc, to); + if (text) this.text = text; + if (origin !== undefined) this.origin = origin; + }; + signal(doc, "beforeChange", doc, obj); + if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); + + if (obj.canceled) return null; + return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; + } + + // Apply a change to a document, and add it to the document's + // history, and propagating it to all linked documents. + function makeChange(doc, change, ignoreReadOnly) { + if (doc.cm) { + if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); + if (doc.cm.state.suppressEdits) return; + } + + if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { + change = filterChange(doc, change, true); + if (!change) return; + } + + // Possibly split or suppress the update based on the presence + // of read-only spans in its range. + var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); + if (split) { + for (var i = split.length - 1; i >= 0; --i) + makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); + } else { + makeChangeInner(doc, change); + } + } + + function makeChangeInner(doc, change) { + if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; + var selAfter = computeSelAfterChange(doc, change); + addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); + + makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); + var rebased = []; + + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); + }); + } + + // Revert a change stored in a document's history. + function makeChangeFromHistory(doc, type, allowSelectionOnly) { + if (doc.cm && doc.cm.state.suppressEdits) return; + + var hist = doc.history, event, selAfter = doc.sel; + var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; + + // Verify that there is a useable event (so that ctrl-z won't + // needlessly clear selection events) + for (var i = 0; i < source.length; i++) { + event = source[i]; + if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) + break; + } + if (i == source.length) return; + hist.lastOrigin = hist.lastSelOrigin = null; + + for (;;) { + event = source.pop(); + if (event.ranges) { + pushSelectionToHistory(event, dest); + if (allowSelectionOnly && !event.equals(doc.sel)) { + setSelection(doc, event, {clearRedo: false}); + return; + } + selAfter = event; + } + else break; + } + + // Build up a reverse change object to add to the opposite history + // stack (redo when undoing, and vice versa). + var antiChanges = []; + pushSelectionToHistory(selAfter, dest); + dest.push({changes: antiChanges, generation: hist.generation}); + hist.generation = event.generation || ++hist.maxGeneration; + + var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); + + for (var i = event.changes.length - 1; i >= 0; --i) { + var change = event.changes[i]; + change.origin = type; + if (filter && !filterChange(doc, change, false)) { + source.length = 0; + return; + } + + antiChanges.push(historyChangeFromChange(doc, change)); + + var after = i ? computeSelAfterChange(doc, change, null) : lst(source); + makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); + if (doc.cm) ensureCursorVisible(doc.cm); + var rebased = []; + + // Propagate to the linked documents + linkedDocs(doc, function(doc, sharedHist) { + if (!sharedHist && indexOf(rebased, doc.history) == -1) { + rebaseHist(doc.history, change); + rebased.push(doc.history); + } + makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); + }); + } + } + + // Sub-views need their line numbers shifted when text is added + // above or below them in the parent document. + function shiftDoc(doc, distance) { + doc.first += distance; + doc.sel = new Selection(map(doc.sel.ranges, function(range) { + return new Range(Pos(range.anchor.line + distance, range.anchor.ch), + Pos(range.head.line + distance, range.head.ch)); + }), doc.sel.primIndex); + if (doc.cm) regChange(doc.cm, doc.first, doc.first - distance, distance); + } + + // More lower-level change function, handling only a single document + // (not linked ones). + function makeChangeSingleDoc(doc, change, selAfter, spans) { + if (doc.cm && !doc.cm.curOp) + return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); + + if (change.to.line < doc.first) { + shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); + return; + } + if (change.from.line > doc.lastLine()) return; + + // Clip the change to the size of this doc + if (change.from.line < doc.first) { + var shift = change.text.length - 1 - (doc.first - change.from.line); + shiftDoc(doc, shift); + change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), + text: [lst(change.text)], origin: change.origin}; + } + var last = doc.lastLine(); + if (change.to.line > last) { + change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), + text: [change.text[0]], origin: change.origin}; + } + + change.removed = getBetween(doc, change.from, change.to); + + if (!selAfter) selAfter = computeSelAfterChange(doc, change, null); + if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); + else updateDoc(doc, change, spans); + setSelectionNoUndo(doc, selAfter, sel_dontScroll); + } + + // Handle the interaction of a change to a document with the editor + // that this document is part of. + function makeChangeSingleDocInEditor(cm, change, spans) { + var doc = cm.doc, display = cm.display, from = change.from, to = change.to; + + var recomputeMaxLength = false, checkWidthStart = from.line; + if (!cm.options.lineWrapping) { + checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); + doc.iter(checkWidthStart, to.line + 1, function(line) { + if (line == display.maxLine) { + recomputeMaxLength = true; + return true; + } + }); + } + + if (doc.sel.contains(change.from, change.to) > -1) + cm.curOp.cursorActivity = true; + + updateDoc(doc, change, spans, estimateHeight(cm)); + + if (!cm.options.lineWrapping) { + doc.iter(checkWidthStart, from.line + change.text.length, function(line) { + var len = lineLength(line); + if (len > display.maxLineLength) { + display.maxLine = line; + display.maxLineLength = len; + display.maxLineChanged = true; + recomputeMaxLength = false; + } + }); + if (recomputeMaxLength) cm.curOp.updateMaxLine = true; + } + + // Adjust frontier, schedule worker + doc.frontier = Math.min(doc.frontier, from.line); + startWorker(cm, 400); + + var lendiff = change.text.length - (to.line - from.line) - 1; + // Remember that these lines changed, for updating the display + if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) + regLineChange(cm, from.line, "text"); + else + regChange(cm, from.line, to.line + 1, lendiff); + + if (hasHandler(cm, "change") || hasHandler(cm, "changes")) + (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push({ + from: from, to: to, + text: change.text, + removed: change.removed, + origin: change.origin + }); + } + + function replaceRange(doc, code, from, to, origin) { + if (!to) to = from; + if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } + if (typeof code == "string") code = splitLines(code); + makeChange(doc, {from: from, to: to, text: code, origin: origin}); + } + + // SCROLLING THINGS INTO VIEW + + // If an editor sits on the top or bottom of the window, partially + // scrolled out of view, this ensures that the cursor is visible. + function maybeScrollWindow(cm, coords) { + var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; + if (coords.top + box.top < 0) doScroll = true; + else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; + if (doScroll != null && !phantom) { + var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + + (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + + (coords.bottom - coords.top + scrollerCutOff) + "px; left: " + + coords.left + "px; width: 2px;"); + cm.display.lineSpace.appendChild(scrollNode); + scrollNode.scrollIntoView(doScroll); + cm.display.lineSpace.removeChild(scrollNode); + } + } + + // Scroll a given position into view (immediately), verifying that + // it actually became visible (as line heights are accurately + // measured, the position of something may 'drift' during drawing). + function scrollPosIntoView(cm, pos, end, margin) { + if (margin == null) margin = 0; + for (;;) { + var changed = false, coords = cursorCoords(cm, pos); + var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); + var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), + Math.min(coords.top, endCoords.top) - margin, + Math.max(coords.left, endCoords.left), + Math.max(coords.bottom, endCoords.bottom) + margin); + var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; + if (scrollPos.scrollTop != null) { + setScrollTop(cm, scrollPos.scrollTop); + if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; + } + if (scrollPos.scrollLeft != null) { + setScrollLeft(cm, scrollPos.scrollLeft); + if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; + } + if (!changed) return coords; + } + } + + // Scroll a given set of coordinates into view (immediately). + function scrollIntoView(cm, x1, y1, x2, y2) { + var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); + if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); + if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); + } + + // Calculate a new scroll position needed to scroll the given + // rectangle into view. Returns an object with scrollTop and + // scrollLeft properties. When these are undefined, the + // vertical/horizontal position does not need to be adjusted. + function calculateScrollPos(cm, x1, y1, x2, y2) { + var display = cm.display, snapMargin = textHeight(cm.display); + if (y1 < 0) y1 = 0; + var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; + var screen = display.scroller.clientHeight - scrollerCutOff, result = {}; + var docBottom = cm.doc.height + paddingVert(display); + var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; + if (y1 < screentop) { + result.scrollTop = atTop ? 0 : y1; + } else if (y2 > screentop + screen) { + var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); + if (newTop != screentop) result.scrollTop = newTop; + } + + var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; + var screenw = display.scroller.clientWidth - scrollerCutOff; + x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth; + var gutterw = display.gutters.offsetWidth; + var atLeft = x1 < gutterw + 10; + if (x1 < screenleft + gutterw || atLeft) { + if (atLeft) x1 = 0; + result.scrollLeft = Math.max(0, x1 - 10 - gutterw); + } else if (x2 > screenw + screenleft - 3) { + result.scrollLeft = x2 + 10 - screenw; + } + return result; + } + + // Store a relative adjustment to the scroll position in the current + // operation (to be applied when the operation finishes). + function addToScrollPos(cm, left, top) { + if (left != null || top != null) resolveScrollToPos(cm); + if (left != null) + cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; + if (top != null) + cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; + } + + // Make sure that at the end of the operation the current cursor is + // shown. + function ensureCursorVisible(cm) { + resolveScrollToPos(cm); + var cur = cm.getCursor(), from = cur, to = cur; + if (!cm.options.lineWrapping) { + from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; + to = Pos(cur.line, cur.ch + 1); + } + cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true}; + } + + // When an operation has its scrollToPos property set, and another + // scroll action is applied before the end of the operation, this + // 'simulates' scrolling that position into view in a cheap way, so + // that the effect of intermediate scroll commands is not ignored. + function resolveScrollToPos(cm) { + var range = cm.curOp.scrollToPos; + if (range) { + cm.curOp.scrollToPos = null; + var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); + var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), + Math.min(from.top, to.top) - range.margin, + Math.max(from.right, to.right), + Math.max(from.bottom, to.bottom) + range.margin); + cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + } + + // API UTILITIES + + // Indent the given line. The how parameter can be "smart", + // "add"/null, "subtract", or "prev". When aggressive is false + // (typically set to true for forced single-line indents), empty + // lines are not indented, and places where the mode returns Pass + // are left alone. + function indentLine(cm, n, how, aggressive) { + var doc = cm.doc, state; + if (how == null) how = "add"; + if (how == "smart") { + // Fall back to "prev" when the mode doesn't have an indentation + // method. + if (!cm.doc.mode.indent) how = "prev"; + else state = getStateBefore(cm, n); + } + + var tabSize = cm.options.tabSize; + var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); + if (line.stateAfter) line.stateAfter = null; + var curSpaceString = line.text.match(/^\s*/)[0], indentation; + if (!aggressive && !/\S/.test(line.text)) { + indentation = 0; + how = "not"; + } else if (how == "smart") { + indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); + if (indentation == Pass) { + if (!aggressive) return; + how = "prev"; + } + } + if (how == "prev") { + if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); + else indentation = 0; + } else if (how == "add") { + indentation = curSpace + cm.options.indentUnit; + } else if (how == "subtract") { + indentation = curSpace - cm.options.indentUnit; + } else if (typeof how == "number") { + indentation = curSpace + how; + } + indentation = Math.max(0, indentation); + + var indentString = "", pos = 0; + if (cm.options.indentWithTabs) + for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} + if (pos < indentation) indentString += spaceStr(indentation - pos); + + if (indentString != curSpaceString) { + replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); + } else { + // Ensure that, if the cursor was in the whitespace at the start + // of the line, it is moved to the end of that space. + for (var i = 0; i < doc.sel.ranges.length; i++) { + var range = doc.sel.ranges[i]; + if (range.head.line == n && range.head.ch < curSpaceString.length) { + var pos = Pos(n, curSpaceString.length); + replaceOneSelection(doc, i, new Range(pos, pos)); + break; + } + } + } + line.stateAfter = null; + } + + // Utility for applying a change to a line by handle or number, + // returning the number and optionally registering the line as + // changed. + function changeLine(cm, handle, changeType, op) { + var no = handle, line = handle, doc = cm.doc; + if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); + else no = lineNo(handle); + if (no == null) return null; + if (op(line, no)) regLineChange(cm, no, changeType); + else return null; + return line; + } + + // Helper for deleting text near the selection(s), used to implement + // backspace, delete, and similar functionality. + function deleteNearSelection(cm, compute) { + var ranges = cm.doc.sel.ranges, kill = []; + // Build up a set of ranges to kill first, merging overlapping + // ranges. + for (var i = 0; i < ranges.length; i++) { + var toKill = compute(ranges[i]); + while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { + var replaced = kill.pop(); + if (cmp(replaced.from, toKill.from) < 0) { + toKill.from = replaced.from; + break; + } + } + kill.push(toKill); + } + // Next, remove those actual ranges. + runInOp(cm, function() { + for (var i = kill.length - 1; i >= 0; i--) + replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); + ensureCursorVisible(cm); + }); + } + + // Used for horizontal relative motion. Dir is -1 or 1 (left or + // right), unit can be "char", "column" (like char, but doesn't + // cross line boundaries), "word" (across next word), or "group" (to + // the start of next group of word or non-word-non-whitespace + // chars). The visually param controls whether, in right-to-left + // text, direction 1 means to move towards the next index in the + // string, or towards the character to the right of the current + // position. The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosH(doc, pos, dir, unit, visually) { + var line = pos.line, ch = pos.ch, origDir = dir; + var lineObj = getLine(doc, line); + var possible = true; + function findNextLine() { + var l = line + dir; + if (l < doc.first || l >= doc.first + doc.size) return (possible = false); + line = l; + return lineObj = getLine(doc, l); + } + function moveOnce(boundToLine) { + var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); + if (next == null) { + if (!boundToLine && findNextLine()) { + if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); + else ch = dir < 0 ? lineObj.text.length : 0; + } else return (possible = false); + } else ch = next; + return true; + } + + if (unit == "char") moveOnce(); + else if (unit == "column") moveOnce(true); + else if (unit == "word" || unit == "group") { + var sawType = null, group = unit == "group"; + for (var first = true;; first = false) { + if (dir < 0 && !moveOnce(!first)) break; + var cur = lineObj.text.charAt(ch) || "\n"; + var type = isWordChar(cur) ? "w" + : group && cur == "\n" ? "n" + : !group || /\s/.test(cur) ? null + : "p"; + if (group && !first && !type) type = "s"; + if (sawType && sawType != type) { + if (dir < 0) {dir = 1; moveOnce();} + break; + } + + if (type) sawType = type; + if (dir > 0 && !moveOnce(!first)) break; + } + } + var result = skipAtomic(doc, Pos(line, ch), origDir, true); + if (!possible) result.hitSide = true; + return result; + } + + // For relative vertical movement. Dir may be -1 or 1. Unit can be + // "page" or "line". The resulting position will have a hitSide=true + // property if it reached the end of the document. + function findPosV(cm, pos, dir, unit) { + var doc = cm.doc, x = pos.left, y; + if (unit == "page") { + var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); + y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); + } else if (unit == "line") { + y = dir > 0 ? pos.bottom + 3 : pos.top - 3; + } + for (;;) { + var target = coordsChar(cm, x, y); + if (!target.outside) break; + if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } + y += dir * 5; + } + return target; + } + + // Find the word at the given position (as returned by coordsChar). + function findWordAt(doc, pos) { + var line = getLine(doc, pos.line).text; + var start = pos.ch, end = pos.ch; + if (line) { + if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; + var startChar = line.charAt(start); + var check = isWordChar(startChar) ? isWordChar + : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} + : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; + while (start > 0 && check(line.charAt(start - 1))) --start; + while (end < line.length && check(line.charAt(end))) ++end; + } + return new Range(Pos(pos.line, start), Pos(pos.line, end)); + } + + // EDITOR METHODS + + // The publicly visible API. Note that methodOp(f) means + // 'wrap f in an operation, performed on its `this` parameter'. + + // This is not the complete set of editor methods. Most of the + // methods defined on the Doc type are also injected into + // CodeMirror.prototype, for backwards compatibility and + // convenience. + + CodeMirror.prototype = { + constructor: CodeMirror, + focus: function(){window.focus(); focusInput(this); fastPoll(this);}, + + setOption: function(option, value) { + var options = this.options, old = options[option]; + if (options[option] == value && option != "mode") return; + options[option] = value; + if (optionHandlers.hasOwnProperty(option)) + operation(this, optionHandlers[option])(this, value, old); + }, + + getOption: function(option) {return this.options[option];}, + getDoc: function() {return this.doc;}, + + addKeyMap: function(map, bottom) { + this.state.keyMaps[bottom ? "push" : "unshift"](map); + }, + removeKeyMap: function(map) { + var maps = this.state.keyMaps; + for (var i = 0; i < maps.length; ++i) + if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) { + maps.splice(i, 1); + return true; + } + }, + + addOverlay: methodOp(function(spec, options) { + var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); + if (mode.startState) throw new Error("Overlays may not be stateful."); + this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); + this.state.modeGen++; + regChange(this); + }), + removeOverlay: methodOp(function(spec) { + var overlays = this.state.overlays; + for (var i = 0; i < overlays.length; ++i) { + var cur = overlays[i].modeSpec; + if (cur == spec || typeof spec == "string" && cur.name == spec) { + overlays.splice(i, 1); + this.state.modeGen++; + regChange(this); + return; + } + } + }), + + indentLine: methodOp(function(n, dir, aggressive) { + if (typeof dir != "string" && typeof dir != "number") { + if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; + else dir = dir ? "add" : "subtract"; + } + if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); + }), + indentSelection: methodOp(function(how) { + var ranges = this.doc.sel.ranges, end = -1; + for (var i = 0; i < ranges.length; i++) { + var range = ranges[i]; + if (!range.empty()) { + var start = Math.max(end, range.from().line); + var to = range.to(); + end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; + for (var j = start; j < end; ++j) + indentLine(this, j, how); + } else if (range.head.line > end) { + indentLine(this, range.head.line, how, true); + end = range.head.line; + if (i == this.doc.sel.primIndex) ensureCursorVisible(this); + } + } + }), + + // Fetch the parser token for a given character. Useful for hacks + // that want to inspect the mode state (say, for completion). + getTokenAt: function(pos, precise) { + var doc = this.doc; + pos = clipPos(doc, pos); + var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode; + var line = getLine(doc, pos.line); + var stream = new StringStream(line.text, this.options.tabSize); + while (stream.pos < pos.ch && !stream.eol()) { + stream.start = stream.pos; + var style = mode.token(stream, state); + } + return {start: stream.start, + end: stream.pos, + string: stream.current(), + type: style || null, + state: state}; + }, + + getTokenTypeAt: function(pos) { + pos = clipPos(this.doc, pos); + var styles = getLineStyles(this, getLine(this.doc, pos.line)); + var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; + if (ch == 0) return styles[2]; + for (;;) { + var mid = (before + after) >> 1; + if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; + else if (styles[mid * 2 + 1] < ch) before = mid + 1; + else return styles[mid * 2 + 2]; + } + }, + + getModeAt: function(pos) { + var mode = this.doc.mode; + if (!mode.innerMode) return mode; + return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; + }, + + getHelper: function(pos, type) { + return this.getHelpers(pos, type)[0]; + }, + + getHelpers: function(pos, type) { + var found = []; + if (!helpers.hasOwnProperty(type)) return helpers; + var help = helpers[type], mode = this.getModeAt(pos); + if (typeof mode[type] == "string") { + if (help[mode[type]]) found.push(help[mode[type]]); + } else if (mode[type]) { + for (var i = 0; i < mode[type].length; i++) { + var val = help[mode[type][i]]; + if (val) found.push(val); + } + } else if (mode.helperType && help[mode.helperType]) { + found.push(help[mode.helperType]); + } else if (help[mode.name]) { + found.push(help[mode.name]); + } + for (var i = 0; i < help._global.length; i++) { + var cur = help._global[i]; + if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) + found.push(cur.val); + } + return found; + }, + + getStateAfter: function(line, precise) { + var doc = this.doc; + line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); + return getStateBefore(this, line + 1, precise); + }, + + cursorCoords: function(start, mode) { + var pos, range = this.doc.sel.primary(); + if (start == null) pos = range.head; + else if (typeof start == "object") pos = clipPos(this.doc, start); + else pos = start ? range.from() : range.to(); + return cursorCoords(this, pos, mode || "page"); + }, + + charCoords: function(pos, mode) { + return charCoords(this, clipPos(this.doc, pos), mode || "page"); + }, + + coordsChar: function(coords, mode) { + coords = fromCoordSystem(this, coords, mode || "page"); + return coordsChar(this, coords.left, coords.top); + }, + + lineAtHeight: function(height, mode) { + height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; + return lineAtHeight(this.doc, height + this.display.viewOffset); + }, + heightAtLine: function(line, mode) { + var end = false, last = this.doc.first + this.doc.size - 1; + if (line < this.doc.first) line = this.doc.first; + else if (line > last) { line = last; end = true; } + var lineObj = getLine(this.doc, line); + return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top + + (end ? this.doc.height - heightAtLine(lineObj) : 0); + }, + + defaultTextHeight: function() { return textHeight(this.display); }, + defaultCharWidth: function() { return charWidth(this.display); }, + + setGutterMarker: methodOp(function(line, gutterID, value) { + return changeLine(this, line, "gutter", function(line) { + var markers = line.gutterMarkers || (line.gutterMarkers = {}); + markers[gutterID] = value; + if (!value && isEmpty(markers)) line.gutterMarkers = null; + return true; + }); + }), + + clearGutter: methodOp(function(gutterID) { + var cm = this, doc = cm.doc, i = doc.first; + doc.iter(function(line) { + if (line.gutterMarkers && line.gutterMarkers[gutterID]) { + line.gutterMarkers[gutterID] = null; + regLineChange(cm, i, "gutter"); + if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; + } + ++i; + }); + }), + + addLineClass: methodOp(function(handle, where, cls) { + return changeLine(this, handle, "class", function(line) { + var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; + if (!line[prop]) line[prop] = cls; + else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false; + else line[prop] += " " + cls; + return true; + }); + }), + + removeLineClass: methodOp(function(handle, where, cls) { + return changeLine(this, handle, "class", function(line) { + var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; + var cur = line[prop]; + if (!cur) return false; + else if (cls == null) line[prop] = null; + else { + var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)")); + if (!found) return false; + var end = found.index + found[0].length; + line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; + } + return true; + }); + }), + + addLineWidget: methodOp(function(handle, node, options) { + return addLineWidget(this, handle, node, options); + }), + + removeLineWidget: function(widget) { widget.clear(); }, + + lineInfo: function(line) { + if (typeof line == "number") { + if (!isLine(this.doc, line)) return null; + var n = line; + line = getLine(this.doc, line); + if (!line) return null; + } else { + var n = lineNo(line); + if (n == null) return null; + } + return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, + textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, + widgets: line.widgets}; + }, + + getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};}, + + addWidget: function(pos, node, scroll, vert, horiz) { + var display = this.display; + pos = cursorCoords(this, clipPos(this.doc, pos)); + var top = pos.bottom, left = pos.left; + node.style.position = "absolute"; + display.sizer.appendChild(node); + if (vert == "over") { + top = pos.top; + } else if (vert == "above" || vert == "near") { + var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), + hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); + // Default to positioning above (if specified and possible); otherwise default to positioning below + if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) + top = pos.top - node.offsetHeight; + else if (pos.bottom + node.offsetHeight <= vspace) + top = pos.bottom; + if (left + node.offsetWidth > hspace) + left = hspace - node.offsetWidth; + } + node.style.top = top + "px"; + node.style.left = node.style.right = ""; + if (horiz == "right") { + left = display.sizer.clientWidth - node.offsetWidth; + node.style.right = "0px"; + } else { + if (horiz == "left") left = 0; + else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; + node.style.left = left + "px"; + } + if (scroll) + scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); + }, + + triggerOnKeyDown: methodOp(onKeyDown), + triggerOnKeyPress: methodOp(onKeyPress), + triggerOnKeyUp: methodOp(onKeyUp), + + execCommand: function(cmd) { + if (commands.hasOwnProperty(cmd)) + return commands[cmd](this); + }, + + findPosH: function(from, amount, unit, visually) { + var dir = 1; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + cur = findPosH(this.doc, cur, dir, unit, visually); + if (cur.hitSide) break; + } + return cur; + }, + + moveH: methodOp(function(dir, unit) { + var cm = this; + cm.extendSelectionsBy(function(range) { + if (cm.display.shift || cm.doc.extend || range.empty()) + return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); + else + return dir < 0 ? range.from() : range.to(); + }, sel_move); + }), + + deleteH: methodOp(function(dir, unit) { + var sel = this.doc.sel, doc = this.doc; + if (sel.somethingSelected()) + doc.replaceSelection("", null, "+delete"); + else + deleteNearSelection(this, function(range) { + var other = findPosH(doc, range.head, dir, unit, false); + return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}; + }); + }), + + findPosV: function(from, amount, unit, goalColumn) { + var dir = 1, x = goalColumn; + if (amount < 0) { dir = -1; amount = -amount; } + for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { + var coords = cursorCoords(this, cur, "div"); + if (x == null) x = coords.left; + else coords.left = x; + cur = findPosV(this, coords, dir, unit); + if (cur.hitSide) break; + } + return cur; + }, + + moveV: methodOp(function(dir, unit) { + var cm = this, doc = this.doc, goals = []; + var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); + doc.extendSelectionsBy(function(range) { + if (collapse) + return dir < 0 ? range.from() : range.to(); + var headPos = cursorCoords(cm, range.head, "div"); + if (range.goalColumn != null) headPos.left = range.goalColumn; + goals.push(headPos.left); + var pos = findPosV(cm, headPos, dir, unit); + if (unit == "page" && range == doc.sel.primary()) + addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); + return pos; + }, sel_move); + if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) + doc.sel.ranges[i].goalColumn = goals[i]; + }), + + toggleOverwrite: function(value) { + if (value != null && value == this.state.overwrite) return; + if (this.state.overwrite = !this.state.overwrite) + this.display.cursorDiv.className += " CodeMirror-overwrite"; + else + this.display.cursorDiv.className = this.display.cursorDiv.className.replace(" CodeMirror-overwrite", ""); + + signal(this, "overwriteToggle", this, this.state.overwrite); + }, + hasFocus: function() { return activeElt() == this.display.input; }, + + scrollTo: methodOp(function(x, y) { + if (x != null || y != null) resolveScrollToPos(this); + if (x != null) this.curOp.scrollLeft = x; + if (y != null) this.curOp.scrollTop = y; + }), + getScrollInfo: function() { + var scroller = this.display.scroller, co = scrollerCutOff; + return {left: scroller.scrollLeft, top: scroller.scrollTop, + height: scroller.scrollHeight - co, width: scroller.scrollWidth - co, + clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co}; + }, + + scrollIntoView: methodOp(function(range, margin) { + if (range == null) { + range = {from: this.doc.sel.primary().head, to: null}; + if (margin == null) margin = this.options.cursorScrollMargin; + } else if (typeof range == "number") { + range = {from: Pos(range, 0), to: null}; + } else if (range.from == null) { + range = {from: range, to: null}; + } + if (!range.to) range.to = range.from; + range.margin = margin || 0; + + if (range.from.line != null) { + resolveScrollToPos(this); + this.curOp.scrollToPos = range; + } else { + var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), + Math.min(range.from.top, range.to.top) - range.margin, + Math.max(range.from.right, range.to.right), + Math.max(range.from.bottom, range.to.bottom) + range.margin); + this.scrollTo(sPos.scrollLeft, sPos.scrollTop); + } + }), + + setSize: methodOp(function(width, height) { + function interpret(val) { + return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; + } + if (width != null) this.display.wrapper.style.width = interpret(width); + if (height != null) this.display.wrapper.style.height = interpret(height); + if (this.options.lineWrapping) clearLineMeasurementCache(this); + this.curOp.forceUpdate = true; + signal(this, "refresh", this); + }), + + operation: function(f){return runInOp(this, f);}, + + refresh: methodOp(function() { + var oldHeight = this.display.cachedTextHeight; + regChange(this); + clearCaches(this); + this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); + if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) + estimateLineHeights(this); + signal(this, "refresh", this); + }), + + swapDoc: methodOp(function(doc) { + var old = this.doc; + old.cm = null; + attachDoc(this, doc); + clearCaches(this); + resetInput(this); + this.scrollTo(doc.scrollLeft, doc.scrollTop); + signalLater(this, "swapDoc", this, old); + return old; + }), + + getInputField: function(){return this.display.input;}, + getWrapperElement: function(){return this.display.wrapper;}, + getScrollerElement: function(){return this.display.scroller;}, + getGutterElement: function(){return this.display.gutters;} + }; + eventMixin(CodeMirror); + + // OPTION DEFAULTS + + // The default configuration options. + var defaults = CodeMirror.defaults = {}; + // Functions to run when options are changed. + var optionHandlers = CodeMirror.optionHandlers = {}; + + function option(name, deflt, handle, notOnInit) { + CodeMirror.defaults[name] = deflt; + if (handle) optionHandlers[name] = + notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; + } + + // Passed to option handlers when there is no old value. + var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; + + // These two are, on init, called from the constructor because they + // have to be initialized before the editor can start at all. + option("value", "", function(cm, val) { + cm.setValue(val); + }, true); + option("mode", null, function(cm, val) { + cm.doc.modeOption = val; + loadMode(cm); + }, true); + + option("indentUnit", 2, loadMode, true); + option("indentWithTabs", false); + option("smartIndent", true); + option("tabSize", 4, function(cm) { + resetModeState(cm); + clearCaches(cm); + regChange(cm); + }, true); + option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) { + cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); + cm.refresh(); + }, true); + option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); + option("electricChars", true); + option("rtlMoveVisually", !windows); + option("wholeLineUpdateBefore", true); + + option("theme", "default", function(cm) { + themeChanged(cm); + guttersChanged(cm); + }, true); + option("keyMap", "default", keyMapChanged); + option("extraKeys", null); + + option("lineWrapping", false, wrappingChanged, true); + option("gutters", [], function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("fixedGutter", true, function(cm, val) { + cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; + cm.refresh(); + }, true); + option("coverGutterNextToScrollbar", false, updateScrollbars, true); + option("lineNumbers", false, function(cm) { + setGuttersForLineNumbers(cm.options); + guttersChanged(cm); + }, true); + option("firstLineNumber", 1, guttersChanged, true); + option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); + option("showCursorWhenSelecting", false, updateSelection, true); + + option("resetSelectionOnContextMenu", true); + + option("readOnly", false, function(cm, val) { + if (val == "nocursor") { + onBlur(cm); + cm.display.input.blur(); + cm.display.disabled = true; + } else { + cm.display.disabled = false; + if (!val) resetInput(cm); + } + }); + option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true); + option("dragDrop", true); + + option("cursorBlinkRate", 530); + option("cursorScrollMargin", 0); + option("cursorHeight", 1); + option("workTime", 100); + option("workDelay", 100); + option("flattenSpans", true, resetModeState, true); + option("addModeClass", false, resetModeState, true); + option("pollInterval", 100); + option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;}); + option("historyEventDelay", 1250); + option("viewportMargin", 10, function(cm){cm.refresh();}, true); + option("maxHighlightLength", 10000, resetModeState, true); + option("moveInputWithCursor", true, function(cm, val) { + if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0; + }); + + option("tabindex", null, function(cm, val) { + cm.display.input.tabIndex = val || ""; + }); + option("autofocus", null); + + // MODE DEFINITION AND QUERYING + + // Known modes, by name and by MIME + var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; + + // Extra arguments are stored as the mode's dependencies, which is + // used by (legacy) mechanisms like loadmode.js to automatically + // load a mode. (Preferred mechanism is the require/define calls.) + CodeMirror.defineMode = function(name, mode) { + if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; + if (arguments.length > 2) { + mode.dependencies = []; + for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]); + } + modes[name] = mode; + }; + + CodeMirror.defineMIME = function(mime, spec) { + mimeModes[mime] = spec; + }; + + // Given a MIME type, a {name, ...options} config object, or a name + // string, return a mode config object. + CodeMirror.resolveMode = function(spec) { + if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { + spec = mimeModes[spec]; + } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { + var found = mimeModes[spec.name]; + if (typeof found == "string") found = {name: found}; + spec = createObj(found, spec); + spec.name = found.name; + } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { + return CodeMirror.resolveMode("application/xml"); + } + if (typeof spec == "string") return {name: spec}; + else return spec || {name: "null"}; + }; + + // Given a mode spec (anything that resolveMode accepts), find and + // initialize an actual mode object. + CodeMirror.getMode = function(options, spec) { + var spec = CodeMirror.resolveMode(spec); + var mfactory = modes[spec.name]; + if (!mfactory) return CodeMirror.getMode(options, "text/plain"); + var modeObj = mfactory(options, spec); + if (modeExtensions.hasOwnProperty(spec.name)) { + var exts = modeExtensions[spec.name]; + for (var prop in exts) { + if (!exts.hasOwnProperty(prop)) continue; + if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; + modeObj[prop] = exts[prop]; + } + } + modeObj.name = spec.name; + if (spec.helperType) modeObj.helperType = spec.helperType; + if (spec.modeProps) for (var prop in spec.modeProps) + modeObj[prop] = spec.modeProps[prop]; + + return modeObj; + }; + + // Minimal default mode. + CodeMirror.defineMode("null", function() { + return {token: function(stream) {stream.skipToEnd();}}; + }); + CodeMirror.defineMIME("text/plain", "null"); + + // This can be used to attach properties to mode objects from + // outside the actual mode definition. + var modeExtensions = CodeMirror.modeExtensions = {}; + CodeMirror.extendMode = function(mode, properties) { + var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); + copyObj(properties, exts); + }; + + // EXTENSIONS + + CodeMirror.defineExtension = function(name, func) { + CodeMirror.prototype[name] = func; + }; + CodeMirror.defineDocExtension = function(name, func) { + Doc.prototype[name] = func; + }; + CodeMirror.defineOption = option; + + var initHooks = []; + CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; + + var helpers = CodeMirror.helpers = {}; + CodeMirror.registerHelper = function(type, name, value) { + if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []}; + helpers[type][name] = value; + }; + CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { + CodeMirror.registerHelper(type, name, value); + helpers[type]._global.push({pred: predicate, val: value}); + }; + + // MODE STATE HANDLING + + // Utility functions for working with state. Exported because nested + // modes need to do this for their inner modes. + + var copyState = CodeMirror.copyState = function(mode, state) { + if (state === true) return state; + if (mode.copyState) return mode.copyState(state); + var nstate = {}; + for (var n in state) { + var val = state[n]; + if (val instanceof Array) val = val.concat([]); + nstate[n] = val; + } + return nstate; + }; + + var startState = CodeMirror.startState = function(mode, a1, a2) { + return mode.startState ? mode.startState(a1, a2) : true; + }; + + // Given a mode and a state (for that mode), find the inner mode and + // state at the position that the state refers to. + CodeMirror.innerMode = function(mode, state) { + while (mode.innerMode) { + var info = mode.innerMode(state); + if (!info || info.mode == mode) break; + state = info.state; + mode = info.mode; + } + return info || {mode: mode, state: state}; + }; + + // STANDARD COMMANDS + + // Commands are parameter-less actions that can be performed on an + // editor, mostly used for keybindings. + var commands = CodeMirror.commands = { + selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);}, + singleSelection: function(cm) { + cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); + }, + killLine: function(cm) { + deleteNearSelection(cm, function(range) { + if (range.empty()) { + var len = getLine(cm.doc, range.head.line).text.length; + if (range.head.ch == len && range.head.line < cm.lastLine()) + return {from: range.head, to: Pos(range.head.line + 1, 0)}; + else + return {from: range.head, to: Pos(range.head.line, len)}; + } else { + return {from: range.from(), to: range.to()}; + } + }); + }, + deleteLine: function(cm) { + deleteNearSelection(cm, function(range) { + return {from: Pos(range.from().line, 0), + to: clipPos(cm.doc, Pos(range.to().line + 1, 0))}; + }); + }, + delLineLeft: function(cm) { + deleteNearSelection(cm, function(range) { + return {from: Pos(range.from().line, 0), to: range.from()}; + }); + }, + undo: function(cm) {cm.undo();}, + redo: function(cm) {cm.redo();}, + undoSelection: function(cm) {cm.undoSelection();}, + redoSelection: function(cm) {cm.redoSelection();}, + goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, + goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, + goLineStart: function(cm) { + cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, sel_move); + }, + goLineStartSmart: function(cm) { + cm.extendSelectionsBy(function(range) { + var start = lineStart(cm, range.head.line); + var line = cm.getLineHandle(start.line); + var order = getOrder(line); + if (!order || order[0].level == 0) { + var firstNonWS = Math.max(0, line.text.search(/\S/)); + var inWS = range.head.line == start.line && range.head.ch <= firstNonWS && range.head.ch; + return Pos(start.line, inWS ? 0 : firstNonWS); + } + return start; + }, sel_move); + }, + goLineEnd: function(cm) { + cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, sel_move); + }, + goLineRight: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); + }, sel_move); + }, + goLineLeft: function(cm) { + cm.extendSelectionsBy(function(range) { + var top = cm.charCoords(range.head, "div").top + 5; + return cm.coordsChar({left: 0, top: top}, "div"); + }, sel_move); + }, + goLineUp: function(cm) {cm.moveV(-1, "line");}, + goLineDown: function(cm) {cm.moveV(1, "line");}, + goPageUp: function(cm) {cm.moveV(-1, "page");}, + goPageDown: function(cm) {cm.moveV(1, "page");}, + goCharLeft: function(cm) {cm.moveH(-1, "char");}, + goCharRight: function(cm) {cm.moveH(1, "char");}, + goColumnLeft: function(cm) {cm.moveH(-1, "column");}, + goColumnRight: function(cm) {cm.moveH(1, "column");}, + goWordLeft: function(cm) {cm.moveH(-1, "word");}, + goGroupRight: function(cm) {cm.moveH(1, "group");}, + goGroupLeft: function(cm) {cm.moveH(-1, "group");}, + goWordRight: function(cm) {cm.moveH(1, "word");}, + delCharBefore: function(cm) {cm.deleteH(-1, "char");}, + delCharAfter: function(cm) {cm.deleteH(1, "char");}, + delWordBefore: function(cm) {cm.deleteH(-1, "word");}, + delWordAfter: function(cm) {cm.deleteH(1, "word");}, + delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, + delGroupAfter: function(cm) {cm.deleteH(1, "group");}, + indentAuto: function(cm) {cm.indentSelection("smart");}, + indentMore: function(cm) {cm.indentSelection("add");}, + indentLess: function(cm) {cm.indentSelection("subtract");}, + insertTab: function(cm) {cm.replaceSelection("\t");}, + defaultTab: function(cm) { + if (cm.somethingSelected()) cm.indentSelection("add"); + else cm.execCommand("insertTab"); + }, + transposeChars: function(cm) { + runInOp(cm, function() { + var ranges = cm.listSelections(); + for (var i = 0; i < ranges.length; i++) { + var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; + if (cur.ch > 0 && cur.ch < line.length - 1) + cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1), + Pos(cur.line, cur.ch - 1), Pos(cur.line, cur.ch + 1)); + } + }); + }, + newlineAndIndent: function(cm) { + runInOp(cm, function() { + var len = cm.listSelections().length; + for (var i = 0; i < len; i++) { + var range = cm.listSelections()[i]; + cm.replaceRange("\n", range.anchor, range.head, "+input"); + cm.indentLine(range.from().line + 1, null, true); + ensureCursorVisible(cm); + } + }); + }, + toggleOverwrite: function(cm) {cm.toggleOverwrite();} + }; + + // STANDARD KEYMAPS + + var keyMap = CodeMirror.keyMap = {}; + keyMap.basic = { + "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", + "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", + "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", + "Tab": "defaultTab", "Shift-Tab": "indentAuto", + "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", + "Esc": "singleSelection" + }; + // Note that the save and find-related commands aren't defined by + // default. User code or addons can define them. Unknown commands + // are simply ignored. + keyMap.pcDefault = { + "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", + "Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd", + "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", + "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", + "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", + "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", + "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", + fallthrough: "basic" + }; + keyMap.macDefault = { + "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", + "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", + "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore", + "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", + "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", + "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft", + "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", + fallthrough: ["basic", "emacsy"] + }; + // Very basic readline/emacs-style bindings, which are standard on Mac. + keyMap.emacsy = { + "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", + "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", + "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", + "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" + }; + keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; + + // KEYMAP DISPATCH + + function getKeyMap(val) { + if (typeof val == "string") return keyMap[val]; + else return val; + } + + // Given an array of keymaps and a key name, call handle on any + // bindings found, until that returns a truthy value, at which point + // we consider the key handled. Implements things like binding a key + // to false stopping further handling and keymap fallthrough. + var lookupKey = CodeMirror.lookupKey = function(name, maps, handle) { + function lookup(map) { + map = getKeyMap(map); + var found = map[name]; + if (found === false) return "stop"; + if (found != null && handle(found)) return true; + if (map.nofallthrough) return "stop"; + + var fallthrough = map.fallthrough; + if (fallthrough == null) return false; + if (Object.prototype.toString.call(fallthrough) != "[object Array]") + return lookup(fallthrough); + for (var i = 0; i < fallthrough.length; ++i) { + var done = lookup(fallthrough[i]); + if (done) return done; + } + return false; + } + + for (var i = 0; i < maps.length; ++i) { + var done = lookup(maps[i]); + if (done) return done != "stop"; + } + }; + + // Modifier key presses don't count as 'real' key presses for the + // purpose of keymap fallthrough. + var isModifierKey = CodeMirror.isModifierKey = function(event) { + var name = keyNames[event.keyCode]; + return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; + }; + + // Look up the name of a key as indicated by an event object. + var keyName = CodeMirror.keyName = function(event, noShift) { + if (presto && event.keyCode == 34 && event["char"]) return false; + var name = keyNames[event.keyCode]; + if (name == null || event.altGraphKey) return false; + if (event.altKey) name = "Alt-" + name; + if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name; + if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name; + if (!noShift && event.shiftKey) name = "Shift-" + name; + return name; + }; + + // FROMTEXTAREA + + CodeMirror.fromTextArea = function(textarea, options) { + if (!options) options = {}; + options.value = textarea.value; + if (!options.tabindex && textarea.tabindex) + options.tabindex = textarea.tabindex; + if (!options.placeholder && textarea.placeholder) + options.placeholder = textarea.placeholder; + // Set autofocus to true if this textarea is focused, or if it has + // autofocus and no other element is focused. + if (options.autofocus == null) { + var hasFocus = activeElt(); + options.autofocus = hasFocus == textarea || + textarea.getAttribute("autofocus") != null && hasFocus == document.body; + } + + function save() {textarea.value = cm.getValue();} + if (textarea.form) { + on(textarea.form, "submit", save); + // Deplorable hack to make the submit method do the right thing. + if (!options.leaveSubmitMethodAlone) { + var form = textarea.form, realSubmit = form.submit; + try { + var wrappedSubmit = form.submit = function() { + save(); + form.submit = realSubmit; + form.submit(); + form.submit = wrappedSubmit; + }; + } catch(e) {} + } + } + + textarea.style.display = "none"; + var cm = CodeMirror(function(node) { + textarea.parentNode.insertBefore(node, textarea.nextSibling); + }, options); + cm.save = save; + cm.getTextArea = function() { return textarea; }; + cm.toTextArea = function() { + save(); + textarea.parentNode.removeChild(cm.getWrapperElement()); + textarea.style.display = ""; + if (textarea.form) { + off(textarea.form, "submit", save); + if (typeof textarea.form.submit == "function") + textarea.form.submit = realSubmit; + } + }; + return cm; + }; + + // STRING STREAM + + // Fed to the mode parsers, provides helper functions to make + // parsers more succinct. + + var StringStream = CodeMirror.StringStream = function(string, tabSize) { + this.pos = this.start = 0; + this.string = string; + this.tabSize = tabSize || 8; + this.lastColumnPos = this.lastColumnValue = 0; + this.lineStart = 0; + }; + + StringStream.prototype = { + eol: function() {return this.pos >= this.string.length;}, + sol: function() {return this.pos == this.lineStart;}, + peek: function() {return this.string.charAt(this.pos) || undefined;}, + next: function() { + if (this.pos < this.string.length) + return this.string.charAt(this.pos++); + }, + eat: function(match) { + var ch = this.string.charAt(this.pos); + if (typeof match == "string") var ok = ch == match; + else var ok = ch && (match.test ? match.test(ch) : match(ch)); + if (ok) {++this.pos; return ch;} + }, + eatWhile: function(match) { + var start = this.pos; + while (this.eat(match)){} + return this.pos > start; + }, + eatSpace: function() { + var start = this.pos; + while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; + return this.pos > start; + }, + skipToEnd: function() {this.pos = this.string.length;}, + skipTo: function(ch) { + var found = this.string.indexOf(ch, this.pos); + if (found > -1) {this.pos = found; return true;} + }, + backUp: function(n) {this.pos -= n;}, + column: function() { + if (this.lastColumnPos < this.start) { + this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); + this.lastColumnPos = this.start; + } + return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + indentation: function() { + return countColumn(this.string, null, this.tabSize) - + (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); + }, + match: function(pattern, consume, caseInsensitive) { + if (typeof pattern == "string") { + var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; + var substr = this.string.substr(this.pos, pattern.length); + if (cased(substr) == cased(pattern)) { + if (consume !== false) this.pos += pattern.length; + return true; + } + } else { + var match = this.string.slice(this.pos).match(pattern); + if (match && match.index > 0) return null; + if (match && consume !== false) this.pos += match[0].length; + return match; + } + }, + current: function(){return this.string.slice(this.start, this.pos);}, + hideFirstChars: function(n, inner) { + this.lineStart += n; + try { return inner(); } + finally { this.lineStart -= n; } + } + }; + + // TEXTMARKERS + + // Created with markText and setBookmark methods. A TextMarker is a + // handle that can be used to clear or find a marked position in the + // document. Line objects hold arrays (markedSpans) containing + // {from, to, marker} object pointing to such marker objects, and + // indicating that such a marker is present on that line. Multiple + // lines may point to the same marker when it spans across lines. + // The spans will have null for their from/to properties when the + // marker continues beyond the start/end of the line. Markers have + // links back to the lines they currently touch. + + var TextMarker = CodeMirror.TextMarker = function(doc, type) { + this.lines = []; + this.type = type; + this.doc = doc; + }; + eventMixin(TextMarker); + + // Clear the marker. + TextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + var cm = this.doc.cm, withOp = cm && !cm.curOp; + if (withOp) startOperation(cm); + if (hasHandler(this, "clear")) { + var found = this.find(); + if (found) signalLater(this, "clear", found.from, found.to); + } + var min = null, max = null; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); + else if (cm) { + if (span.to != null) max = lineNo(line); + if (span.from != null) min = lineNo(line); + } + line.markedSpans = removeMarkedSpan(line.markedSpans, span); + if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) + updateLineHeight(line, textHeight(cm.display)); + } + if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { + var visual = visualLine(this.lines[i]), len = lineLength(visual); + if (len > cm.display.maxLineLength) { + cm.display.maxLine = visual; + cm.display.maxLineLength = len; + cm.display.maxLineChanged = true; + } + } + + if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); + this.lines.length = 0; + this.explicitlyCleared = true; + if (this.atomic && this.doc.cantEdit) { + this.doc.cantEdit = false; + if (cm) reCheckSelection(cm.doc); + } + if (cm) signalLater(cm, "markerCleared", cm, this); + if (withOp) endOperation(cm); + }; + + // Find the position of the marker in the document. Returns a {from, + // to} object by default. Side can be passed to get a specific side + // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the + // Pos objects returned contain a line object, rather than a line + // number (used to prevent looking up the same line twice). + TextMarker.prototype.find = function(side, lineObj) { + if (side == null && this.type == "bookmark") side = 1; + var from, to; + for (var i = 0; i < this.lines.length; ++i) { + var line = this.lines[i]; + var span = getMarkedSpanFor(line.markedSpans, this); + if (span.from != null) { + from = Pos(lineObj ? line : lineNo(line), span.from); + if (side == -1) return from; + } + if (span.to != null) { + to = Pos(lineObj ? line : lineNo(line), span.to); + if (side == 1) return to; + } + } + return from && {from: from, to: to}; + }; + + // Signals that the marker's widget changed, and surrounding layout + // should be recomputed. + TextMarker.prototype.changed = function() { + var pos = this.find(-1, true), widget = this, cm = this.doc.cm; + if (!pos || !cm) return; + runInOp(cm, function() { + var line = pos.line, lineN = lineNo(pos.line); + var view = findViewForLine(cm, lineN); + if (view) { + clearLineMeasurementCacheFor(view); + cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; + } + cm.curOp.updateMaxLine = true; + if (!lineIsHidden(widget.doc, line) && widget.height != null) { + var oldHeight = widget.height; + widget.height = null; + var dHeight = widgetHeight(widget) - oldHeight; + if (dHeight) + updateLineHeight(line, line.height + dHeight); + } + }); + }; + + TextMarker.prototype.attachLine = function(line) { + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) + (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); + } + this.lines.push(line); + }; + TextMarker.prototype.detachLine = function(line) { + this.lines.splice(indexOf(this.lines, line), 1); + if (!this.lines.length && this.doc.cm) { + var op = this.doc.cm.curOp; + (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); + } + }; + + // Collapsed markers have unique ids, in order to be able to order + // them, which is needed for uniquely determining an outer marker + // when they overlap (they may nest, but not partially overlap). + var nextMarkerId = 0; + + // Create a marker, wire it up to the right lines, and + function markText(doc, from, to, options, type) { + // Shared markers (across linked documents) are handled separately + // (markTextShared will call out to this again, once per + // document). + if (options && options.shared) return markTextShared(doc, from, to, options, type); + // Ensure we are in an operation. + if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); + + var marker = new TextMarker(doc, type), diff = cmp(from, to); + if (options) copyObj(options, marker); + // Don't connect empty markers unless clearWhenEmpty is false + if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) + return marker; + if (marker.replacedWith) { + // Showing up as a widget implies collapsed (widget replaces text) + marker.collapsed = true; + marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); + if (!options.handleMouseEvents) marker.widgetNode.ignoreEvents = true; + if (options.insertLeft) marker.widgetNode.insertLeft = true; + } + if (marker.collapsed) { + if (conflictingCollapsedRange(doc, from.line, from, to, marker) || + from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) + throw new Error("Inserting collapsed marker partially overlapping an existing one"); + sawCollapsedSpans = true; + } + + if (marker.addToHistory) + addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); + + var curLine = from.line, cm = doc.cm, updateMaxLine; + doc.iter(curLine, to.line + 1, function(line) { + if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) + updateMaxLine = true; + if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); + addMarkedSpan(line, new MarkedSpan(marker, + curLine == from.line ? from.ch : null, + curLine == to.line ? to.ch : null)); + ++curLine; + }); + // lineIsHidden depends on the presence of the spans, so needs a second pass + if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { + if (lineIsHidden(doc, line)) updateLineHeight(line, 0); + }); + + if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); + + if (marker.readOnly) { + sawReadOnlySpans = true; + if (doc.history.done.length || doc.history.undone.length) + doc.clearHistory(); + } + if (marker.collapsed) { + marker.id = ++nextMarkerId; + marker.atomic = true; + } + if (cm) { + // Sync editor state + if (updateMaxLine) cm.curOp.updateMaxLine = true; + if (marker.collapsed) + regChange(cm, from.line, to.line + 1); + else if (marker.className || marker.title || marker.startStyle || marker.endStyle) + for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); + if (marker.atomic) reCheckSelection(cm.doc); + signalLater(cm, "markerAdded", cm, marker); + } + return marker; + } + + // SHARED TEXTMARKERS + + // A shared marker spans multiple linked documents. It is + // implemented as a meta-marker-object controlling multiple normal + // markers. + var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) { + this.markers = markers; + this.primary = primary; + for (var i = 0, me = this; i < markers.length; ++i) { + markers[i].parent = this; + on(markers[i], "clear", function(){me.clear();}); + } + }; + eventMixin(SharedTextMarker); + + SharedTextMarker.prototype.clear = function() { + if (this.explicitlyCleared) return; + this.explicitlyCleared = true; + for (var i = 0; i < this.markers.length; ++i) + this.markers[i].clear(); + signalLater(this, "clear"); + }; + SharedTextMarker.prototype.find = function(side, lineObj) { + return this.primary.find(side, lineObj); + }; + + function markTextShared(doc, from, to, options, type) { + options = copyObj(options); + options.shared = false; + var markers = [markText(doc, from, to, options, type)], primary = markers[0]; + var widget = options.widgetNode; + linkedDocs(doc, function(doc) { + if (widget) options.widgetNode = widget.cloneNode(true); + markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); + for (var i = 0; i < doc.linked.length; ++i) + if (doc.linked[i].isParent) return; + primary = lst(markers); + }); + return new SharedTextMarker(markers, primary); + } + + // TEXTMARKER SPANS + + function MarkedSpan(marker, from, to) { + this.marker = marker; + this.from = from; this.to = to; + } + + // Search an array of spans for a span matching the given marker. + function getMarkedSpanFor(spans, marker) { + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.marker == marker) return span; + } + } + // Remove a span from an array, returning undefined if no spans are + // left (we don't store arrays for lines without spans). + function removeMarkedSpan(spans, span) { + for (var r, i = 0; i < spans.length; ++i) + if (spans[i] != span) (r || (r = [])).push(spans[i]); + return r; + } + // Add a span to a line. + function addMarkedSpan(line, span) { + line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; + span.marker.attachLine(line); + } + + // Used for the algorithm that adjusts markers for a change in the + // document. These functions cut an array of spans at a given + // character position, returning an array of remaining chunks (or + // undefined if nothing remains). + function markedSpansBefore(old, startCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); + if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); + (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); + } + } + return nw; + } + function markedSpansAfter(old, endCh, isInsert) { + if (old) for (var i = 0, nw; i < old.length; ++i) { + var span = old[i], marker = span.marker; + var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); + if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { + var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); + (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, + span.to == null ? null : span.to - endCh)); + } + } + return nw; + } + + // Given a change object, compute the new set of marker spans that + // cover the line in which the change took place. Removes spans + // entirely within the change, reconnects spans belonging to the + // same marker that appear on both sides of the change, and cuts off + // spans partially within the change. Returns an array of span + // arrays with one element for each line in (after) the change. + function stretchSpansOverChange(doc, change) { + var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; + var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; + if (!oldFirst && !oldLast) return null; + + var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; + // Get the spans that 'stick out' on both sides + var first = markedSpansBefore(oldFirst, startCh, isInsert); + var last = markedSpansAfter(oldLast, endCh, isInsert); + + // Next, merge those two ends + var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); + if (first) { + // Fix up .to properties of first + for (var i = 0; i < first.length; ++i) { + var span = first[i]; + if (span.to == null) { + var found = getMarkedSpanFor(last, span.marker); + if (!found) span.to = startCh; + else if (sameLine) span.to = found.to == null ? null : found.to + offset; + } + } + } + if (last) { + // Fix up .from in last (or move them into first in case of sameLine) + for (var i = 0; i < last.length; ++i) { + var span = last[i]; + if (span.to != null) span.to += offset; + if (span.from == null) { + var found = getMarkedSpanFor(first, span.marker); + if (!found) { + span.from = offset; + if (sameLine) (first || (first = [])).push(span); + } + } else { + span.from += offset; + if (sameLine) (first || (first = [])).push(span); + } + } + } + // Make sure we didn't create any zero-length spans + if (first) first = clearEmptySpans(first); + if (last && last != first) last = clearEmptySpans(last); + + var newMarkers = [first]; + if (!sameLine) { + // Fill gap with whole-line-spans + var gap = change.text.length - 2, gapMarkers; + if (gap > 0 && first) + for (var i = 0; i < first.length; ++i) + if (first[i].to == null) + (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); + for (var i = 0; i < gap; ++i) + newMarkers.push(gapMarkers); + newMarkers.push(last); + } + return newMarkers; + } + + // Remove spans that are empty and don't have a clearWhenEmpty + // option of false. + function clearEmptySpans(spans) { + for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) + spans.splice(i--, 1); + } + if (!spans.length) return null; + return spans; + } + + // Used for un/re-doing changes from the history. Combines the + // result of computing the existing spans with the set of spans that + // existed in the history (so that deleting around a span and then + // undoing brings back the span). + function mergeOldSpans(doc, change) { + var old = getOldSpans(doc, change); + var stretched = stretchSpansOverChange(doc, change); + if (!old) return stretched; + if (!stretched) return old; + + for (var i = 0; i < old.length; ++i) { + var oldCur = old[i], stretchCur = stretched[i]; + if (oldCur && stretchCur) { + spans: for (var j = 0; j < stretchCur.length; ++j) { + var span = stretchCur[j]; + for (var k = 0; k < oldCur.length; ++k) + if (oldCur[k].marker == span.marker) continue spans; + oldCur.push(span); + } + } else if (stretchCur) { + old[i] = stretchCur; + } + } + return old; + } + + // Used to 'clip' out readOnly ranges when making a change. + function removeReadOnlyRanges(doc, from, to) { + var markers = null; + doc.iter(from.line, to.line + 1, function(line) { + if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { + var mark = line.markedSpans[i].marker; + if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) + (markers || (markers = [])).push(mark); + } + }); + if (!markers) return null; + var parts = [{from: from, to: to}]; + for (var i = 0; i < markers.length; ++i) { + var mk = markers[i], m = mk.find(0); + for (var j = 0; j < parts.length; ++j) { + var p = parts[j]; + if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; + var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); + if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) + newParts.push({from: p.from, to: m.from}); + if (dto > 0 || !mk.inclusiveRight && !dto) + newParts.push({from: m.to, to: p.to}); + parts.splice.apply(parts, newParts); + j += newParts.length - 1; + } + } + return parts; + } + + // Connect or disconnect spans from a line. + function detachMarkedSpans(line) { + var spans = line.markedSpans; + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.detachLine(line); + line.markedSpans = null; + } + function attachMarkedSpans(line, spans) { + if (!spans) return; + for (var i = 0; i < spans.length; ++i) + spans[i].marker.attachLine(line); + line.markedSpans = spans; + } + + // Helpers used when computing which overlapping collapsed span + // counts as the larger one. + function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } + function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } + + // Returns a number indicating which of two overlapping collapsed + // spans is larger (and thus includes the other). Falls back to + // comparing ids when the spans cover exactly the same range. + function compareCollapsedMarkers(a, b) { + var lenDiff = a.lines.length - b.lines.length; + if (lenDiff != 0) return lenDiff; + var aPos = a.find(), bPos = b.find(); + var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); + if (fromCmp) return -fromCmp; + var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); + if (toCmp) return toCmp; + return b.id - a.id; + } + + // Find out whether a line ends or starts in a collapsed span. If + // so, return the marker for that span. + function collapsedSpanAtSide(line, start) { + var sps = sawCollapsedSpans && line.markedSpans, found; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && + (!found || compareCollapsedMarkers(found, sp.marker) < 0)) + found = sp.marker; + } + return found; + } + function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } + function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } + + // Test whether there exists a collapsed span that partially + // overlaps (covers the start or end, but not both) of a new span. + // Such overlap is not allowed. + function conflictingCollapsedRange(doc, lineNo, from, to, marker) { + var line = getLine(doc, lineNo); + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) { + var sp = sps[i]; + if (!sp.marker.collapsed) continue; + var found = sp.marker.find(0); + var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); + var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); + if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; + if (fromCmp <= 0 && (cmp(found.to, from) || extraRight(sp.marker) - extraLeft(marker)) > 0 || + fromCmp >= 0 && (cmp(found.from, to) || extraLeft(sp.marker) - extraRight(marker)) < 0) + return true; + } + } + + // A visual line is a line as drawn on the screen. Folding, for + // example, can cause multiple logical lines to appear on the same + // visual line. This finds the start of the visual line that the + // given line is part of (usually that is the line itself). + function visualLine(line) { + var merged; + while (merged = collapsedSpanAtStart(line)) + line = merged.find(-1, true).line; + return line; + } + + // Returns an array of logical lines that continue the visual line + // started by the argument, or undefined if there are no such lines. + function visualLineContinued(line) { + var merged, lines; + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + (lines || (lines = [])).push(line); + } + return lines; + } + + // Get the line number of the start of the visual line that the + // given line number is part of. + function visualLineNo(doc, lineN) { + var line = getLine(doc, lineN), vis = visualLine(line); + if (line == vis) return lineN; + return lineNo(vis); + } + // Get the line number of the start of the next visual line after + // the given line. + function visualLineEndNo(doc, lineN) { + if (lineN > doc.lastLine()) return lineN; + var line = getLine(doc, lineN), merged; + if (!lineIsHidden(doc, line)) return lineN; + while (merged = collapsedSpanAtEnd(line)) + line = merged.find(1, true).line; + return lineNo(line) + 1; + } + + // Compute whether a line is hidden. Lines count as hidden when they + // are part of a visual line that starts with another line, or when + // they are entirely covered by collapsed, non-widget span. + function lineIsHidden(doc, line) { + var sps = sawCollapsedSpans && line.markedSpans; + if (sps) for (var sp, i = 0; i < sps.length; ++i) { + sp = sps[i]; + if (!sp.marker.collapsed) continue; + if (sp.from == null) return true; + if (sp.marker.widgetNode) continue; + if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) + return true; + } + } + function lineIsHiddenInner(doc, line, span) { + if (span.to == null) { + var end = span.marker.find(1, true); + return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); + } + if (span.marker.inclusiveRight && span.to == line.text.length) + return true; + for (var sp, i = 0; i < line.markedSpans.length; ++i) { + sp = line.markedSpans[i]; + if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && + (sp.to == null || sp.to != span.from) && + (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && + lineIsHiddenInner(doc, line, sp)) return true; + } + } + + // LINE WIDGETS + + // Line widgets are block elements displayed above or below a line. + + var LineWidget = CodeMirror.LineWidget = function(cm, node, options) { + if (options) for (var opt in options) if (options.hasOwnProperty(opt)) + this[opt] = options[opt]; + this.cm = cm; + this.node = node; + }; + eventMixin(LineWidget); + + function adjustScrollWhenAboveVisible(cm, line, diff) { + if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) + addToScrollPos(cm, null, diff); + } + + LineWidget.prototype.clear = function() { + var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); + if (no == null || !ws) return; + for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); + if (!ws.length) line.widgets = null; + var height = widgetHeight(this); + runInOp(cm, function() { + adjustScrollWhenAboveVisible(cm, line, -height); + regLineChange(cm, no, "widget"); + updateLineHeight(line, Math.max(0, line.height - height)); + }); + }; + LineWidget.prototype.changed = function() { + var oldH = this.height, cm = this.cm, line = this.line; + this.height = null; + var diff = widgetHeight(this) - oldH; + if (!diff) return; + runInOp(cm, function() { + cm.curOp.forceUpdate = true; + adjustScrollWhenAboveVisible(cm, line, diff); + updateLineHeight(line, line.height + diff); + }); + }; + + function widgetHeight(widget) { + if (widget.height != null) return widget.height; + if (!contains(document.body, widget.node)) + removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, "position: relative")); + return widget.height = widget.node.offsetHeight; + } + + function addLineWidget(cm, handle, node, options) { + var widget = new LineWidget(cm, node, options); + if (widget.noHScroll) cm.display.alignWidgets = true; + changeLine(cm, handle, "widget", function(line) { + var widgets = line.widgets || (line.widgets = []); + if (widget.insertAt == null) widgets.push(widget); + else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); + widget.line = line; + if (!lineIsHidden(cm.doc, line)) { + var aboveVisible = heightAtLine(line) < cm.doc.scrollTop; + updateLineHeight(line, line.height + widgetHeight(widget)); + if (aboveVisible) addToScrollPos(cm, null, widget.height); + cm.curOp.forceUpdate = true; + } + return true; + }); + return widget; + } + + // LINE DATA STRUCTURE + + // Line objects. These hold state related to a line, including + // highlighting info (the styles array). + var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { + this.text = text; + attachMarkedSpans(this, markedSpans); + this.height = estimateHeight ? estimateHeight(this) : 1; + }; + eventMixin(Line); + Line.prototype.lineNo = function() { return lineNo(this); }; + + // Change the content (text, markers) of a line. Automatically + // invalidates cached information and tries to re-estimate the + // line's height. + function updateLine(line, text, markedSpans, estimateHeight) { + line.text = text; + if (line.stateAfter) line.stateAfter = null; + if (line.styles) line.styles = null; + if (line.order != null) line.order = null; + detachMarkedSpans(line); + attachMarkedSpans(line, markedSpans); + var estHeight = estimateHeight ? estimateHeight(line) : 1; + if (estHeight != line.height) updateLineHeight(line, estHeight); + } + + // Detach a line from the document tree and its markers. + function cleanUpLine(line) { + line.parent = null; + detachMarkedSpans(line); + } + + // Run the given mode's parser over a line, calling f for each token. + function runMode(cm, text, mode, state, f, forceToEnd) { + var flattenSpans = mode.flattenSpans; + if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; + var curStart = 0, curStyle = null; + var stream = new StringStream(text, cm.options.tabSize), style; + if (text == "" && mode.blankLine) mode.blankLine(state); + while (!stream.eol()) { + if (stream.pos > cm.options.maxHighlightLength) { + flattenSpans = false; + if (forceToEnd) processLine(cm, text, state, stream.pos); + stream.pos = text.length; + style = null; + } else { + style = mode.token(stream, state); + } + if (cm.options.addModeClass) { + var mName = CodeMirror.innerMode(mode, state).mode.name; + if (mName) style = "m-" + (style ? mName + " " + style : mName); + } + if (!flattenSpans || curStyle != style) { + if (curStart < stream.start) f(stream.start, curStyle); + curStart = stream.start; curStyle = style; + } + stream.start = stream.pos; + } + while (curStart < stream.pos) { + // Webkit seems to refuse to render text nodes longer than 57444 characters + var pos = Math.min(stream.pos, curStart + 50000); + f(pos, curStyle); + curStart = pos; + } + } + + // Compute a style array (an array starting with a mode generation + // -- for invalidation -- followed by pairs of end positions and + // style strings), which is used to highlight the tokens on the + // line. + function highlightLine(cm, line, state, forceToEnd) { + // A styles array always starts with a number identifying the + // mode/overlays that it is based on (for easy invalidation). + var st = [cm.state.modeGen]; + // Compute the base array of styles + runMode(cm, line.text, cm.doc.mode, state, function(end, style) { + st.push(end, style); + }, forceToEnd); + + // Run overlays, adjust style array. + for (var o = 0; o < cm.state.overlays.length; ++o) { + var overlay = cm.state.overlays[o], i = 1, at = 0; + runMode(cm, line.text, overlay.mode, true, function(end, style) { + var start = i; + // Ensure there's a token end at the current position, and that i points at it + while (at < end) { + var i_end = st[i]; + if (i_end > end) + st.splice(i, 1, end, st[i+1], i_end); + i += 2; + at = Math.min(end, i_end); + } + if (!style) return; + if (overlay.opaque) { + st.splice(start, i - start, end, style); + i = start + 2; + } else { + for (; start < i; start += 2) { + var cur = st[start+1]; + st[start+1] = cur ? cur + " " + style : style; + } + } + }); + } + + return st; + } + + function getLineStyles(cm, line) { + if (!line.styles || line.styles[0] != cm.state.modeGen) + line.styles = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line))); + return line.styles; + } + + // Lightweight form of highlight -- proceed over this line and + // update state, but don't save a style array. Used for lines that + // aren't currently visible. + function processLine(cm, text, state, startAt) { + var mode = cm.doc.mode; + var stream = new StringStream(text, cm.options.tabSize); + stream.start = stream.pos = startAt || 0; + if (text == "" && mode.blankLine) mode.blankLine(state); + while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { + mode.token(stream, state); + stream.start = stream.pos; + } + } + + // Convert a style as returned by a mode (either null, or a string + // containing one or more styles) to a CSS style. This is cached, + // and also looks for line-wide styles. + var styleToClassCache = {}, styleToClassCacheWithMode = {}; + function interpretTokenStyle(style, builder) { + if (!style) return null; + for (;;) { + var lineClass = style.match(/(?:^|\s+)line-(background-)?(\S+)/); + if (!lineClass) break; + style = style.slice(0, lineClass.index) + style.slice(lineClass.index + lineClass[0].length); + var prop = lineClass[1] ? "bgClass" : "textClass"; + if (builder[prop] == null) + builder[prop] = lineClass[2]; + else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(builder[prop])) + builder[prop] += " " + lineClass[2]; + } + if (/^\s*$/.test(style)) return null; + var cache = builder.cm.options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; + return cache[style] || + (cache[style] = style.replace(/\S+/g, "cm-$&")); + } + + // Render the DOM representation of the text of a line. Also builds + // up a 'line map', which points at the DOM nodes that represent + // specific stretches of text, and is used by the measuring code. + // The returned object contains the DOM node, this map, and + // information about line-wide styles that were set by the mode. + function buildLineContent(cm, lineView) { + // The padding-right forces the element to have a 'border', which + // is needed on Webkit to be able to get line-level bounding + // rectangles for it (in measureChar). + var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); + var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm}; + lineView.measure = {}; + + // Iterate over the logical lines that make up this visual line. + for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { + var line = i ? lineView.rest[i - 1] : lineView.line, order; + builder.pos = 0; + builder.addToken = buildToken; + // Optionally wire in some hacks into the token-rendering + // algorithm, to deal with browser quirks. + if ((ie || webkit) && cm.getOption("lineWrapping")) + builder.addToken = buildTokenSplitSpaces(builder.addToken); + if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) + builder.addToken = buildTokenBadBidi(builder.addToken, order); + builder.map = []; + insertLineContent(line, builder, getLineStyles(cm, line)); + + // Ensure at least a single node is present, for measuring. + if (builder.map.length == 0) + builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); + + // Store the map and a cache object for the current logical line + if (i == 0) { + lineView.measure.map = builder.map; + lineView.measure.cache = {}; + } else { + (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); + (lineView.measure.caches || (lineView.measure.caches = [])).push({}); + } + } + + signal(cm, "renderLine", cm, lineView.line, builder.pre); + return builder; + } + + function defaultSpecialCharPlaceholder(ch) { + var token = elt("span", "\u2022", "cm-invalidchar"); + token.title = "\\u" + ch.charCodeAt(0).toString(16); + return token; + } + + // Build up the DOM representation for a single token, and add it to + // the line map. Takes care to render special characters separately. + function buildToken(builder, text, style, startStyle, endStyle, title) { + if (!text) return; + var special = builder.cm.options.specialChars, mustWrap = false; + if (!special.test(text)) { + builder.col += text.length; + var content = document.createTextNode(text); + builder.map.push(builder.pos, builder.pos + text.length, content); + if (ie_upto8) mustWrap = true; + builder.pos += text.length; + } else { + var content = document.createDocumentFragment(), pos = 0; + while (true) { + special.lastIndex = pos; + var m = special.exec(text); + var skipped = m ? m.index - pos : text.length - pos; + if (skipped) { + var txt = document.createTextNode(text.slice(pos, pos + skipped)); + if (ie_upto8) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.map.push(builder.pos, builder.pos + skipped, txt); + builder.col += skipped; + builder.pos += skipped; + } + if (!m) break; + pos += skipped + 1; + if (m[0] == "\t") { + var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; + var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); + builder.col += tabWidth; + } else { + var txt = builder.cm.options.specialCharPlaceholder(m[0]); + if (ie_upto8) content.appendChild(elt("span", [txt])); + else content.appendChild(txt); + builder.col += 1; + } + builder.map.push(builder.pos, builder.pos + 1, txt); + builder.pos++; + } + } + if (style || startStyle || endStyle || mustWrap) { + var fullStyle = style || ""; + if (startStyle) fullStyle += startStyle; + if (endStyle) fullStyle += endStyle; + var token = elt("span", [content], fullStyle); + if (title) token.title = title; + return builder.content.appendChild(token); + } + builder.content.appendChild(content); + } + + function buildTokenSplitSpaces(inner) { + function split(old) { + var out = " "; + for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; + out += " "; + return out; + } + return function(builder, text, style, startStyle, endStyle, title) { + inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title); + }; + } + + // Work around nonsense dimensions being reported for stretches of + // right-to-left text. + function buildTokenBadBidi(inner, order) { + return function(builder, text, style, startStyle, endStyle, title) { + style = style ? style + " cm-force-border" : "cm-force-border"; + var start = builder.pos, end = start + text.length; + for (;;) { + // Find the part that overlaps with the start of this text + for (var i = 0; i < order.length; i++) { + var part = order[i]; + if (part.to > start && part.from <= start) break; + } + if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title); + inner(builder, text.slice(0, part.to - start), style, startStyle, null, title); + startStyle = null; + text = text.slice(part.to - start); + start = part.to; + } + }; + } + + function buildCollapsedSpan(builder, size, marker, ignoreWidget) { + var widget = !ignoreWidget && marker.widgetNode; + if (widget) { + builder.map.push(builder.pos, builder.pos + size, widget); + builder.content.appendChild(widget); + } + builder.pos += size; + } + + // Outputs a number of spans to make up a line, taking highlighting + // and marked text into account. + function insertLineContent(line, builder, styles) { + var spans = line.markedSpans, allText = line.text, at = 0; + if (!spans) { + for (var i = 1; i < styles.length; i+=2) + builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder)); + return; + } + + var len = allText.length, pos = 0, i = 1, text = "", style; + var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; + for (;;) { + if (nextChange == pos) { // Update current marker set + spanStyle = spanEndStyle = spanStartStyle = title = ""; + collapsed = null; nextChange = Infinity; + var foundBookmarks = []; + for (var j = 0; j < spans.length; ++j) { + var sp = spans[j], m = sp.marker; + if (sp.from <= pos && (sp.to == null || sp.to > pos)) { + if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; } + if (m.className) spanStyle += " " + m.className; + if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; + if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle; + if (m.title && !title) title = m.title; + if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) + collapsed = sp; + } else if (sp.from > pos && nextChange > sp.from) { + nextChange = sp.from; + } + if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m); + } + if (collapsed && (collapsed.from || 0) == pos) { + buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, + collapsed.marker, collapsed.from == null); + if (collapsed.to == null) return; + } + if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j) + buildCollapsedSpan(builder, 0, foundBookmarks[j]); + } + if (pos >= len) break; + + var upto = Math.min(len, nextChange); + while (true) { + if (text) { + var end = pos + text.length; + if (!collapsed) { + var tokenText = end > upto ? text.slice(0, upto - pos) : text; + builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, + spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title); + } + if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} + pos = end; + spanStartStyle = ""; + } + text = allText.slice(at, at = styles[i++]); + style = interpretTokenStyle(styles[i++], builder); + } + } + } + + // DOCUMENT DATA STRUCTURE + + // By default, updates that start and end at the beginning of a line + // are treated specially, in order to make the association of line + // widgets and marker elements with the text behave more intuitive. + function isWholeLineUpdate(doc, change) { + return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && + (!doc.cm || doc.cm.options.wholeLineUpdateBefore); + } + + // Perform a change on the document data structure. + function updateDoc(doc, change, markedSpans, estimateHeight) { + function spansFor(n) {return markedSpans ? markedSpans[n] : null;} + function update(line, text, spans) { + updateLine(line, text, spans, estimateHeight); + signalLater(line, "change", line, change); + } + + var from = change.from, to = change.to, text = change.text; + var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); + var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; + + // Adjust the line structure + if (isWholeLineUpdate(doc, change)) { + // This is a whole-line replace. Treated specially to make + // sure line objects move the way they are supposed to. + for (var i = 0, added = []; i < text.length - 1; ++i) + added.push(new Line(text[i], spansFor(i), estimateHeight)); + update(lastLine, lastLine.text, lastSpans); + if (nlines) doc.remove(from.line, nlines); + if (added.length) doc.insert(from.line, added); + } else if (firstLine == lastLine) { + if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); + } else { + for (var added = [], i = 1; i < text.length - 1; ++i) + added.push(new Line(text[i], spansFor(i), estimateHeight)); + added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + doc.insert(from.line + 1, added); + } + } else if (text.length == 1) { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); + doc.remove(from.line + 1, nlines); + } else { + update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); + update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); + for (var i = 1, added = []; i < text.length - 1; ++i) + added.push(new Line(text[i], spansFor(i), estimateHeight)); + if (nlines > 1) doc.remove(from.line + 1, nlines - 1); + doc.insert(from.line + 1, added); + } + + signalLater(doc, "change", doc, change); + } + + // The document is represented as a BTree consisting of leaves, with + // chunk of lines in them, and branches, with up to ten leaves or + // other branch nodes below them. The top node is always a branch + // node, and is the document object itself (meaning it has + // additional methods and properties). + // + // All nodes have parent links. The tree is used both to go from + // line numbers to line objects, and to go from objects to numbers. + // It also indexes by height, and is used to convert between height + // and line object, and to find the total height of the document. + // + // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html + + function LeafChunk(lines) { + this.lines = lines; + this.parent = null; + for (var i = 0, height = 0; i < lines.length; ++i) { + lines[i].parent = this; + height += lines[i].height; + } + this.height = height; + } + + LeafChunk.prototype = { + chunkSize: function() { return this.lines.length; }, + // Remove the n lines at offset 'at'. + removeInner: function(at, n) { + for (var i = at, e = at + n; i < e; ++i) { + var line = this.lines[i]; + this.height -= line.height; + cleanUpLine(line); + signalLater(line, "delete"); + } + this.lines.splice(at, n); + }, + // Helper used to collapse a small branch into a single leaf. + collapse: function(lines) { + lines.push.apply(lines, this.lines); + }, + // Insert the given array of lines at offset 'at', count them as + // having the given height. + insertInner: function(at, lines, height) { + this.height += height; + this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); + for (var i = 0; i < lines.length; ++i) lines[i].parent = this; + }, + // Used to iterate over a part of the tree. + iterN: function(at, n, op) { + for (var e = at + n; at < e; ++at) + if (op(this.lines[at])) return true; + } + }; + + function BranchChunk(children) { + this.children = children; + var size = 0, height = 0; + for (var i = 0; i < children.length; ++i) { + var ch = children[i]; + size += ch.chunkSize(); height += ch.height; + ch.parent = this; + } + this.size = size; + this.height = height; + this.parent = null; + } + + BranchChunk.prototype = { + chunkSize: function() { return this.size; }, + removeInner: function(at, n) { + this.size -= n; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var rm = Math.min(n, sz - at), oldHeight = child.height; + child.removeInner(at, rm); + this.height -= oldHeight - child.height; + if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } + if ((n -= rm) == 0) break; + at = 0; + } else at -= sz; + } + // If the result is smaller than 25 lines, ensure that it is a + // single leaf node. + if (this.size - n < 25 && + (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { + var lines = []; + this.collapse(lines); + this.children = [new LeafChunk(lines)]; + this.children[0].parent = this; + } + }, + collapse: function(lines) { + for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); + }, + insertInner: function(at, lines, height) { + this.size += lines.length; + this.height += height; + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at <= sz) { + child.insertInner(at, lines, height); + if (child.lines && child.lines.length > 50) { + while (child.lines.length > 50) { + var spilled = child.lines.splice(child.lines.length - 25, 25); + var newleaf = new LeafChunk(spilled); + child.height -= newleaf.height; + this.children.splice(i + 1, 0, newleaf); + newleaf.parent = this; + } + this.maybeSpill(); + } + break; + } + at -= sz; + } + }, + // When a node has grown, check whether it should be split. + maybeSpill: function() { + if (this.children.length <= 10) return; + var me = this; + do { + var spilled = me.children.splice(me.children.length - 5, 5); + var sibling = new BranchChunk(spilled); + if (!me.parent) { // Become the parent node + var copy = new BranchChunk(me.children); + copy.parent = me; + me.children = [copy, sibling]; + me = copy; + } else { + me.size -= sibling.size; + me.height -= sibling.height; + var myIndex = indexOf(me.parent.children, me); + me.parent.children.splice(myIndex + 1, 0, sibling); + } + sibling.parent = me.parent; + } while (me.children.length > 10); + me.parent.maybeSpill(); + }, + iterN: function(at, n, op) { + for (var i = 0; i < this.children.length; ++i) { + var child = this.children[i], sz = child.chunkSize(); + if (at < sz) { + var used = Math.min(n, sz - at); + if (child.iterN(at, used, op)) return true; + if ((n -= used) == 0) break; + at = 0; + } else at -= sz; + } + } + }; + + var nextDocId = 0; + var Doc = CodeMirror.Doc = function(text, mode, firstLine) { + if (!(this instanceof Doc)) return new Doc(text, mode, firstLine); + if (firstLine == null) firstLine = 0; + + BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); + this.first = firstLine; + this.scrollTop = this.scrollLeft = 0; + this.cantEdit = false; + this.cleanGeneration = 1; + this.frontier = firstLine; + var start = Pos(firstLine, 0); + this.sel = simpleSelection(start); + this.history = new History(null); + this.id = ++nextDocId; + this.modeOption = mode; + + if (typeof text == "string") text = splitLines(text); + updateDoc(this, {from: start, to: start, text: text}); + setSelection(this, simpleSelection(start), sel_dontScroll); + }; + + Doc.prototype = createObj(BranchChunk.prototype, { + constructor: Doc, + // Iterate over the document. Supports two forms -- with only one + // argument, it calls that for each line in the document. With + // three, it iterates over the range given by the first two (with + // the second being non-inclusive). + iter: function(from, to, op) { + if (op) this.iterN(from - this.first, to - from, op); + else this.iterN(this.first, this.first + this.size, from); + }, + + // Non-public interface for adding and removing lines. + insert: function(at, lines) { + var height = 0; + for (var i = 0; i < lines.length; ++i) height += lines[i].height; + this.insertInner(at - this.first, lines, height); + }, + remove: function(at, n) { this.removeInner(at - this.first, n); }, + + // From here, the methods are part of the public interface. Most + // are also available from CodeMirror (editor) instances. + + getValue: function(lineSep) { + var lines = getLines(this, this.first, this.first + this.size); + if (lineSep === false) return lines; + return lines.join(lineSep || "\n"); + }, + setValue: docMethodOp(function(code) { + var top = Pos(this.first, 0), last = this.first + this.size - 1; + makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), + text: splitLines(code), origin: "setValue"}, true); + setSelection(this, simpleSelection(top)); + }), + replaceRange: function(code, from, to, origin) { + from = clipPos(this, from); + to = to ? clipPos(this, to) : from; + replaceRange(this, code, from, to, origin); + }, + getRange: function(from, to, lineSep) { + var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); + if (lineSep === false) return lines; + return lines.join(lineSep || "\n"); + }, + + getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, + + getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, + getLineNumber: function(line) {return lineNo(line);}, + + getLineHandleVisualStart: function(line) { + if (typeof line == "number") line = getLine(this, line); + return visualLine(line); + }, + + lineCount: function() {return this.size;}, + firstLine: function() {return this.first;}, + lastLine: function() {return this.first + this.size - 1;}, + + clipPos: function(pos) {return clipPos(this, pos);}, + + getCursor: function(start) { + var range = this.sel.primary(), pos; + if (start == null || start == "head") pos = range.head; + else if (start == "anchor") pos = range.anchor; + else if (start == "end" || start == "to" || start === false) pos = range.to(); + else pos = range.from(); + return pos; + }, + listSelections: function() { return this.sel.ranges; }, + somethingSelected: function() {return this.sel.somethingSelected();}, + + setCursor: docMethodOp(function(line, ch, options) { + setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); + }), + setSelection: docMethodOp(function(anchor, head, options) { + setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); + }), + extendSelection: docMethodOp(function(head, other, options) { + extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); + }), + extendSelections: docMethodOp(function(heads, options) { + extendSelections(this, clipPosArray(this, heads, options)); + }), + extendSelectionsBy: docMethodOp(function(f, options) { + extendSelections(this, map(this.sel.ranges, f), options); + }), + setSelections: docMethodOp(function(ranges, primary, options) { + if (!ranges.length) return; + for (var i = 0, out = []; i < ranges.length; i++) + out[i] = new Range(clipPos(this, ranges[i].anchor), + clipPos(this, ranges[i].head)); + if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); + setSelection(this, normalizeSelection(out, primary), options); + }), + addSelection: docMethodOp(function(anchor, head, options) { + var ranges = this.sel.ranges.slice(0); + ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); + setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); + }), + + getSelection: function(lineSep) { + var ranges = this.sel.ranges, lines; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + lines = lines ? lines.concat(sel) : sel; + } + if (lineSep === false) return lines; + else return lines.join(lineSep || "\n"); + }, + getSelections: function(lineSep) { + var parts = [], ranges = this.sel.ranges; + for (var i = 0; i < ranges.length; i++) { + var sel = getBetween(this, ranges[i].from(), ranges[i].to()); + if (lineSep !== false) sel = sel.join(lineSep || "\n"); + parts[i] = sel; + } + return parts; + }, + replaceSelection: docMethodOp(function(code, collapse, origin) { + var dup = []; + for (var i = 0; i < this.sel.ranges.length; i++) + dup[i] = code; + this.replaceSelections(dup, collapse, origin || "+input"); + }), + replaceSelections: function(code, collapse, origin) { + var changes = [], sel = this.sel; + for (var i = 0; i < sel.ranges.length; i++) { + var range = sel.ranges[i]; + changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin}; + } + var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); + for (var i = changes.length - 1; i >= 0; i--) + makeChange(this, changes[i]); + if (newSel) setSelectionReplaceHistory(this, newSel); + else if (this.cm) ensureCursorVisible(this.cm); + }, + undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), + redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), + undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), + redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), + + setExtending: function(val) {this.extend = val;}, + getExtending: function() {return this.extend;}, + + historySize: function() { + var hist = this.history, done = 0, undone = 0; + for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; + for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; + return {undo: done, redo: undone}; + }, + clearHistory: function() {this.history = new History(this.history.maxGeneration);}, + + markClean: function() { + this.cleanGeneration = this.changeGeneration(true); + }, + changeGeneration: function(forceSplit) { + if (forceSplit) + this.history.lastOp = this.history.lastOrigin = null; + return this.history.generation; + }, + isClean: function (gen) { + return this.history.generation == (gen || this.cleanGeneration); + }, + + getHistory: function() { + return {done: copyHistoryArray(this.history.done), + undone: copyHistoryArray(this.history.undone)}; + }, + setHistory: function(histData) { + var hist = this.history = new History(this.history.maxGeneration); + hist.done = copyHistoryArray(histData.done.slice(0), null, true); + hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); + }, + + markText: function(from, to, options) { + return markText(this, clipPos(this, from), clipPos(this, to), options, "range"); + }, + setBookmark: function(pos, options) { + var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), + insertLeft: options && options.insertLeft, + clearWhenEmpty: false, shared: options && options.shared}; + pos = clipPos(this, pos); + return markText(this, pos, pos, realOpts, "bookmark"); + }, + findMarksAt: function(pos) { + pos = clipPos(this, pos); + var markers = [], spans = getLine(this, pos.line).markedSpans; + if (spans) for (var i = 0; i < spans.length; ++i) { + var span = spans[i]; + if ((span.from == null || span.from <= pos.ch) && + (span.to == null || span.to >= pos.ch)) + markers.push(span.marker.parent || span.marker); + } + return markers; + }, + findMarks: function(from, to) { + from = clipPos(this, from); to = clipPos(this, to); + var found = [], lineNo = from.line; + this.iter(from.line, to.line + 1, function(line) { + var spans = line.markedSpans; + if (spans) for (var i = 0; i < spans.length; i++) { + var span = spans[i]; + if (!(lineNo == from.line && from.ch > span.to || + span.from == null && lineNo != from.line|| + lineNo == to.line && span.from > to.ch)) + found.push(span.marker.parent || span.marker); + } + ++lineNo; + }); + return found; + }, + getAllMarks: function() { + var markers = []; + this.iter(function(line) { + var sps = line.markedSpans; + if (sps) for (var i = 0; i < sps.length; ++i) + if (sps[i].from != null) markers.push(sps[i].marker); + }); + return markers; + }, + + posFromIndex: function(off) { + var ch, lineNo = this.first; + this.iter(function(line) { + var sz = line.text.length + 1; + if (sz > off) { ch = off; return true; } + off -= sz; + ++lineNo; + }); + return clipPos(this, Pos(lineNo, ch)); + }, + indexFromPos: function (coords) { + coords = clipPos(this, coords); + var index = coords.ch; + if (coords.line < this.first || coords.ch < 0) return 0; + this.iter(this.first, coords.line, function (line) { + index += line.text.length + 1; + }); + return index; + }, + + copy: function(copyHistory) { + var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first); + doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; + doc.sel = this.sel; + doc.extend = false; + if (copyHistory) { + doc.history.undoDepth = this.history.undoDepth; + doc.setHistory(this.getHistory()); + } + return doc; + }, + + linkedDoc: function(options) { + if (!options) options = {}; + var from = this.first, to = this.first + this.size; + if (options.from != null && options.from > from) from = options.from; + if (options.to != null && options.to < to) to = options.to; + var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from); + if (options.sharedHist) copy.history = this.history; + (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); + copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; + return copy; + }, + unlinkDoc: function(other) { + if (other instanceof CodeMirror) other = other.doc; + if (this.linked) for (var i = 0; i < this.linked.length; ++i) { + var link = this.linked[i]; + if (link.doc != other) continue; + this.linked.splice(i, 1); + other.unlinkDoc(this); + break; + } + // If the histories were shared, split them again + if (other.history == this.history) { + var splitIds = [other.id]; + linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); + other.history = new History(null); + other.history.done = copyHistoryArray(this.history.done, splitIds); + other.history.undone = copyHistoryArray(this.history.undone, splitIds); + } + }, + iterLinkedDocs: function(f) {linkedDocs(this, f);}, + + getMode: function() {return this.mode;}, + getEditor: function() {return this.cm;} + }); + + // Public alias. + Doc.prototype.eachLine = Doc.prototype.iter; + + // Set up methods on CodeMirror's prototype to redirect to the editor's document. + var dontDelegate = "iter insert remove copy getEditor".split(" "); + for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) + CodeMirror.prototype[prop] = (function(method) { + return function() {return method.apply(this.doc, arguments);}; + })(Doc.prototype[prop]); + + eventMixin(Doc); + + // Call f for all linked documents. + function linkedDocs(doc, f, sharedHistOnly) { + function propagate(doc, skip, sharedHist) { + if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { + var rel = doc.linked[i]; + if (rel.doc == skip) continue; + var shared = sharedHist && rel.sharedHist; + if (sharedHistOnly && !shared) continue; + f(rel.doc, shared); + propagate(rel.doc, doc, shared); + } + } + propagate(doc, null, true); + } + + // Attach a document to an editor. + function attachDoc(cm, doc) { + if (doc.cm) throw new Error("This document is already in use."); + cm.doc = doc; + doc.cm = cm; + estimateLineHeights(cm); + loadMode(cm); + if (!cm.options.lineWrapping) findMaxLine(cm); + cm.options.mode = doc.modeOption; + regChange(cm); + } + + // LINE UTILITIES + + // Find the line object corresponding to the given line number. + function getLine(doc, n) { + n -= doc.first; + if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); + for (var chunk = doc; !chunk.lines;) { + for (var i = 0;; ++i) { + var child = chunk.children[i], sz = child.chunkSize(); + if (n < sz) { chunk = child; break; } + n -= sz; + } + } + return chunk.lines[n]; + } + + // Get the part of a document between two positions, as an array of + // strings. + function getBetween(doc, start, end) { + var out = [], n = start.line; + doc.iter(start.line, end.line + 1, function(line) { + var text = line.text; + if (n == end.line) text = text.slice(0, end.ch); + if (n == start.line) text = text.slice(start.ch); + out.push(text); + ++n; + }); + return out; + } + // Get the lines between from and to, as array of strings. + function getLines(doc, from, to) { + var out = []; + doc.iter(from, to, function(line) { out.push(line.text); }); + return out; + } + + // Update the height of a line, propagating the height change + // upwards to parent nodes. + function updateLineHeight(line, height) { + var diff = height - line.height; + if (diff) for (var n = line; n; n = n.parent) n.height += diff; + } + + // Given a line object, find its line number by walking up through + // its parent links. + function lineNo(line) { + if (line.parent == null) return null; + var cur = line.parent, no = indexOf(cur.lines, line); + for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { + for (var i = 0;; ++i) { + if (chunk.children[i] == cur) break; + no += chunk.children[i].chunkSize(); + } + } + return no + cur.first; + } + + // Find the line at the given vertical position, using the height + // information in the document tree. + function lineAtHeight(chunk, h) { + var n = chunk.first; + outer: do { + for (var i = 0; i < chunk.children.length; ++i) { + var child = chunk.children[i], ch = child.height; + if (h < ch) { chunk = child; continue outer; } + h -= ch; + n += child.chunkSize(); + } + return n; + } while (!chunk.lines); + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i], lh = line.height; + if (h < lh) break; + h -= lh; + } + return n + i; + } + + + // Find the height above the given line. + function heightAtLine(lineObj) { + lineObj = visualLine(lineObj); + + var h = 0, chunk = lineObj.parent; + for (var i = 0; i < chunk.lines.length; ++i) { + var line = chunk.lines[i]; + if (line == lineObj) break; + else h += line.height; + } + for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { + for (var i = 0; i < p.children.length; ++i) { + var cur = p.children[i]; + if (cur == chunk) break; + else h += cur.height; + } + } + return h; + } + + // Get the bidi ordering for the given line (and cache it). Returns + // false for lines that are fully left-to-right, and an array of + // BidiSpan objects otherwise. + function getOrder(line) { + var order = line.order; + if (order == null) order = line.order = bidiOrdering(line.text); + return order; + } + + // HISTORY + + function History(startGen) { + // Arrays of change events and selections. Doing something adds an + // event to done and clears undo. Undoing moves events from done + // to undone, redoing moves them in the other direction. + this.done = []; this.undone = []; + this.undoDepth = Infinity; + // Used to track when changes can be merged into a single undo + // event + this.lastModTime = this.lastSelTime = 0; + this.lastOp = null; + this.lastOrigin = this.lastSelOrigin = null; + // Used by the isClean() method + this.generation = this.maxGeneration = startGen || 1; + } + + // Create a history change event from an updateDoc-style change + // object. + function historyChangeFromChange(doc, change) { + var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; + attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); + linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); + return histChange; + } + + // Pop all selection events off the end of a history array. Stop at + // a change event. + function clearSelectionEvents(array) { + while (array.length) { + var last = lst(array); + if (last.ranges) array.pop(); + else break; + } + } + + // Find the top change event in the history. Pop off selection + // events that are in the way. + function lastChangeEvent(hist, force) { + if (force) { + clearSelectionEvents(hist.done); + return lst(hist.done); + } else if (hist.done.length && !lst(hist.done).ranges) { + return lst(hist.done); + } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { + hist.done.pop(); + return lst(hist.done); + } + } + + // Register a change in the history. Merges changes that are within + // a single operation, ore are close together with an origin that + // allows merging (starting with "+") into a single event. + function addChangeToHistory(doc, change, selAfter, opId) { + var hist = doc.history; + hist.undone.length = 0; + var time = +new Date, cur; + + if ((hist.lastOp == opId || + hist.lastOrigin == change.origin && change.origin && + ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || + change.origin.charAt(0) == "*")) && + (cur = lastChangeEvent(hist, hist.lastOp == opId))) { + // Merge this change into the last event + var last = lst(cur.changes); + if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { + // Optimized case for simple insertion -- don't want to add + // new changesets for every character typed + last.to = changeEnd(change); + } else { + // Add new sub-event + cur.changes.push(historyChangeFromChange(doc, change)); + } + } else { + // Can not be merged, start a new event. + var before = lst(hist.done); + if (!before || !before.ranges) + pushSelectionToHistory(doc.sel, hist.done); + cur = {changes: [historyChangeFromChange(doc, change)], + generation: hist.generation}; + hist.done.push(cur); + while (hist.done.length > hist.undoDepth) { + hist.done.shift(); + if (!hist.done[0].ranges) hist.done.shift(); + } + } + hist.done.push(selAfter); + hist.generation = ++hist.maxGeneration; + hist.lastModTime = hist.lastSelTime = time; + hist.lastOp = opId; + hist.lastOrigin = hist.lastSelOrigin = change.origin; + + if (!last) signal(doc, "historyAdded"); + } + + function selectionEventCanBeMerged(doc, origin, prev, sel) { + var ch = origin.charAt(0); + return ch == "*" || + ch == "+" && + prev.ranges.length == sel.ranges.length && + prev.somethingSelected() == sel.somethingSelected() && + new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); + } + + // Called whenever the selection changes, sets the new selection as + // the pending selection in the history, and pushes the old pending + // selection into the 'done' array when it was significantly + // different (in number of selected ranges, emptiness, or time). + function addSelectionToHistory(doc, sel, opId, options) { + var hist = doc.history, origin = options && options.origin; + + // A new event is started when the previous origin does not match + // the current, or the origins don't allow matching. Origins + // starting with * are always merged, those starting with + are + // merged when similar and close together in time. + if (opId == hist.lastOp || + (origin && hist.lastSelOrigin == origin && + (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || + selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) + hist.done[hist.done.length - 1] = sel; + else + pushSelectionToHistory(sel, hist.done); + + hist.lastSelTime = +new Date; + hist.lastSelOrigin = origin; + hist.lastOp = opId; + if (options && options.clearRedo !== false) + clearSelectionEvents(hist.undone); + } + + function pushSelectionToHistory(sel, dest) { + var top = lst(dest); + if (!(top && top.ranges && top.equals(sel))) + dest.push(sel); + } + + // Used to store marked span information in the history. + function attachLocalSpans(doc, change, from, to) { + var existing = change["spans_" + doc.id], n = 0; + doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { + if (line.markedSpans) + (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; + ++n; + }); + } + + // When un/re-doing restores text containing marked spans, those + // that have been explicitly cleared should not be restored. + function removeClearedSpans(spans) { + if (!spans) return null; + for (var i = 0, out; i < spans.length; ++i) { + if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } + else if (out) out.push(spans[i]); + } + return !out ? spans : out.length ? out : null; + } + + // Retrieve and filter the old marked spans stored in a change event. + function getOldSpans(doc, change) { + var found = change["spans_" + doc.id]; + if (!found) return null; + for (var i = 0, nw = []; i < change.text.length; ++i) + nw.push(removeClearedSpans(found[i])); + return nw; + } + + // Used both to provide a JSON-safe object in .getHistory, and, when + // detaching a document, to split the history in two + function copyHistoryArray(events, newGroup, instantiateSel) { + for (var i = 0, copy = []; i < events.length; ++i) { + var event = events[i]; + if (event.ranges) { + copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); + continue; + } + var changes = event.changes, newChanges = []; + copy.push({changes: newChanges}); + for (var j = 0; j < changes.length; ++j) { + var change = changes[j], m; + newChanges.push({from: change.from, to: change.to, text: change.text}); + if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { + if (indexOf(newGroup, Number(m[1])) > -1) { + lst(newChanges)[prop] = change[prop]; + delete change[prop]; + } + } + } + } + return copy; + } + + // Rebasing/resetting history to deal with externally-sourced changes + + function rebaseHistSelSingle(pos, from, to, diff) { + if (to < pos.line) { + pos.line += diff; + } else if (from < pos.line) { + pos.line = from; + pos.ch = 0; + } + } + + // Tries to rebase an array of history events given a change in the + // document. If the change touches the same lines as the event, the + // event, and everything 'behind' it, is discarded. If the change is + // before the event, the event's positions are updated. Uses a + // copy-on-write scheme for the positions, to avoid having to + // reallocate them all on every rebase, but also avoid problems with + // shared position objects being unsafely updated. + function rebaseHistArray(array, from, to, diff) { + for (var i = 0; i < array.length; ++i) { + var sub = array[i], ok = true; + if (sub.ranges) { + if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } + for (var j = 0; j < sub.ranges.length; j++) { + rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); + rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); + } + continue; + } + for (var j = 0; j < sub.changes.length; ++j) { + var cur = sub.changes[j]; + if (to < cur.from.line) { + cur.from = Pos(cur.from.line + diff, cur.from.ch); + cur.to = Pos(cur.to.line + diff, cur.to.ch); + } else if (from <= cur.to.line) { + ok = false; + break; + } + } + if (!ok) { + array.splice(0, i + 1); + i = 0; + } + } + } + + function rebaseHist(hist, change) { + var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; + rebaseHistArray(hist.done, from, to, diff); + rebaseHistArray(hist.undone, from, to, diff); + } + + // EVENT UTILITIES + + // Due to the fact that we still support jurassic IE versions, some + // compatibility wrappers are needed. + + var e_preventDefault = CodeMirror.e_preventDefault = function(e) { + if (e.preventDefault) e.preventDefault(); + else e.returnValue = false; + }; + var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) { + if (e.stopPropagation) e.stopPropagation(); + else e.cancelBubble = true; + }; + function e_defaultPrevented(e) { + return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; + } + var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);}; + + function e_target(e) {return e.target || e.srcElement;} + function e_button(e) { + var b = e.which; + if (b == null) { + if (e.button & 1) b = 1; + else if (e.button & 2) b = 3; + else if (e.button & 4) b = 2; + } + if (mac && e.ctrlKey && b == 1) b = 3; + return b; + } + + // EVENT HANDLING + + // Lightweight event framework. on/off also work on DOM nodes, + // registering native DOM handlers. + + var on = CodeMirror.on = function(emitter, type, f) { + if (emitter.addEventListener) + emitter.addEventListener(type, f, false); + else if (emitter.attachEvent) + emitter.attachEvent("on" + type, f); + else { + var map = emitter._handlers || (emitter._handlers = {}); + var arr = map[type] || (map[type] = []); + arr.push(f); + } + }; + + var off = CodeMirror.off = function(emitter, type, f) { + if (emitter.removeEventListener) + emitter.removeEventListener(type, f, false); + else if (emitter.detachEvent) + emitter.detachEvent("on" + type, f); + else { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + for (var i = 0; i < arr.length; ++i) + if (arr[i] == f) { arr.splice(i, 1); break; } + } + }; + + var signal = CodeMirror.signal = function(emitter, type /*, values...*/) { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + var args = Array.prototype.slice.call(arguments, 2); + for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args); + }; + + // Often, we want to signal events at a point where we are in the + // middle of some work, but don't want the handler to start calling + // other methods on the editor, which might be in an inconsistent + // state or simply not expect any other events to happen. + // signalLater looks whether there are any handlers, and schedules + // them to be executed when the last operation ends, or, if no + // operation is active, when a timeout fires. + var delayedCallbacks, delayedCallbackDepth = 0; + function signalLater(emitter, type /*, values...*/) { + var arr = emitter._handlers && emitter._handlers[type]; + if (!arr) return; + var args = Array.prototype.slice.call(arguments, 2); + if (!delayedCallbacks) { + ++delayedCallbackDepth; + delayedCallbacks = []; + setTimeout(fireDelayed, 0); + } + function bnd(f) {return function(){f.apply(null, args);};}; + for (var i = 0; i < arr.length; ++i) + delayedCallbacks.push(bnd(arr[i])); + } + + function fireDelayed() { + --delayedCallbackDepth; + var delayed = delayedCallbacks; + delayedCallbacks = null; + for (var i = 0; i < delayed.length; ++i) delayed[i](); + } + + // The DOM events that CodeMirror handles can be overridden by + // registering a (non-DOM) handler on the editor for the event name, + // and preventDefault-ing the event in that handler. + function signalDOMEvent(cm, e, override) { + signal(cm, override || e.type, cm, e); + return e_defaultPrevented(e) || e.codemirrorIgnore; + } + + function hasHandler(emitter, type) { + var arr = emitter._handlers && emitter._handlers[type]; + return arr && arr.length > 0; + } + + // Add on and off methods to a constructor's prototype, to make + // registering events on such objects more convenient. + function eventMixin(ctor) { + ctor.prototype.on = function(type, f) {on(this, type, f);}; + ctor.prototype.off = function(type, f) {off(this, type, f);}; + } + + // MISC UTILITIES + + // Number of pixels added to scroller and sizer to hide scrollbar + var scrollerCutOff = 30; + + // Returned or thrown by various protocols to signal 'I'm not + // handling this'. + var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; + + // Reused option objects for setSelection & friends + var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; + + function Delayed() {this.id = null;} + Delayed.prototype.set = function(ms, f) { + clearTimeout(this.id); + this.id = setTimeout(f, ms); + }; + + // Counts the column offset in a string, taking tabs into account. + // Used mostly to find indentation. + var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) { + if (end == null) { + end = string.search(/[^\s\u00a0]/); + if (end == -1) end = string.length; + } + for (var i = startIndex || 0, n = startValue || 0;;) { + var nextTab = string.indexOf("\t", i); + if (nextTab < 0 || nextTab >= end) + return n + (end - i); + n += nextTab - i; + n += tabSize - (n % tabSize); + i = nextTab + 1; + } + }; + + // The inverse of countColumn -- find the offset that corresponds to + // a particular column. + function findColumn(string, goal, tabSize) { + for (var pos = 0, col = 0;;) { + var nextTab = string.indexOf("\t", pos); + if (nextTab == -1) nextTab = string.length; + var skipped = nextTab - pos; + if (nextTab == string.length || col + skipped >= goal) + return pos + Math.min(skipped, goal - col); + col += nextTab - pos; + col += tabSize - (col % tabSize); + pos = nextTab + 1; + if (col >= goal) return pos; + } + } + + var spaceStrs = [""]; + function spaceStr(n) { + while (spaceStrs.length <= n) + spaceStrs.push(lst(spaceStrs) + " "); + return spaceStrs[n]; + } + + function lst(arr) { return arr[arr.length-1]; } + + var selectInput = function(node) { node.select(); }; + if (ios) // Mobile Safari apparently has a bug where select() is broken. + selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; + else if (ie) // Suppress mysterious IE10 errors + selectInput = function(node) { try { node.select(); } catch(_e) {} }; + + function indexOf(array, elt) { + for (var i = 0; i < array.length; ++i) + if (array[i] == elt) return i; + return -1; + } + if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); }; + function map(array, f) { + var out = []; + for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); + return out; + } + if ([].map) map = function(array, f) { return array.map(f); }; + + function createObj(base, props) { + var inst; + if (Object.create) { + inst = Object.create(base); + } else { + var ctor = function() {}; + ctor.prototype = base; + inst = new ctor(); + } + if (props) copyObj(props, inst); + return inst; + }; + + function copyObj(obj, target) { + if (!target) target = {}; + for (var prop in obj) if (obj.hasOwnProperty(prop)) target[prop] = obj[prop]; + return target; + } + + function bind(f) { + var args = Array.prototype.slice.call(arguments, 1); + return function(){return f.apply(null, args);}; + } + + var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; + var isWordChar = CodeMirror.isWordChar = function(ch) { + return /\w/.test(ch) || ch > "\x80" && + (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); + }; + + function isEmpty(obj) { + for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; + return true; + } + + // Extending unicode characters. A series of a non-extending char + + // any number of extending chars is treated as a single unit as far + // as editing and measuring is concerned. This is not fully correct, + // since some scripts/fonts/browsers also treat other configurations + // of code points as a group. + var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; + function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } + + // DOM UTILITIES + + function elt(tag, content, className, style) { + var e = document.createElement(tag); + if (className) e.className = className; + if (style) e.style.cssText = style; + if (typeof content == "string") e.appendChild(document.createTextNode(content)); + else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); + return e; + } + + var range; + if (document.createRange) range = function(node, start, end) { + var r = document.createRange(); + r.setEnd(node, end); + r.setStart(node, start); + return r; + }; + else range = function(node, start, end) { + var r = document.body.createTextRange(); + r.moveToElementText(node.parentNode); + r.collapse(true); + r.moveEnd("character", end); + r.moveStart("character", start); + return r; + }; + + function removeChildren(e) { + for (var count = e.childNodes.length; count > 0; --count) + e.removeChild(e.firstChild); + return e; + } + + function removeChildrenAndAdd(parent, e) { + return removeChildren(parent).appendChild(e); + } + + function contains(parent, child) { + if (parent.contains) + return parent.contains(child); + while (child = child.parentNode) + if (child == parent) return true; + } + + function activeElt() { return document.activeElement; } + // Older versions of IE throws unspecified error when touching + // document.activeElement in some cases (during loading, in iframe) + if (ie_upto10) activeElt = function() { + try { return document.activeElement; } + catch(e) { return document.body; } + }; + + // FEATURE DETECTION + + // Detect drag-and-drop + var dragAndDrop = function() { + // There is *some* kind of drag-and-drop support in IE6-8, but I + // couldn't get it to work yet. + if (ie_upto8) return false; + var div = elt('div'); + return "draggable" in div || "dragDrop" in div; + }(); + + var knownScrollbarWidth; + function scrollbarWidth(measure) { + if (knownScrollbarWidth != null) return knownScrollbarWidth; + var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll"); + removeChildrenAndAdd(measure, test); + if (test.offsetWidth) + knownScrollbarWidth = test.offsetHeight - test.clientHeight; + return knownScrollbarWidth || 0; + } + + var zwspSupported; + function zeroWidthElement(measure) { + if (zwspSupported == null) { + var test = elt("span", "\u200b"); + removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); + if (measure.firstChild.offsetHeight != 0) + zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !ie_upto7; + } + if (zwspSupported) return elt("span", "\u200b"); + else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); + } + + // Feature-detect IE's crummy client rect reporting for bidi text + var badBidiRects; + function hasBadBidiRects(measure) { + if (badBidiRects != null) return badBidiRects; + var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); + var r0 = range(txt, 0, 1).getBoundingClientRect(); + if (r0.left == r0.right) return false; + var r1 = range(txt, 1, 2).getBoundingClientRect(); + return badBidiRects = (r1.right - r0.right < 3); + } + + // See if "".split is the broken IE version, if so, provide an + // alternative way to split lines. + var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { + var pos = 0, result = [], l = string.length; + while (pos <= l) { + var nl = string.indexOf("\n", pos); + if (nl == -1) nl = string.length; + var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); + var rt = line.indexOf("\r"); + if (rt != -1) { + result.push(line.slice(0, rt)); + pos += rt + 1; + } else { + result.push(line); + pos = nl + 1; + } + } + return result; + } : function(string){return string.split(/\r\n?|\n/);}; + + var hasSelection = window.getSelection ? function(te) { + try { return te.selectionStart != te.selectionEnd; } + catch(e) { return false; } + } : function(te) { + try {var range = te.ownerDocument.selection.createRange();} + catch(e) {} + if (!range || range.parentElement() != te) return false; + return range.compareEndPoints("StartToEnd", range) != 0; + }; + + var hasCopyEvent = (function() { + var e = elt("div"); + if ("oncopy" in e) return true; + e.setAttribute("oncopy", "return;"); + return typeof e.oncopy == "function"; + })(); + + // KEY NAMES + + var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", + 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", + 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", + 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete", + 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", + 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", + 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"}; + CodeMirror.keyNames = keyNames; + (function() { + // Number keys + for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); + // Alphabetic keys + for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); + // Function keys + for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; + })(); + + // BIDI HELPERS + + function iterateBidiSections(order, from, to, f) { + if (!order) return f(from, to, "ltr"); + var found = false; + for (var i = 0; i < order.length; ++i) { + var part = order[i]; + if (part.from < to && part.to > from || from == to && part.to == from) { + f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); + found = true; + } + } + if (!found) f(from, to, "ltr"); + } + + function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } + function bidiRight(part) { return part.level % 2 ? part.from : part.to; } + + function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } + function lineRight(line) { + var order = getOrder(line); + if (!order) return line.text.length; + return bidiRight(lst(order)); + } + + function lineStart(cm, lineN) { + var line = getLine(cm.doc, lineN); + var visual = visualLine(line); + if (visual != line) lineN = lineNo(visual); + var order = getOrder(visual); + var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); + return Pos(lineN, ch); + } + function lineEnd(cm, lineN) { + var merged, line = getLine(cm.doc, lineN); + while (merged = collapsedSpanAtEnd(line)) { + line = merged.find(1, true).line; + lineN = null; + } + var order = getOrder(line); + var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); + return Pos(lineN == null ? lineNo(line) : lineN, ch); + } + + function compareBidiLevel(order, a, b) { + var linedir = order[0].level; + if (a == linedir) return true; + if (b == linedir) return false; + return a < b; + } + var bidiOther; + function getBidiPartAt(order, pos) { + bidiOther = null; + for (var i = 0, found; i < order.length; ++i) { + var cur = order[i]; + if (cur.from < pos && cur.to > pos) return i; + if ((cur.from == pos || cur.to == pos)) { + if (found == null) { + found = i; + } else if (compareBidiLevel(order, cur.level, order[found].level)) { + if (cur.from != cur.to) bidiOther = found; + return i; + } else { + if (cur.from != cur.to) bidiOther = i; + return found; + } + } + } + return found; + } + + function moveInLine(line, pos, dir, byUnit) { + if (!byUnit) return pos + dir; + do pos += dir; + while (pos > 0 && isExtendingChar(line.text.charAt(pos))); + return pos; + } + + // This is needed in order to move 'visually' through bi-directional + // text -- i.e., pressing left should make the cursor go left, even + // when in RTL text. The tricky part is the 'jumps', where RTL and + // LTR text touch each other. This often requires the cursor offset + // to move more than one unit, in order to visually move one unit. + function moveVisually(line, start, dir, byUnit) { + var bidi = getOrder(line); + if (!bidi) return moveLogically(line, start, dir, byUnit); + var pos = getBidiPartAt(bidi, start), part = bidi[pos]; + var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); + + for (;;) { + if (target > part.from && target < part.to) return target; + if (target == part.from || target == part.to) { + if (getBidiPartAt(bidi, target) == pos) return target; + part = bidi[pos += dir]; + return (dir > 0) == part.level % 2 ? part.to : part.from; + } else { + part = bidi[pos += dir]; + if (!part) return null; + if ((dir > 0) == part.level % 2) + target = moveInLine(line, part.to, -1, byUnit); + else + target = moveInLine(line, part.from, 1, byUnit); + } + } + } + + function moveLogically(line, start, dir, byUnit) { + var target = start + dir; + if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; + return target < 0 || target > line.text.length ? null : target; + } + + // Bidirectional ordering algorithm + // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm + // that this (partially) implements. + + // One-char codes used for character types: + // L (L): Left-to-Right + // R (R): Right-to-Left + // r (AL): Right-to-Left Arabic + // 1 (EN): European Number + // + (ES): European Number Separator + // % (ET): European Number Terminator + // n (AN): Arabic Number + // , (CS): Common Number Separator + // m (NSM): Non-Spacing Mark + // b (BN): Boundary Neutral + // s (B): Paragraph Separator + // t (S): Segment Separator + // w (WS): Whitespace + // N (ON): Other Neutrals + + // Returns null if characters are ordered as they appear + // (left-to-right), or an array of sections ({from, to, level} + // objects) in the order in which they occur visually. + var bidiOrdering = (function() { + // Character types for codepoints 0 to 0xff + var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; + // Character types for codepoints 0x600 to 0x6ff + var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; + function charType(code) { + if (code <= 0xf7) return lowTypes.charAt(code); + else if (0x590 <= code && code <= 0x5f4) return "R"; + else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); + else if (0x6ee <= code && code <= 0x8ac) return "r"; + else if (0x2000 <= code && code <= 0x200b) return "w"; + else if (code == 0x200c) return "b"; + else return "L"; + } + + var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; + var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; + // Browsers seem to always treat the boundaries of block elements as being L. + var outerType = "L"; + + function BidiSpan(level, from, to) { + this.level = level; + this.from = from; this.to = to; + } + + return function(str) { + if (!bidiRE.test(str)) return false; + var len = str.length, types = []; + for (var i = 0, type; i < len; ++i) + types.push(type = charType(str.charCodeAt(i))); + + // W1. Examine each non-spacing mark (NSM) in the level run, and + // change the type of the NSM to the type of the previous + // character. If the NSM is at the start of the level run, it will + // get the type of sor. + for (var i = 0, prev = outerType; i < len; ++i) { + var type = types[i]; + if (type == "m") types[i] = prev; + else prev = type; + } + + // W2. Search backwards from each instance of a European number + // until the first strong type (R, L, AL, or sor) is found. If an + // AL is found, change the type of the European number to Arabic + // number. + // W3. Change all ALs to R. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (type == "1" && cur == "r") types[i] = "n"; + else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } + } + + // W4. A single European separator between two European numbers + // changes to a European number. A single common separator between + // two numbers of the same type changes to that type. + for (var i = 1, prev = types[0]; i < len - 1; ++i) { + var type = types[i]; + if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; + else if (type == "," && prev == types[i+1] && + (prev == "1" || prev == "n")) types[i] = prev; + prev = type; + } + + // W5. A sequence of European terminators adjacent to European + // numbers changes to all European numbers. + // W6. Otherwise, separators and terminators change to Other + // Neutral. + for (var i = 0; i < len; ++i) { + var type = types[i]; + if (type == ",") types[i] = "N"; + else if (type == "%") { + for (var end = i + 1; end < len && types[end] == "%"; ++end) {} + var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // W7. Search backwards from each instance of a European number + // until the first strong type (R, L, or sor) is found. If an L is + // found, then change the type of the European number to L. + for (var i = 0, cur = outerType; i < len; ++i) { + var type = types[i]; + if (cur == "L" && type == "1") types[i] = "L"; + else if (isStrong.test(type)) cur = type; + } + + // N1. A sequence of neutrals takes the direction of the + // surrounding strong text if the text on both sides has the same + // direction. European and Arabic numbers act as if they were R in + // terms of their influence on neutrals. Start-of-level-run (sor) + // and end-of-level-run (eor) are used at level run boundaries. + // N2. Any remaining neutrals take the embedding direction. + for (var i = 0; i < len; ++i) { + if (isNeutral.test(types[i])) { + for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} + var before = (i ? types[i-1] : outerType) == "L"; + var after = (end < len ? types[end] : outerType) == "L"; + var replace = before || after ? "L" : "R"; + for (var j = i; j < end; ++j) types[j] = replace; + i = end - 1; + } + } + + // Here we depart from the documented algorithm, in order to avoid + // building up an actual levels array. Since there are only three + // levels (0, 1, 2) in an implementation that doesn't take + // explicit embedding into account, we can build up the order on + // the fly, without following the level-based algorithm. + var order = [], m; + for (var i = 0; i < len;) { + if (countsAsLeft.test(types[i])) { + var start = i; + for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} + order.push(new BidiSpan(0, start, i)); + } else { + var pos = i, at = order.length; + for (++i; i < len && types[i] != "L"; ++i) {} + for (var j = pos; j < i;) { + if (countsAsNum.test(types[j])) { + if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); + var nstart = j; + for (++j; j < i && countsAsNum.test(types[j]); ++j) {} + order.splice(at, 0, new BidiSpan(2, nstart, j)); + pos = j; + } else ++j; + } + if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); + } + } + if (order[0].level == 1 && (m = str.match(/^\s+/))) { + order[0].from = m[0].length; + order.unshift(new BidiSpan(0, 0, m[0].length)); + } + if (lst(order).level == 1 && (m = str.match(/\s+$/))) { + lst(order).to -= m[0].length; + order.push(new BidiSpan(0, len - m[0].length, len)); + } + if (order[0].level != lst(order).level) + order.push(new BidiSpan(order[0].level, len, len)); + + return order; + }; + })(); + + // THE END + + CodeMirror.version = "4.0.3"; + + return CodeMirror; +}); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/css/css.js b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/css/css.js new file mode 100644 index 0000000..f8fc5ce --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/css/css.js @@ -0,0 +1,701 @@ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("css", function(config, parserConfig) { + if (!parserConfig.propertyKeywords) parserConfig = CodeMirror.resolveMode("text/css"); + + var indentUnit = config.indentUnit, + tokenHooks = parserConfig.tokenHooks, + mediaTypes = parserConfig.mediaTypes || {}, + mediaFeatures = parserConfig.mediaFeatures || {}, + propertyKeywords = parserConfig.propertyKeywords || {}, + colorKeywords = parserConfig.colorKeywords || {}, + valueKeywords = parserConfig.valueKeywords || {}, + fontProperties = parserConfig.fontProperties || {}, + allowNested = parserConfig.allowNested; + + var type, override; + function ret(style, tp) { type = tp; return style; } + + // Tokenizers + + function tokenBase(stream, state) { + var ch = stream.next(); + if (tokenHooks[ch]) { + var result = tokenHooks[ch](stream, state); + if (result !== false) return result; + } + if (ch == "@") { + stream.eatWhile(/[\w\\\-]/); + return ret("def", stream.current()); + } else if (ch == "=" || (ch == "~" || ch == "|") && stream.eat("=")) { + return ret(null, "compare"); + } else if (ch == "\"" || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } else if (ch == "#") { + stream.eatWhile(/[\w\\\-]/); + return ret("atom", "hash"); + } else if (ch == "!") { + stream.match(/^\s*\w*/); + return ret("keyword", "important"); + } else if (/\d/.test(ch) || ch == "." && stream.eat(/\d/)) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } else if (ch === "-") { + if (/[\d.]/.test(stream.peek())) { + stream.eatWhile(/[\w.%]/); + return ret("number", "unit"); + } else if (stream.match(/^[^-]+-/)) { + return ret("meta", "meta"); + } + } else if (/[,+>*\/]/.test(ch)) { + return ret(null, "select-op"); + } else if (ch == "." && stream.match(/^-?[_a-z][_a-z0-9-]*/i)) { + return ret("qualifier", "qualifier"); + } else if (/[:;{}\[\]\(\)]/.test(ch)) { + return ret(null, ch); + } else if (ch == "u" && stream.match("rl(")) { + stream.backUp(1); + state.tokenize = tokenParenthesized; + return ret("property", "word"); + } else if (/[\w\\\-]/.test(ch)) { + stream.eatWhile(/[\w\\\-]/); + return ret("property", "word"); + } else { + return ret(null, null); + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, ch; + while ((ch = stream.next()) != null) { + if (ch == quote && !escaped) { + if (quote == ")") stream.backUp(1); + break; + } + escaped = !escaped && ch == "\\"; + } + if (ch == quote || !escaped && quote != ")") state.tokenize = null; + return ret("string", "string"); + }; + } + + function tokenParenthesized(stream, state) { + stream.next(); // Must be '(' + if (!stream.match(/\s*[\"\']/, false)) + state.tokenize = tokenString(")"); + else + state.tokenize = null; + return ret(null, "("); + } + + // Context management + + function Context(type, indent, prev) { + this.type = type; + this.indent = indent; + this.prev = prev; + } + + function pushContext(state, stream, type) { + state.context = new Context(type, stream.indentation() + indentUnit, state.context); + return type; + } + + function popContext(state) { + state.context = state.context.prev; + return state.context.type; + } + + function pass(type, stream, state) { + return states[state.context.type](type, stream, state); + } + function popAndPass(type, stream, state, n) { + for (var i = n || 1; i > 0; i--) + state.context = state.context.prev; + return pass(type, stream, state); + } + + // Parser + + function wordAsValue(stream) { + var word = stream.current().toLowerCase(); + if (valueKeywords.hasOwnProperty(word)) + override = "atom"; + else if (colorKeywords.hasOwnProperty(word)) + override = "keyword"; + else + override = "variable"; + } + + var states = {}; + + states.top = function(type, stream, state) { + if (type == "{") { + return pushContext(state, stream, "block"); + } else if (type == "}" && state.context.prev) { + return popContext(state); + } else if (type == "@media") { + return pushContext(state, stream, "media"); + } else if (type == "@font-face") { + return "font_face_before"; + } else if (/^@(-(moz|ms|o|webkit)-)?keyframes$/.test(type)) { + return "keyframes"; + } else if (type && type.charAt(0) == "@") { + return pushContext(state, stream, "at"); + } else if (type == "hash") { + override = "builtin"; + } else if (type == "word") { + override = "tag"; + } else if (type == "variable-definition") { + return "maybeprop"; + } else if (type == "interpolation") { + return pushContext(state, stream, "interpolation"); + } else if (type == ":") { + return "pseudo"; + } else if (allowNested && type == "(") { + return pushContext(state, stream, "params"); + } + return state.context.type; + }; + + states.block = function(type, stream, state) { + if (type == "word") { + if (propertyKeywords.hasOwnProperty(stream.current().toLowerCase())) { + override = "property"; + return "maybeprop"; + } else if (allowNested) { + override = stream.match(/^\s*:/, false) ? "property" : "tag"; + return "block"; + } else { + override += " error"; + return "maybeprop"; + } + } else if (type == "meta") { + return "block"; + } else if (!allowNested && (type == "hash" || type == "qualifier")) { + override = "error"; + return "block"; + } else { + return states.top(type, stream, state); + } + }; + + states.maybeprop = function(type, stream, state) { + if (type == ":") return pushContext(state, stream, "prop"); + return pass(type, stream, state); + }; + + states.prop = function(type, stream, state) { + if (type == ";") return popContext(state); + if (type == "{" && allowNested) return pushContext(state, stream, "propBlock"); + if (type == "}" || type == "{") return popAndPass(type, stream, state); + if (type == "(") return pushContext(state, stream, "parens"); + + if (type == "hash" && !/^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/.test(stream.current())) { + override += " error"; + } else if (type == "word") { + wordAsValue(stream); + } else if (type == "interpolation") { + return pushContext(state, stream, "interpolation"); + } + return "prop"; + }; + + states.propBlock = function(type, _stream, state) { + if (type == "}") return popContext(state); + if (type == "word") { override = "property"; return "maybeprop"; } + return state.context.type; + }; + + states.parens = function(type, stream, state) { + if (type == "{" || type == "}") return popAndPass(type, stream, state); + if (type == ")") return popContext(state); + return "parens"; + }; + + states.pseudo = function(type, stream, state) { + if (type == "word") { + override = "variable-3"; + return state.context.type; + } + return pass(type, stream, state); + }; + + states.media = function(type, stream, state) { + if (type == "(") return pushContext(state, stream, "media_parens"); + if (type == "}") return popAndPass(type, stream, state); + if (type == "{") return popContext(state) && pushContext(state, stream, allowNested ? "block" : "top"); + + if (type == "word") { + var word = stream.current().toLowerCase(); + if (word == "only" || word == "not" || word == "and") + override = "keyword"; + else if (mediaTypes.hasOwnProperty(word)) + override = "attribute"; + else if (mediaFeatures.hasOwnProperty(word)) + override = "property"; + else + override = "error"; + } + return state.context.type; + }; + + states.media_parens = function(type, stream, state) { + if (type == ")") return popContext(state); + if (type == "{" || type == "}") return popAndPass(type, stream, state, 2); + return states.media(type, stream, state); + }; + + states.font_face_before = function(type, stream, state) { + if (type == "{") + return pushContext(state, stream, "font_face"); + return pass(type, stream, state); + }; + + states.font_face = function(type, stream, state) { + if (type == "}") return popContext(state); + if (type == "word") { + if (!fontProperties.hasOwnProperty(stream.current().toLowerCase())) + override = "error"; + else + override = "property"; + return "maybeprop"; + } + return "font_face"; + }; + + states.keyframes = function(type, stream, state) { + if (type == "word") { override = "variable"; return "keyframes"; } + if (type == "{") return pushContext(state, stream, "top"); + return pass(type, stream, state); + }; + + states.at = function(type, stream, state) { + if (type == ";") return popContext(state); + if (type == "{" || type == "}") return popAndPass(type, stream, state); + if (type == "word") override = "tag"; + else if (type == "hash") override = "builtin"; + return "at"; + }; + + states.interpolation = function(type, stream, state) { + if (type == "}") return popContext(state); + if (type == "{" || type == ";") return popAndPass(type, stream, state); + if (type != "variable") override = "error"; + return "interpolation"; + }; + + states.params = function(type, stream, state) { + if (type == ")") return popContext(state); + if (type == "{" || type == "}") return popAndPass(type, stream, state); + if (type == "word") wordAsValue(stream); + return "params"; + }; + + return { + startState: function(base) { + return {tokenize: null, + state: "top", + context: new Context("top", base || 0, null)}; + }, + + token: function(stream, state) { + if (!state.tokenize && stream.eatSpace()) return null; + var style = (state.tokenize || tokenBase)(stream, state); + if (style && typeof style == "object") { + type = style[1]; + style = style[0]; + } + override = style; + state.state = states[state.state](type, stream, state); + return override; + }, + + indent: function(state, textAfter) { + var cx = state.context, ch = textAfter && textAfter.charAt(0); + var indent = cx.indent; + if (cx.type == "prop" && ch == "}") cx = cx.prev; + if (cx.prev && + (ch == "}" && (cx.type == "block" || cx.type == "top" || cx.type == "interpolation" || cx.type == "font_face") || + ch == ")" && (cx.type == "parens" || cx.type == "params" || cx.type == "media_parens") || + ch == "{" && (cx.type == "at" || cx.type == "media"))) { + indent = cx.indent - indentUnit; + cx = cx.prev; + } + return indent; + }, + + electricChars: "}", + blockCommentStart: "/*", + blockCommentEnd: "*/", + fold: "brace" + }; +}); + + function keySet(array) { + var keys = {}; + for (var i = 0; i < array.length; ++i) { + keys[array[i]] = true; + } + return keys; + } + + var mediaTypes_ = [ + "all", "aural", "braille", "handheld", "print", "projection", "screen", + "tty", "tv", "embossed" + ], mediaTypes = keySet(mediaTypes_); + + var mediaFeatures_ = [ + "width", "min-width", "max-width", "height", "min-height", "max-height", + "device-width", "min-device-width", "max-device-width", "device-height", + "min-device-height", "max-device-height", "aspect-ratio", + "min-aspect-ratio", "max-aspect-ratio", "device-aspect-ratio", + "min-device-aspect-ratio", "max-device-aspect-ratio", "color", "min-color", + "max-color", "color-index", "min-color-index", "max-color-index", + "monochrome", "min-monochrome", "max-monochrome", "resolution", + "min-resolution", "max-resolution", "scan", "grid" + ], mediaFeatures = keySet(mediaFeatures_); + + var propertyKeywords_ = [ + "align-content", "align-items", "align-self", "alignment-adjust", + "alignment-baseline", "anchor-point", "animation", "animation-delay", + "animation-direction", "animation-duration", "animation-fill-mode", + "animation-iteration-count", "animation-name", "animation-play-state", + "animation-timing-function", "appearance", "azimuth", "backface-visibility", + "background", "background-attachment", "background-clip", "background-color", + "background-image", "background-origin", "background-position", + "background-repeat", "background-size", "baseline-shift", "binding", + "bleed", "bookmark-label", "bookmark-level", "bookmark-state", + "bookmark-target", "border", "border-bottom", "border-bottom-color", + "border-bottom-left-radius", "border-bottom-right-radius", + "border-bottom-style", "border-bottom-width", "border-collapse", + "border-color", "border-image", "border-image-outset", + "border-image-repeat", "border-image-slice", "border-image-source", + "border-image-width", "border-left", "border-left-color", + "border-left-style", "border-left-width", "border-radius", "border-right", + "border-right-color", "border-right-style", "border-right-width", + "border-spacing", "border-style", "border-top", "border-top-color", + "border-top-left-radius", "border-top-right-radius", "border-top-style", + "border-top-width", "border-width", "bottom", "box-decoration-break", + "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", + "caption-side", "clear", "clip", "color", "color-profile", "column-count", + "column-fill", "column-gap", "column-rule", "column-rule-color", + "column-rule-style", "column-rule-width", "column-span", "column-width", + "columns", "content", "counter-increment", "counter-reset", "crop", "cue", + "cue-after", "cue-before", "cursor", "direction", "display", + "dominant-baseline", "drop-initial-after-adjust", + "drop-initial-after-align", "drop-initial-before-adjust", + "drop-initial-before-align", "drop-initial-size", "drop-initial-value", + "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", + "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", + "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", + "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", + "font-stretch", "font-style", "font-synthesis", "font-variant", + "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", + "font-variant-ligatures", "font-variant-numeric", "font-variant-position", + "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", + "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end", + "grid-column-start", "grid-row", "grid-row-end", "grid-row-start", + "grid-template", "grid-template-areas", "grid-template-columns", + "grid-template-rows", "hanging-punctuation", "height", "hyphens", + "icon", "image-orientation", "image-rendering", "image-resolution", + "inline-box-align", "justify-content", "left", "letter-spacing", + "line-break", "line-height", "line-stacking", "line-stacking-ruby", + "line-stacking-shift", "line-stacking-strategy", "list-style", + "list-style-image", "list-style-position", "list-style-type", "margin", + "margin-bottom", "margin-left", "margin-right", "margin-top", + "marker-offset", "marks", "marquee-direction", "marquee-loop", + "marquee-play-count", "marquee-speed", "marquee-style", "max-height", + "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", + "nav-left", "nav-right", "nav-up", "opacity", "order", "orphans", "outline", + "outline-color", "outline-offset", "outline-style", "outline-width", + "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", + "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", + "page", "page-break-after", "page-break-before", "page-break-inside", + "page-policy", "pause", "pause-after", "pause-before", "perspective", + "perspective-origin", "pitch", "pitch-range", "play-during", "position", + "presentation-level", "punctuation-trim", "quotes", "region-break-after", + "region-break-before", "region-break-inside", "region-fragment", + "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", + "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", + "ruby-position", "ruby-span", "shape-inside", "shape-outside", "size", + "speak", "speak-as", "speak-header", + "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", + "tab-size", "table-layout", "target", "target-name", "target-new", + "target-position", "text-align", "text-align-last", "text-decoration", + "text-decoration-color", "text-decoration-line", "text-decoration-skip", + "text-decoration-style", "text-emphasis", "text-emphasis-color", + "text-emphasis-position", "text-emphasis-style", "text-height", + "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", + "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", + "text-wrap", "top", "transform", "transform-origin", "transform-style", + "transition", "transition-delay", "transition-duration", + "transition-property", "transition-timing-function", "unicode-bidi", + "vertical-align", "visibility", "voice-balance", "voice-duration", + "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", + "voice-volume", "volume", "white-space", "widows", "width", "word-break", + "word-spacing", "word-wrap", "z-index", "zoom", + // SVG-specific + "clip-path", "clip-rule", "mask", "enable-background", "filter", "flood-color", + "flood-opacity", "lighting-color", "stop-color", "stop-opacity", "pointer-events", + "color-interpolation", "color-interpolation-filters", "color-profile", + "color-rendering", "fill", "fill-opacity", "fill-rule", "image-rendering", + "marker", "marker-end", "marker-mid", "marker-start", "shape-rendering", "stroke", + "stroke-dasharray", "stroke-dashoffset", "stroke-linecap", "stroke-linejoin", + "stroke-miterlimit", "stroke-opacity", "stroke-width", "text-rendering", + "baseline-shift", "dominant-baseline", "glyph-orientation-horizontal", + "glyph-orientation-vertical", "kerning", "text-anchor", "writing-mode" + ], propertyKeywords = keySet(propertyKeywords_); + + var colorKeywords_ = [ + "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", + "bisque", "black", "blanchedalmond", "blue", "blueviolet", "brown", + "burlywood", "cadetblue", "chartreuse", "chocolate", "coral", "cornflowerblue", + "cornsilk", "crimson", "cyan", "darkblue", "darkcyan", "darkgoldenrod", + "darkgray", "darkgreen", "darkkhaki", "darkmagenta", "darkolivegreen", + "darkorange", "darkorchid", "darkred", "darksalmon", "darkseagreen", + "darkslateblue", "darkslategray", "darkturquoise", "darkviolet", + "deeppink", "deepskyblue", "dimgray", "dodgerblue", "firebrick", + "floralwhite", "forestgreen", "fuchsia", "gainsboro", "ghostwhite", + "gold", "goldenrod", "gray", "grey", "green", "greenyellow", "honeydew", + "hotpink", "indianred", "indigo", "ivory", "khaki", "lavender", + "lavenderblush", "lawngreen", "lemonchiffon", "lightblue", "lightcoral", + "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightpink", + "lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", + "lightsteelblue", "lightyellow", "lime", "limegreen", "linen", "magenta", + "maroon", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", + "mediumseagreen", "mediumslateblue", "mediumspringgreen", "mediumturquoise", + "mediumvioletred", "midnightblue", "mintcream", "mistyrose", "moccasin", + "navajowhite", "navy", "oldlace", "olive", "olivedrab", "orange", "orangered", + "orchid", "palegoldenrod", "palegreen", "paleturquoise", "palevioletred", + "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", + "purple", "red", "rosybrown", "royalblue", "saddlebrown", "salmon", + "sandybrown", "seagreen", "seashell", "sienna", "silver", "skyblue", + "slateblue", "slategray", "snow", "springgreen", "steelblue", "tan", + "teal", "thistle", "tomato", "turquoise", "violet", "wheat", "white", + "whitesmoke", "yellow", "yellowgreen" + ], colorKeywords = keySet(colorKeywords_); + + var valueKeywords_ = [ + "above", "absolute", "activeborder", "activecaption", "afar", + "after-white-space", "ahead", "alias", "all", "all-scroll", "alternate", + "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", + "arabic-indic", "armenian", "asterisks", "auto", "avoid", "avoid-column", "avoid-page", + "avoid-region", "background", "backwards", "baseline", "below", "bidi-override", "binary", + "bengali", "blink", "block", "block-axis", "bold", "bolder", "border", "border-box", + "both", "bottom", "break", "break-all", "break-word", "button", "button-bevel", + "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", + "capitalize", "caps-lock-indicator", "caption", "captiontext", "caret", + "cell", "center", "checkbox", "circle", "cjk-earthly-branch", + "cjk-heavenly-stem", "cjk-ideographic", "clear", "clip", "close-quote", + "col-resize", "collapse", "column", "compact", "condensed", "contain", "content", + "content-box", "context-menu", "continuous", "copy", "cover", "crop", + "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", + "decimal-leading-zero", "default", "default-button", "destination-atop", + "destination-in", "destination-out", "destination-over", "devanagari", + "disc", "discard", "document", "dot-dash", "dot-dot-dash", "dotted", + "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", + "element", "ellipse", "ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", + "ethiopic-abegede-am-et", "ethiopic-abegede-gez", "ethiopic-abegede-ti-er", + "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", + "ethiopic-halehame-aa-et", "ethiopic-halehame-am-et", + "ethiopic-halehame-gez", "ethiopic-halehame-om-et", + "ethiopic-halehame-sid-et", "ethiopic-halehame-so-et", + "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", + "ethiopic-halehame-tig", "ew-resize", "expanded", "extra-condensed", + "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", + "forwards", "from", "geometricPrecision", "georgian", "graytext", "groove", + "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", + "help", "hidden", "hide", "higher", "highlight", "highlighttext", + "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore", + "inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", + "infobackground", "infotext", "inherit", "initial", "inline", "inline-axis", + "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", + "italic", "justify", "kannada", "katakana", "katakana-iroha", "keep-all", "khmer", + "landscape", "lao", "large", "larger", "left", "level", "lighter", + "line-through", "linear", "lines", "list-item", "listbox", "listitem", + "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", + "lower-greek", "lower-hexadecimal", "lower-latin", "lower-norwegian", + "lower-roman", "lowercase", "ltr", "malayalam", "match", + "media-controls-background", "media-current-time-display", + "media-fullscreen-button", "media-mute-button", "media-play-button", + "media-return-to-realtime-button", "media-rewind-button", + "media-seek-back-button", "media-seek-forward-button", "media-slider", + "media-sliderthumb", "media-time-remaining-display", "media-volume-slider", + "media-volume-slider-container", "media-volume-sliderthumb", "medium", + "menu", "menulist", "menulist-button", "menulist-text", + "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", + "mix", "mongolian", "monospace", "move", "multiple", "myanmar", "n-resize", + "narrower", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", + "no-open-quote", "no-repeat", "none", "normal", "not-allowed", "nowrap", + "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", + "optimizeLegibility", "optimizeSpeed", "oriya", "oromo", "outset", + "outside", "outside-shape", "overlay", "overline", "padding", "padding-box", + "painted", "page", "paused", "persian", "plus-darker", "plus-lighter", "pointer", + "polygon", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress", "push-button", + "radio", "read-only", "read-write", "read-write-plaintext-only", "rectangle", "region", + "relative", "repeat", "repeat-x", "repeat-y", "reset", "reverse", "rgb", "rgba", + "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", + "s-resize", "sans-serif", "scroll", "scrollbar", "se-resize", "searchfield", + "searchfield-cancel-button", "searchfield-decoration", + "searchfield-results-button", "searchfield-results-decoration", + "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", + "single", "skip-white-space", "slide", "slider-horizontal", + "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow", + "small", "small-caps", "small-caption", "smaller", "solid", "somali", + "source-atop", "source-in", "source-out", "source-over", "space", "square", + "square-button", "start", "static", "status-bar", "stretch", "stroke", + "sub", "subpixel-antialiased", "super", "sw-resize", "table", + "table-caption", "table-cell", "table-column", "table-column-group", + "table-footer-group", "table-header-group", "table-row", "table-row-group", + "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", + "thick", "thin", "threeddarkshadow", "threedface", "threedhighlight", + "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", + "tigrinya-er-abegede", "tigrinya-et", "tigrinya-et-abegede", "to", "top", + "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", + "upper-alpha", "upper-armenian", "upper-greek", "upper-hexadecimal", + "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", + "vertical", "vertical-text", "visible", "visibleFill", "visiblePainted", + "visibleStroke", "visual", "w-resize", "wait", "wave", "wider", + "window", "windowframe", "windowtext", "x-large", "x-small", "xor", + "xx-large", "xx-small" + ], valueKeywords = keySet(valueKeywords_); + + var fontProperties_ = [ + "font-family", "src", "unicode-range", "font-variant", "font-feature-settings", + "font-stretch", "font-weight", "font-style" + ], fontProperties = keySet(fontProperties_); + + var allWords = mediaTypes_.concat(mediaFeatures_).concat(propertyKeywords_).concat(colorKeywords_).concat(valueKeywords_); + CodeMirror.registerHelper("hintWords", "css", allWords); + + function tokenCComment(stream, state) { + var maybeEnd = false, ch; + while ((ch = stream.next()) != null) { + if (maybeEnd && ch == "/") { + state.tokenize = null; + break; + } + maybeEnd = (ch == "*"); + } + return ["comment", "comment"]; + } + + function tokenSGMLComment(stream, state) { + if (stream.skipTo("-->")) { + stream.match("-->"); + state.tokenize = null; + } else { + stream.skipToEnd(); + } + return ["comment", "comment"]; + } + + CodeMirror.defineMIME("text/css", { + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + propertyKeywords: propertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + fontProperties: fontProperties, + tokenHooks: { + "<": function(stream, state) { + if (!stream.match("!--")) return false; + state.tokenize = tokenSGMLComment; + return tokenSGMLComment(stream, state); + }, + "/": function(stream, state) { + if (!stream.eat("*")) return false; + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } + }, + name: "css" + }); + + CodeMirror.defineMIME("text/x-scss", { + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + propertyKeywords: propertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + fontProperties: fontProperties, + allowNested: true, + tokenHooks: { + "/": function(stream, state) { + if (stream.eat("/")) { + stream.skipToEnd(); + return ["comment", "comment"]; + } else if (stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } else { + return ["operator", "operator"]; + } + }, + ":": function(stream) { + if (stream.match(/\s*{/)) + return [null, "{"]; + return false; + }, + "$": function(stream) { + stream.match(/^[\w-]+/); + if (stream.match(/^\s*:/, false)) + return ["variable-2", "variable-definition"]; + return ["variable-2", "variable"]; + }, + "#": function(stream) { + if (!stream.eat("{")) return false; + return [null, "interpolation"]; + } + }, + name: "css", + helperType: "scss" + }); + + CodeMirror.defineMIME("text/x-less", { + mediaTypes: mediaTypes, + mediaFeatures: mediaFeatures, + propertyKeywords: propertyKeywords, + colorKeywords: colorKeywords, + valueKeywords: valueKeywords, + fontProperties: fontProperties, + allowNested: true, + tokenHooks: { + "/": function(stream, state) { + if (stream.eat("/")) { + stream.skipToEnd(); + return ["comment", "comment"]; + } else if (stream.eat("*")) { + state.tokenize = tokenCComment; + return tokenCComment(stream, state); + } else { + return ["operator", "operator"]; + } + }, + "@": function(stream) { + if (stream.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/, false)) return false; + stream.eatWhile(/[\w\\\-]/); + if (stream.match(/^\s*:/, false)) + return ["variable-2", "variable-definition"]; + return ["variable-2", "variable"]; + }, + "&": function() { + return ["atom", "atom"]; + } + }, + name: "css", + helperType: "less" + }); + +}); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/htmlmixed/htmlmixed.js b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/htmlmixed/htmlmixed.js new file mode 100644 index 0000000..d80ef9c --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/htmlmixed/htmlmixed.js @@ -0,0 +1,117 @@ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"), require("../css/css")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript", "../css/css"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("htmlmixed", function(config, parserConfig) { + var htmlMode = CodeMirror.getMode(config, {name: "xml", + htmlMode: true, + multilineTagIndentFactor: parserConfig.multilineTagIndentFactor, + multilineTagIndentPastTag: parserConfig.multilineTagIndentPastTag}); + var cssMode = CodeMirror.getMode(config, "css"); + + var scriptTypes = [], scriptTypesConf = parserConfig && parserConfig.scriptTypes; + scriptTypes.push({matches: /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^$/i, + mode: CodeMirror.getMode(config, "javascript")}); + if (scriptTypesConf) for (var i = 0; i < scriptTypesConf.length; ++i) { + var conf = scriptTypesConf[i]; + scriptTypes.push({matches: conf.matches, mode: conf.mode && CodeMirror.getMode(config, conf.mode)}); + } + scriptTypes.push({matches: /./, + mode: CodeMirror.getMode(config, "text/plain")}); + + function html(stream, state) { + var tagName = state.htmlState.tagName; + var style = htmlMode.token(stream, state.htmlState); + if (tagName == "script" && /\btag\b/.test(style) && stream.current() == ">") { + // Script block: mode to change to depends on type attribute + var scriptType = stream.string.slice(Math.max(0, stream.pos - 100), stream.pos).match(/\btype\s*=\s*("[^"]+"|'[^']+'|\S+)[^<]*$/i); + scriptType = scriptType ? scriptType[1] : ""; + if (scriptType && /[\"\']/.test(scriptType.charAt(0))) scriptType = scriptType.slice(1, scriptType.length - 1); + for (var i = 0; i < scriptTypes.length; ++i) { + var tp = scriptTypes[i]; + if (typeof tp.matches == "string" ? scriptType == tp.matches : tp.matches.test(scriptType)) { + if (tp.mode) { + state.token = script; + state.localMode = tp.mode; + state.localState = tp.mode.startState && tp.mode.startState(htmlMode.indent(state.htmlState, "")); + } + break; + } + } + } else if (tagName == "style" && /\btag\b/.test(style) && stream.current() == ">") { + state.token = css; + state.localMode = cssMode; + state.localState = cssMode.startState(htmlMode.indent(state.htmlState, "")); + } + return style; + } + function maybeBackup(stream, pat, style) { + var cur = stream.current(); + var close = cur.search(pat), m; + if (close > -1) stream.backUp(cur.length - close); + else if (m = cur.match(/<\/?$/)) { + stream.backUp(cur.length); + if (!stream.match(pat, false)) stream.match(cur); + } + return style; + } + function script(stream, state) { + if (stream.match(/^<\/\s*script\s*>/i, false)) { + state.token = html; + state.localState = state.localMode = null; + return html(stream, state); + } + return maybeBackup(stream, /<\/\s*script\s*>/, + state.localMode.token(stream, state.localState)); + } + function css(stream, state) { + if (stream.match(/^<\/\s*style\s*>/i, false)) { + state.token = html; + state.localState = state.localMode = null; + return html(stream, state); + } + return maybeBackup(stream, /<\/\s*style\s*>/, + cssMode.token(stream, state.localState)); + } + + return { + startState: function() { + var state = htmlMode.startState(); + return {token: html, localMode: null, localState: null, htmlState: state}; + }, + + copyState: function(state) { + if (state.localState) + var local = CodeMirror.copyState(state.localMode, state.localState); + return {token: state.token, localMode: state.localMode, localState: local, + htmlState: CodeMirror.copyState(htmlMode, state.htmlState)}; + }, + + token: function(stream, state) { + return state.token(stream, state); + }, + + indent: function(state, textAfter) { + if (!state.localMode || /^\s*<\//.test(textAfter)) + return htmlMode.indent(state.htmlState, textAfter); + else if (state.localMode.indent) + return state.localMode.indent(state.localState, textAfter); + else + return CodeMirror.Pass; + }, + + innerMode: function(state) { + return {state: state.localState || state.htmlState, mode: state.localMode || htmlMode}; + } + }; +}, "xml", "javascript", "css"); + +CodeMirror.defineMIME("text/html", "htmlmixed"); + +}); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/javascript/javascript.js b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/javascript/javascript.js new file mode 100644 index 0000000..15eccf7 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/javascript/javascript.js @@ -0,0 +1,652 @@ +// TODO actually recognize syntax of TypeScript constructs + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("javascript", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var statementIndent = parserConfig.statementIndent; + var jsonldMode = parserConfig.jsonld; + var jsonMode = parserConfig.json || jsonldMode; + var isTS = parserConfig.typescript; + + // Tokenizer + + var keywords = function(){ + function kw(type) {return {type: type, style: "keyword"};} + var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); + var operator = kw("operator"), atom = {type: "atom", style: "atom"}; + + var jsKeywords = { + "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, + "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C, + "var": kw("var"), "const": kw("var"), "let": kw("var"), + "function": kw("function"), "catch": kw("catch"), + "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), + "in": operator, "typeof": operator, "instanceof": operator, + "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, + "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), + "yield": C, "export": kw("export"), "import": kw("import"), "extends": C + }; + + // Extend the 'normal' keywords with the TypeScript language extensions + if (isTS) { + var type = {type: "variable", style: "variable-3"}; + var tsKeywords = { + // object-like things + "interface": kw("interface"), + "extends": kw("extends"), + "constructor": kw("constructor"), + + // scope modifiers + "public": kw("public"), + "private": kw("private"), + "protected": kw("protected"), + "static": kw("static"), + + // types + "string": type, "number": type, "bool": type, "any": type + }; + + for (var attr in tsKeywords) { + jsKeywords[attr] = tsKeywords[attr]; + } + } + + return jsKeywords; + }(); + + var isOperatorChar = /[+\-*&%=<>!?|~^]/; + var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; + + function readRegexp(stream) { + var escaped = false, next, inSet = false; + while ((next = stream.next()) != null) { + if (!escaped) { + if (next == "/" && !inSet) return; + if (next == "[") inSet = true; + else if (inSet && next == "]") inSet = false; + } + escaped = !escaped && next == "\\"; + } + } + + // Used as scratch variables to communicate multiple values without + // consing up tons of objects. + var type, content; + function ret(tp, style, cont) { + type = tp; content = cont; + return style; + } + function tokenBase(stream, state) { + var ch = stream.next(); + if (ch == '"' || ch == "'") { + state.tokenize = tokenString(ch); + return state.tokenize(stream, state); + } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { + return ret("number", "number"); + } else if (ch == "." && stream.match("..")) { + return ret("spread", "meta"); + } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { + return ret(ch); + } else if (ch == "=" && stream.eat(">")) { + return ret("=>", "operator"); + } else if (ch == "0" && stream.eat(/x/i)) { + stream.eatWhile(/[\da-f]/i); + return ret("number", "number"); + } else if (/\d/.test(ch)) { + stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); + return ret("number", "number"); + } else if (ch == "/") { + if (stream.eat("*")) { + state.tokenize = tokenComment; + return tokenComment(stream, state); + } else if (stream.eat("/")) { + stream.skipToEnd(); + return ret("comment", "comment"); + } else if (state.lastType == "operator" || state.lastType == "keyword c" || + state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { + readRegexp(stream); + stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla + return ret("regexp", "string-2"); + } else { + stream.eatWhile(isOperatorChar); + return ret("operator", "operator", stream.current()); + } + } else if (ch == "`") { + state.tokenize = tokenQuasi; + return tokenQuasi(stream, state); + } else if (ch == "#") { + stream.skipToEnd(); + return ret("error", "error"); + } else if (isOperatorChar.test(ch)) { + stream.eatWhile(isOperatorChar); + return ret("operator", "operator", stream.current()); + } else { + stream.eatWhile(/[\w\$_]/); + var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; + return (known && state.lastType != ".") ? ret(known.type, known.style, word) : + ret("variable", "variable", word); + } + } + + function tokenString(quote) { + return function(stream, state) { + var escaped = false, next; + if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ + state.tokenize = tokenBase; + return ret("jsonld-keyword", "meta"); + } + while ((next = stream.next()) != null) { + if (next == quote && !escaped) break; + escaped = !escaped && next == "\\"; + } + if (!escaped) state.tokenize = tokenBase; + return ret("string", "string"); + }; + } + + function tokenComment(stream, state) { + var maybeEnd = false, ch; + while (ch = stream.next()) { + if (ch == "/" && maybeEnd) { + state.tokenize = tokenBase; + break; + } + maybeEnd = (ch == "*"); + } + return ret("comment", "comment"); + } + + function tokenQuasi(stream, state) { + var escaped = false, next; + while ((next = stream.next()) != null) { + if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { + state.tokenize = tokenBase; + break; + } + escaped = !escaped && next == "\\"; + } + return ret("quasi", "string-2", stream.current()); + } + + var brackets = "([{}])"; + // This is a crude lookahead trick to try and notice that we're + // parsing the argument patterns for a fat-arrow function before we + // actually hit the arrow token. It only works if the arrow is on + // the same line as the arguments and there's no strange noise + // (comments) in between. Fallback is to only notice when we hit the + // arrow, and not declare the arguments as locals for the arrow + // body. + function findFatArrow(stream, state) { + if (state.fatArrowAt) state.fatArrowAt = null; + var arrow = stream.string.indexOf("=>", stream.start); + if (arrow < 0) return; + + var depth = 0, sawSomething = false; + for (var pos = arrow - 1; pos >= 0; --pos) { + var ch = stream.string.charAt(pos); + var bracket = brackets.indexOf(ch); + if (bracket >= 0 && bracket < 3) { + if (!depth) { ++pos; break; } + if (--depth == 0) break; + } else if (bracket >= 3 && bracket < 6) { + ++depth; + } else if (/[$\w]/.test(ch)) { + sawSomething = true; + } else if (sawSomething && !depth) { + ++pos; + break; + } + } + if (sawSomething && !depth) state.fatArrowAt = pos; + } + + // Parser + + var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; + + function JSLexical(indented, column, type, align, prev, info) { + this.indented = indented; + this.column = column; + this.type = type; + this.prev = prev; + this.info = info; + if (align != null) this.align = align; + } + + function inScope(state, varname) { + for (var v = state.localVars; v; v = v.next) + if (v.name == varname) return true; + for (var cx = state.context; cx; cx = cx.prev) { + for (var v = cx.vars; v; v = v.next) + if (v.name == varname) return true; + } + } + + function parseJS(state, style, type, content, stream) { + var cc = state.cc; + // Communicate our context to the combinators. + // (Less wasteful than consing up a hundred closures on every call.) + cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; + + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = true; + + while(true) { + var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; + if (combinator(type, content)) { + while(cc.length && cc[cc.length - 1].lex) + cc.pop()(); + if (cx.marked) return cx.marked; + if (type == "variable" && inScope(state, content)) return "variable-2"; + return style; + } + } + } + + // Combinator utils + + var cx = {state: null, column: null, marked: null, cc: null}; + function pass() { + for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); + } + function cont() { + pass.apply(null, arguments); + return true; + } + function register(varname) { + function inList(list) { + for (var v = list; v; v = v.next) + if (v.name == varname) return true; + return false; + } + var state = cx.state; + if (state.context) { + cx.marked = "def"; + if (inList(state.localVars)) return; + state.localVars = {name: varname, next: state.localVars}; + } else { + if (inList(state.globalVars)) return; + if (parserConfig.globalVars) + state.globalVars = {name: varname, next: state.globalVars}; + } + } + + // Combinators + + var defaultVars = {name: "this", next: {name: "arguments"}}; + function pushcontext() { + cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; + cx.state.localVars = defaultVars; + } + function popcontext() { + cx.state.localVars = cx.state.context.vars; + cx.state.context = cx.state.context.prev; + } + function pushlex(type, info) { + var result = function() { + var state = cx.state, indent = state.indented; + if (state.lexical.type == "stat") indent = state.lexical.indented; + state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); + }; + result.lex = true; + return result; + } + function poplex() { + var state = cx.state; + if (state.lexical.prev) { + if (state.lexical.type == ")") + state.indented = state.lexical.indented; + state.lexical = state.lexical.prev; + } + } + poplex.lex = true; + + function expect(wanted) { + function exp(type) { + if (type == wanted) return cont(); + else if (wanted == ";") return pass(); + else return cont(exp); + }; + return exp; + } + + function statement(type, value) { + if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); + if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); + if (type == "keyword b") return cont(pushlex("form"), statement, poplex); + if (type == "{") return cont(pushlex("}"), block, poplex); + if (type == ";") return cont(); + if (type == "if") return cont(pushlex("form"), expression, statement, poplex, maybeelse); + if (type == "function") return cont(functiondef); + if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); + if (type == "variable") return cont(pushlex("stat"), maybelabel); + if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), + block, poplex, poplex); + if (type == "case") return cont(expression, expect(":")); + if (type == "default") return cont(expect(":")); + if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), + statement, poplex, popcontext); + if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); + if (type == "class") return cont(pushlex("form"), className, objlit, poplex); + if (type == "export") return cont(pushlex("form"), afterExport, poplex); + if (type == "import") return cont(pushlex("form"), afterImport, poplex); + return pass(pushlex("stat"), expression, expect(";"), poplex); + } + function expression(type) { + return expressionInner(type, false); + } + function expressionNoComma(type) { + return expressionInner(type, true); + } + function expressionInner(type, noComma) { + if (cx.state.fatArrowAt == cx.stream.start) { + var body = noComma ? arrowBodyNoComma : arrowBody; + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); + else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); + } + + var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; + if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); + if (type == "function") return cont(functiondef); + if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); + if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); + if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); + if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); + if (type == "{") return contCommasep(objprop, "}", null, maybeop); + return cont(); + } + function maybeexpression(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expression); + } + function maybeexpressionNoComma(type) { + if (type.match(/[;\}\)\],]/)) return pass(); + return pass(expressionNoComma); + } + + function maybeoperatorComma(type, value) { + if (type == ",") return cont(expression); + return maybeoperatorNoComma(type, value, false); + } + function maybeoperatorNoComma(type, value, noComma) { + var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; + var expr = noComma == false ? expression : expressionNoComma; + if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); + if (type == "operator") { + if (/\+\+|--/.test(value)) return cont(me); + if (value == "?") return cont(expression, expect(":"), expr); + return cont(expr); + } + if (type == "quasi") { cx.cc.push(me); return quasi(value); } + if (type == ";") return; + if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); + if (type == ".") return cont(property, me); + if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); + } + function quasi(value) { + if (value.slice(value.length - 2) != "${") return cont(); + return cont(expression, continueQuasi); + } + function continueQuasi(type) { + if (type == "}") { + cx.marked = "string-2"; + cx.state.tokenize = tokenQuasi; + return cont(); + } + } + function arrowBody(type) { + findFatArrow(cx.stream, cx.state); + if (type == "{") return pass(statement); + return pass(expression); + } + function arrowBodyNoComma(type) { + findFatArrow(cx.stream, cx.state); + if (type == "{") return pass(statement); + return pass(expressionNoComma); + } + function maybelabel(type) { + if (type == ":") return cont(poplex, statement); + return pass(maybeoperatorComma, expect(";"), poplex); + } + function property(type) { + if (type == "variable") {cx.marked = "property"; return cont();} + } + function objprop(type, value) { + if (type == "variable") { + cx.marked = "property"; + if (value == "get" || value == "set") return cont(getterSetter); + } else if (type == "number" || type == "string") { + cx.marked = jsonldMode ? "property" : (type + " property"); + } else if (type == "[") { + return cont(expression, expect("]"), afterprop); + } + if (atomicTypes.hasOwnProperty(type)) return cont(afterprop); + } + function getterSetter(type) { + if (type != "variable") return pass(afterprop); + cx.marked = "property"; + return cont(functiondef); + } + function afterprop(type) { + if (type == ":") return cont(expressionNoComma); + if (type == "(") return pass(functiondef); + } + function commasep(what, end) { + function proceed(type) { + if (type == ",") { + var lex = cx.state.lexical; + if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; + return cont(what, proceed); + } + if (type == end) return cont(); + return cont(expect(end)); + } + return function(type) { + if (type == end) return cont(); + return pass(what, proceed); + }; + } + function contCommasep(what, end, info) { + for (var i = 3; i < arguments.length; i++) + cx.cc.push(arguments[i]); + return cont(pushlex(end, info), commasep(what, end), poplex); + } + function block(type) { + if (type == "}") return cont(); + return pass(statement, block); + } + function maybetype(type) { + if (isTS && type == ":") return cont(typedef); + } + function typedef(type) { + if (type == "variable"){cx.marked = "variable-3"; return cont();} + } + function vardef() { + return pass(pattern, maybetype, maybeAssign, vardefCont); + } + function pattern(type, value) { + if (type == "variable") { register(value); return cont(); } + if (type == "[") return contCommasep(pattern, "]"); + if (type == "{") return contCommasep(proppattern, "}"); + } + function proppattern(type, value) { + if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { + register(value); + return cont(maybeAssign); + } + if (type == "variable") cx.marked = "property"; + return cont(expect(":"), pattern, maybeAssign); + } + function maybeAssign(_type, value) { + if (value == "=") return cont(expressionNoComma); + } + function vardefCont(type) { + if (type == ",") return cont(vardef); + } + function maybeelse(type, value) { + if (type == "keyword b" && value == "else") return cont(pushlex("form"), statement, poplex); + } + function forspec(type) { + if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); + } + function forspec1(type) { + if (type == "var") return cont(vardef, expect(";"), forspec2); + if (type == ";") return cont(forspec2); + if (type == "variable") return cont(formaybeinof); + return pass(expression, expect(";"), forspec2); + } + function formaybeinof(_type, value) { + if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } + return cont(maybeoperatorComma, forspec2); + } + function forspec2(type, value) { + if (type == ";") return cont(forspec3); + if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } + return pass(expression, expect(";"), forspec3); + } + function forspec3(type) { + if (type != ")") cont(expression); + } + function functiondef(type, value) { + if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} + if (type == "variable") {register(value); return cont(functiondef);} + if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext); + } + function funarg(type) { + if (type == "spread") return cont(funarg); + return pass(pattern, maybetype); + } + function className(type, value) { + if (type == "variable") {register(value); return cont(classNameAfter);} + } + function classNameAfter(_type, value) { + if (value == "extends") return cont(expression); + } + function objlit(type) { + if (type == "{") return contCommasep(objprop, "}"); + } + function afterModule(type, value) { + if (type == "string") return cont(statement); + if (type == "variable") { register(value); return cont(maybeFrom); } + } + function afterExport(_type, value) { + if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } + if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } + return pass(statement); + } + function afterImport(type) { + if (type == "string") return cont(); + return pass(importSpec, maybeFrom); + } + function importSpec(type, value) { + if (type == "{") return contCommasep(importSpec, "}"); + if (type == "variable") register(value); + return cont(); + } + function maybeFrom(_type, value) { + if (value == "from") { cx.marked = "keyword"; return cont(expression); } + } + function arrayLiteral(type) { + if (type == "]") return cont(); + return pass(expressionNoComma, maybeArrayComprehension); + } + function maybeArrayComprehension(type) { + if (type == "for") return pass(comprehension, expect("]")); + if (type == ",") return cont(commasep(expressionNoComma, "]")); + return pass(commasep(expressionNoComma, "]")); + } + function comprehension(type) { + if (type == "for") return cont(forspec, comprehension); + if (type == "if") return cont(expression, comprehension); + } + + // Interface + + return { + startState: function(basecolumn) { + var state = { + tokenize: tokenBase, + lastType: "sof", + cc: [], + lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), + localVars: parserConfig.localVars, + context: parserConfig.localVars && {vars: parserConfig.localVars}, + indented: 0 + }; + if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") + state.globalVars = parserConfig.globalVars; + return state; + }, + + token: function(stream, state) { + if (stream.sol()) { + if (!state.lexical.hasOwnProperty("align")) + state.lexical.align = false; + state.indented = stream.indentation(); + findFatArrow(stream, state); + } + if (state.tokenize != tokenComment && stream.eatSpace()) return null; + var style = state.tokenize(stream, state); + if (type == "comment") return style; + state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; + return parseJS(state, style, type, content, stream); + }, + + indent: function(state, textAfter) { + if (state.tokenize == tokenComment) return CodeMirror.Pass; + if (state.tokenize != tokenBase) return 0; + var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; + // Kludge to prevent 'maybelse' from blocking lexical scope pops + for (var i = state.cc.length - 1; i >= 0; --i) { + var c = state.cc[i]; + if (c == poplex) lexical = lexical.prev; + else if (c != maybeelse) break; + } + if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; + if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") + lexical = lexical.prev; + var type = lexical.type, closing = firstChar == type; + + if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); + else if (type == "form" && firstChar == "{") return lexical.indented; + else if (type == "form") return lexical.indented + indentUnit; + else if (type == "stat") + return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0); + else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) + return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); + else if (lexical.align) return lexical.column + (closing ? 0 : 1); + else return lexical.indented + (closing ? 0 : indentUnit); + }, + + electricChars: ":{}", + blockCommentStart: jsonMode ? null : "/*", + blockCommentEnd: jsonMode ? null : "*/", + lineComment: jsonMode ? null : "//", + fold: "brace", + + helperType: jsonMode ? "json" : "javascript", + jsonldMode: jsonldMode, + jsonMode: jsonMode + }; +}); + +CodeMirror.defineMIME("text/javascript", "javascript"); +CodeMirror.defineMIME("text/ecmascript", "javascript"); +CodeMirror.defineMIME("application/javascript", "javascript"); +CodeMirror.defineMIME("application/ecmascript", "javascript"); +CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); +CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); +CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); +CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); +CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); + +}); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/xml/xml.js b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/xml/xml.js new file mode 100644 index 0000000..880b74d --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/mode/xml/xml.js @@ -0,0 +1,349 @@ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { +"use strict"; + +CodeMirror.defineMode("xml", function(config, parserConfig) { + var indentUnit = config.indentUnit; + var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; + var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag; + if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true; + + var Kludges = parserConfig.htmlMode ? { + autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, + 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, + 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, + 'track': true, 'wbr': true}, + implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, + 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, + 'th': true, 'tr': true}, + contextGrabbers: { + 'dd': {'dd': true, 'dt': true}, + 'dt': {'dd': true, 'dt': true}, + 'li': {'li': true}, + 'option': {'option': true, 'optgroup': true}, + 'optgroup': {'optgroup': true}, + 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, + 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, + 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, + 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, + 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, + 'rp': {'rp': true, 'rt': true}, + 'rt': {'rp': true, 'rt': true}, + 'tbody': {'tbody': true, 'tfoot': true}, + 'td': {'td': true, 'th': true}, + 'tfoot': {'tbody': true}, + 'th': {'td': true, 'th': true}, + 'thead': {'tbody': true, 'tfoot': true}, + 'tr': {'tr': true} + }, + doNotIndent: {"pre": true}, + allowUnquoted: true, + allowMissing: true, + caseFold: true + } : { + autoSelfClosers: {}, + implicitlyClosed: {}, + contextGrabbers: {}, + doNotIndent: {}, + allowUnquoted: false, + allowMissing: false, + caseFold: false + }; + var alignCDATA = parserConfig.alignCDATA; + + // Return variables for tokenizers + var tagName, type, setStyle; + + function inText(stream, state) { + function chain(parser) { + state.tokenize = parser; + return parser(stream, state); + } + + var ch = stream.next(); + if (ch == "<") { + if (stream.eat("!")) { + if (stream.eat("[")) { + if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); + else return null; + } else if (stream.match("--")) { + return chain(inBlock("comment", "-->")); + } else if (stream.match("DOCTYPE", true, true)) { + stream.eatWhile(/[\w\._\-]/); + return chain(doctype(1)); + } else { + return null; + } + } else if (stream.eat("?")) { + stream.eatWhile(/[\w\._\-]/); + state.tokenize = inBlock("meta", "?>"); + return "meta"; + } else { + var isClose = stream.eat("/"); + tagName = ""; + var c; + while ((c = stream.eat(/[^\s\u00a0=<>\"\'\/?]/))) tagName += c; + if (Kludges.caseFold) tagName = tagName.toLowerCase(); + if (!tagName) return "tag error"; + type = isClose ? "closeTag" : "openTag"; + state.tokenize = inTag; + return "tag"; + } + } else if (ch == "&") { + var ok; + if (stream.eat("#")) { + if (stream.eat("x")) { + ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); + } else { + ok = stream.eatWhile(/[\d]/) && stream.eat(";"); + } + } else { + ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); + } + return ok ? "atom" : "error"; + } else { + stream.eatWhile(/[^&<]/); + return null; + } + } + + function inTag(stream, state) { + var ch = stream.next(); + if (ch == ">" || (ch == "/" && stream.eat(">"))) { + state.tokenize = inText; + type = ch == ">" ? "endTag" : "selfcloseTag"; + return "tag"; + } else if (ch == "=") { + type = "equals"; + return null; + } else if (ch == "<") { + state.tokenize = inText; + state.state = baseState; + state.tagName = state.tagStart = null; + var next = state.tokenize(stream, state); + return next ? next + " error" : "error"; + } else if (/[\'\"]/.test(ch)) { + state.tokenize = inAttribute(ch); + state.stringStartCol = stream.column(); + return state.tokenize(stream, state); + } else { + stream.eatWhile(/[^\s\u00a0=<>\"\']/); + return "word"; + } + } + + function inAttribute(quote) { + var closure = function(stream, state) { + while (!stream.eol()) { + if (stream.next() == quote) { + state.tokenize = inTag; + break; + } + } + return "string"; + }; + closure.isInAttribute = true; + return closure; + } + + function inBlock(style, terminator) { + return function(stream, state) { + while (!stream.eol()) { + if (stream.match(terminator)) { + state.tokenize = inText; + break; + } + stream.next(); + } + return style; + }; + } + function doctype(depth) { + return function(stream, state) { + var ch; + while ((ch = stream.next()) != null) { + if (ch == "<") { + state.tokenize = doctype(depth + 1); + return state.tokenize(stream, state); + } else if (ch == ">") { + if (depth == 1) { + state.tokenize = inText; + break; + } else { + state.tokenize = doctype(depth - 1); + return state.tokenize(stream, state); + } + } + } + return "meta"; + }; + } + + function Context(state, tagName, startOfLine) { + this.prev = state.context; + this.tagName = tagName; + this.indent = state.indented; + this.startOfLine = startOfLine; + if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) + this.noIndent = true; + } + function popContext(state) { + if (state.context) state.context = state.context.prev; + } + function maybePopContext(state, nextTagName) { + var parentTagName; + while (true) { + if (!state.context) { + return; + } + parentTagName = state.context.tagName; + if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || + !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { + return; + } + popContext(state); + } + } + + function baseState(type, stream, state) { + if (type == "openTag") { + state.tagName = tagName; + state.tagStart = stream.column(); + return attrState; + } else if (type == "closeTag") { + var err = false; + if (state.context) { + if (state.context.tagName != tagName) { + if (Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName)) + popContext(state); + err = !state.context || state.context.tagName != tagName; + } + } else { + err = true; + } + if (err) setStyle = "error"; + return err ? closeStateErr : closeState; + } else { + return baseState; + } + } + + function closeState(type, _stream, state) { + if (type != "endTag") { + setStyle = "error"; + return closeState; + } + popContext(state); + return baseState; + } + function closeStateErr(type, stream, state) { + setStyle = "error"; + return closeState(type, stream, state); + } + + function attrState(type, _stream, state) { + if (type == "word") { + setStyle = "attribute"; + return attrEqState; + } else if (type == "endTag" || type == "selfcloseTag") { + var tagName = state.tagName, tagStart = state.tagStart; + state.tagName = state.tagStart = null; + if (type == "selfcloseTag" || + Kludges.autoSelfClosers.hasOwnProperty(tagName)) { + maybePopContext(state, tagName); + } else { + maybePopContext(state, tagName); + state.context = new Context(state, tagName, tagStart == state.indented); + } + return baseState; + } + setStyle = "error"; + return attrState; + } + function attrEqState(type, stream, state) { + if (type == "equals") return attrValueState; + if (!Kludges.allowMissing) setStyle = "error"; + return attrState(type, stream, state); + } + function attrValueState(type, stream, state) { + if (type == "string") return attrContinuedState; + if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;} + setStyle = "error"; + return attrState(type, stream, state); + } + function attrContinuedState(type, stream, state) { + if (type == "string") return attrContinuedState; + return attrState(type, stream, state); + } + + return { + startState: function() { + return {tokenize: inText, + state: baseState, + indented: 0, + tagName: null, tagStart: null, + context: null}; + }, + + token: function(stream, state) { + if (!state.tagName && stream.sol()) + state.indented = stream.indentation(); + + if (stream.eatSpace()) return null; + tagName = type = null; + var style = state.tokenize(stream, state); + if ((style || type) && style != "comment") { + setStyle = null; + state.state = state.state(type || style, stream, state); + if (setStyle) + style = setStyle == "error" ? style + " error" : setStyle; + } + return style; + }, + + indent: function(state, textAfter, fullLine) { + var context = state.context; + // Indent multi-line strings (e.g. css). + if (state.tokenize.isInAttribute) { + return state.stringStartCol + 1; + } + if (context && context.noIndent) return CodeMirror.Pass; + if (state.tokenize != inTag && state.tokenize != inText) + return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; + // Indent the starts of attribute names. + if (state.tagName) { + if (multilineTagIndentPastTag) + return state.tagStart + state.tagName.length + 2; + else + return state.tagStart + indentUnit * multilineTagIndentFactor; + } + if (alignCDATA && /", + + configuration: parserConfig.htmlMode ? "html" : "xml", + helperType: parserConfig.htmlMode ? "html" : "xml" + }; +}); + +CodeMirror.defineMIME("text/xml", "xml"); +CodeMirror.defineMIME("application/xml", "xml"); +if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) + CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); + +}); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/theme/monokai.css b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/theme/monokai.css new file mode 100644 index 0000000..7ac601a --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/codemirror/theme/monokai.css @@ -0,0 +1,29 @@ +/* Based on Sublime Text's Monokai theme */ + +.cm-s-monokai.CodeMirror {background: #272822; color: #f8f8f2;} +.cm-s-monokai div.CodeMirror-selected {background: #49483E !important;} +.cm-s-monokai .CodeMirror-gutters {background: #272822; border-right: 0px;} +.cm-s-monokai .CodeMirror-linenumber {color: #d0d0d0;} +.cm-s-monokai .CodeMirror-cursor {border-left: 1px solid #f8f8f0 !important;} + +.cm-s-monokai span.cm-comment {color: #75715e;} +.cm-s-monokai span.cm-atom {color: #ae81ff;} +.cm-s-monokai span.cm-number {color: #ae81ff;} + +.cm-s-monokai span.cm-property, .cm-s-monokai span.cm-attribute {color: #a6e22e;} +.cm-s-monokai span.cm-keyword {color: #f92672;} +.cm-s-monokai span.cm-string {color: #e6db74;} + +.cm-s-monokai span.cm-variable {color: #a6e22e;} +.cm-s-monokai span.cm-variable-2 {color: #9effff;} +.cm-s-monokai span.cm-def {color: #fd971f;} +.cm-s-monokai span.cm-bracket {color: #f8f8f2;} +.cm-s-monokai span.cm-tag {color: #f92672;} +.cm-s-monokai span.cm-link {color: #ae81ff;} +.cm-s-monokai span.cm-error {background: #f92672; color: #f8f8f0;} + +.cm-s-monokai .CodeMirror-activeline-background {background: #373831 !important;} +.cm-s-monokai .CodeMirror-matchingbracket { + text-decoration: underline; + color: white !important; +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/css/basic.css b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/css/basic.css new file mode 100644 index 0000000..83084db --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/css/basic.css @@ -0,0 +1,155 @@ +/* The MIT License */ +.dropzone, +.dropzone *, +.dropzone-previews, +.dropzone-previews * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.dropzone { + position: relative; + border: 1px solid rgba(0,0,0,0.08); + background: rgba(0,0,0,0.02); + padding: 1em; +} +.dropzone.dz-clickable { + cursor: pointer; +} +.dropzone.dz-clickable .dz-message, +.dropzone.dz-clickable .dz-message span { + cursor: pointer; +} +.dropzone.dz-clickable * { + cursor: default; +} +.dropzone .dz-message { + opacity: 1; + -ms-filter: none; + filter: none; +} +.dropzone.dz-drag-hover { + border-color: rgba(0,0,0,0.15); + background: rgba(0,0,0,0.04); +} +.dropzone.dz-started .dz-message { + display: none; +} +.dropzone .dz-preview, +.dropzone-previews .dz-preview { + background: rgba(255,255,255,0.8); + position: relative; + display: inline-block; + margin: 17px; + vertical-align: top; + border: 1px solid #acacac; + padding: 6px 6px 6px 6px; +} +.dropzone .dz-preview.dz-file-preview [data-dz-thumbnail], +.dropzone-previews .dz-preview.dz-file-preview [data-dz-thumbnail] { + display: none; +} +.dropzone .dz-preview .dz-details, +.dropzone-previews .dz-preview .dz-details { + width: 100px; + height: 100px; + position: relative; + background: #ebebeb; + padding: 5px; + margin-bottom: 22px; +} +.dropzone .dz-preview .dz-details .dz-filename, +.dropzone-previews .dz-preview .dz-details .dz-filename { + overflow: hidden; + height: 100%; +} +.dropzone .dz-preview .dz-details img, +.dropzone-previews .dz-preview .dz-details img { + position: absolute; + top: 0; + left: 0; + width: 100px; + height: 100px; +} +.dropzone .dz-preview .dz-details .dz-size, +.dropzone-previews .dz-preview .dz-details .dz-size { + position: absolute; + bottom: -28px; + left: 3px; + height: 28px; + line-height: 28px; +} +.dropzone .dz-preview.dz-error .dz-error-mark, +.dropzone-previews .dz-preview.dz-error .dz-error-mark { + display: block; +} +.dropzone .dz-preview.dz-success .dz-success-mark, +.dropzone-previews .dz-preview.dz-success .dz-success-mark { + display: block; +} +.dropzone .dz-preview:hover .dz-details img, +.dropzone-previews .dz-preview:hover .dz-details img { + display: none; +} +.dropzone .dz-preview .dz-success-mark, +.dropzone-previews .dz-preview .dz-success-mark, +.dropzone .dz-preview .dz-error-mark, +.dropzone-previews .dz-preview .dz-error-mark { + display: none; + position: absolute; + width: 40px; + height: 40px; + font-size: 30px; + text-align: center; + right: -10px; + top: -10px; +} +.dropzone .dz-preview .dz-success-mark, +.dropzone-previews .dz-preview .dz-success-mark { + color: #8cc657; +} +.dropzone .dz-preview .dz-error-mark, +.dropzone-previews .dz-preview .dz-error-mark { + color: #ee162d; +} +.dropzone .dz-preview .dz-progress, +.dropzone-previews .dz-preview .dz-progress { + position: absolute; + top: 100px; + left: 6px; + right: 6px; + height: 6px; + background: #d7d7d7; + display: none; +} +.dropzone .dz-preview .dz-progress .dz-upload, +.dropzone-previews .dz-preview .dz-progress .dz-upload { + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 0%; + background-color: #8cc657; +} +.dropzone .dz-preview.dz-processing .dz-progress, +.dropzone-previews .dz-preview.dz-processing .dz-progress { + display: block; +} +.dropzone .dz-preview .dz-error-message, +.dropzone-previews .dz-preview .dz-error-message { + display: none; + position: absolute; + top: -5px; + left: -20px; + background: rgba(245,245,245,0.8); + padding: 8px 10px; + color: #800; + min-width: 140px; + max-width: 500px; + z-index: 500; +} +.dropzone .dz-preview:hover.dz-error .dz-error-message, +.dropzone-previews .dz-preview:hover.dz-error .dz-error-message { + display: block; +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/css/dropzone.css b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/css/dropzone.css new file mode 100644 index 0000000..48e0df4 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/css/dropzone.css @@ -0,0 +1,410 @@ +/* The MIT License */ +.dropzone, +.dropzone *, +.dropzone-previews, +.dropzone-previews * { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.dropzone { + position: relative; + border: 1px solid rgba(0,0,0,0.08); + background: rgba(0,0,0,0.02); + padding: 1em; +} +.dropzone.dz-clickable { + cursor: pointer; +} +.dropzone.dz-clickable .dz-message, +.dropzone.dz-clickable .dz-message span { + cursor: pointer; +} +.dropzone.dz-clickable * { + cursor: default; +} +.dropzone .dz-message { + opacity: 1; + -ms-filter: none; + filter: none; +} +.dropzone.dz-drag-hover { + border-color: rgba(0,0,0,0.15); + background: rgba(0,0,0,0.04); +} +.dropzone.dz-started .dz-message { + display: none; +} +.dropzone .dz-preview, +.dropzone-previews .dz-preview { + background: rgba(255,255,255,0.8); + position: relative; + display: inline-block; + margin: 17px; + vertical-align: top; + border: 1px solid #acacac; + padding: 6px 6px 6px 6px; +} +.dropzone .dz-preview.dz-file-preview [data-dz-thumbnail], +.dropzone-previews .dz-preview.dz-file-preview [data-dz-thumbnail] { + display: none; +} +.dropzone .dz-preview .dz-details, +.dropzone-previews .dz-preview .dz-details { + width: 100px; + height: 100px; + position: relative; + background: #ebebeb; + padding: 5px; + margin-bottom: 22px; +} +.dropzone .dz-preview .dz-details .dz-filename, +.dropzone-previews .dz-preview .dz-details .dz-filename { + overflow: hidden; + height: 100%; +} +.dropzone .dz-preview .dz-details img, +.dropzone-previews .dz-preview .dz-details img { + position: absolute; + top: 0; + left: 0; + width: 100px; + height: 100px; +} +.dropzone .dz-preview .dz-details .dz-size, +.dropzone-previews .dz-preview .dz-details .dz-size { + position: absolute; + bottom: -28px; + left: 3px; + height: 28px; + line-height: 28px; +} +.dropzone .dz-preview.dz-error .dz-error-mark, +.dropzone-previews .dz-preview.dz-error .dz-error-mark { + display: block; +} +.dropzone .dz-preview.dz-success .dz-success-mark, +.dropzone-previews .dz-preview.dz-success .dz-success-mark { + display: block; +} +.dropzone .dz-preview:hover .dz-details img, +.dropzone-previews .dz-preview:hover .dz-details img { + display: none; +} +.dropzone .dz-preview .dz-success-mark, +.dropzone-previews .dz-preview .dz-success-mark, +.dropzone .dz-preview .dz-error-mark, +.dropzone-previews .dz-preview .dz-error-mark { + display: none; + position: absolute; + width: 40px; + height: 40px; + font-size: 30px; + text-align: center; + right: -10px; + top: -10px; +} +.dropzone .dz-preview .dz-success-mark, +.dropzone-previews .dz-preview .dz-success-mark { + color: #8cc657; +} +.dropzone .dz-preview .dz-error-mark, +.dropzone-previews .dz-preview .dz-error-mark { + color: #ee162d; +} +.dropzone .dz-preview .dz-progress, +.dropzone-previews .dz-preview .dz-progress { + position: absolute; + top: 100px; + left: 6px; + right: 6px; + height: 6px; + background: #d7d7d7; + display: none; +} +.dropzone .dz-preview .dz-progress .dz-upload, +.dropzone-previews .dz-preview .dz-progress .dz-upload { + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 0%; + background-color: #8cc657; +} +.dropzone .dz-preview.dz-processing .dz-progress, +.dropzone-previews .dz-preview.dz-processing .dz-progress { + display: block; +} +.dropzone .dz-preview .dz-error-message, +.dropzone-previews .dz-preview .dz-error-message { + display: none; + position: absolute; + top: -5px; + left: -20px; + background: rgba(245,245,245,0.8); + padding: 8px 10px; + color: #800; + min-width: 140px; + max-width: 500px; + z-index: 500; +} +.dropzone .dz-preview:hover.dz-error .dz-error-message, +.dropzone-previews .dz-preview:hover.dz-error .dz-error-message { + display: block; +} +.dropzone { + border: 1px solid rgba(0,0,0,0.03); + min-height: 360px; + -webkit-border-radius: 3px; + border-radius: 3px; + background: rgba(0,0,0,0.03); + padding: 23px; +} +.dropzone .dz-default.dz-message { + opacity: 1; + -ms-filter: none; + filter: none; + -webkit-transition: opacity 0.3s ease-in-out; + -moz-transition: opacity 0.3s ease-in-out; + -o-transition: opacity 0.3s ease-in-out; + -ms-transition: opacity 0.3s ease-in-out; + transition: opacity 0.3s ease-in-out; + background-image: url("../images/spritemap.png"); + background-repeat: no-repeat; + background-position: 0 0; + position: absolute; + width: 428px; + height: 123px; + margin-left: -214px; + margin-top: -61.5px; + top: 50%; + left: 50%; +} +@media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) { + .dropzone .dz-default.dz-message { + background-image: url("../images/spritemap%402x.png"); + -webkit-background-size: 428px 406px; + -moz-background-size: 428px 406px; + background-size: 428px 406px; + } +} +.dropzone .dz-default.dz-message span { + display: none; +} +.dropzone.dz-square .dz-default.dz-message { + background-position: 0 -123px; + width: 268px; + margin-left: -134px; + height: 174px; + margin-top: -87px; +} +.dropzone.dz-drag-hover .dz-message { + opacity: 0.15; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=15)"; + filter: alpha(opacity=15); +} +.dropzone.dz-started .dz-message { + display: block; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); +} +.dropzone .dz-preview, +.dropzone-previews .dz-preview { + -webkit-box-shadow: 1px 1px 4px rgba(0,0,0,0.16); + box-shadow: 1px 1px 4px rgba(0,0,0,0.16); + font-size: 14px; +} +.dropzone .dz-preview.dz-image-preview:hover .dz-details img, +.dropzone-previews .dz-preview.dz-image-preview:hover .dz-details img { + display: block; + opacity: 0.1; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=10)"; + filter: alpha(opacity=10); +} +.dropzone .dz-preview.dz-success .dz-success-mark, +.dropzone-previews .dz-preview.dz-success .dz-success-mark { + opacity: 1; + -ms-filter: none; + filter: none; +} +.dropzone .dz-preview.dz-error .dz-error-mark, +.dropzone-previews .dz-preview.dz-error .dz-error-mark { + opacity: 1; + -ms-filter: none; + filter: none; +} +.dropzone .dz-preview.dz-error .dz-progress .dz-upload, +.dropzone-previews .dz-preview.dz-error .dz-progress .dz-upload { + background: #ee1e2d; +} +.dropzone .dz-preview .dz-error-mark, +.dropzone-previews .dz-preview .dz-error-mark, +.dropzone .dz-preview .dz-success-mark, +.dropzone-previews .dz-preview .dz-success-mark { + display: block; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: opacity 0.4s ease-in-out; + -moz-transition: opacity 0.4s ease-in-out; + -o-transition: opacity 0.4s ease-in-out; + -ms-transition: opacity 0.4s ease-in-out; + transition: opacity 0.4s ease-in-out; + background-image: url("../images/spritemap.png"); + background-repeat: no-repeat; +} +@media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) { + .dropzone .dz-preview .dz-error-mark, + .dropzone-previews .dz-preview .dz-error-mark, + .dropzone .dz-preview .dz-success-mark, + .dropzone-previews .dz-preview .dz-success-mark { + background-image: url("../images/spritemap%402x.png"); + -webkit-background-size: 428px 406px; + -moz-background-size: 428px 406px; + background-size: 428px 406px; + } +} +.dropzone .dz-preview .dz-error-mark span, +.dropzone-previews .dz-preview .dz-error-mark span, +.dropzone .dz-preview .dz-success-mark span, +.dropzone-previews .dz-preview .dz-success-mark span { + display: none; +} +.dropzone .dz-preview .dz-error-mark, +.dropzone-previews .dz-preview .dz-error-mark { + background-position: -268px -123px; +} +.dropzone .dz-preview .dz-success-mark, +.dropzone-previews .dz-preview .dz-success-mark { + background-position: -268px -163px; +} +.dropzone .dz-preview .dz-progress .dz-upload, +.dropzone-previews .dz-preview .dz-progress .dz-upload { + -webkit-animation: loading 0.4s linear infinite; + -moz-animation: loading 0.4s linear infinite; + -o-animation: loading 0.4s linear infinite; + -ms-animation: loading 0.4s linear infinite; + animation: loading 0.4s linear infinite; + -webkit-transition: width 0.3s ease-in-out; + -moz-transition: width 0.3s ease-in-out; + -o-transition: width 0.3s ease-in-out; + -ms-transition: width 0.3s ease-in-out; + transition: width 0.3s ease-in-out; + -webkit-border-radius: 2px; + border-radius: 2px; + position: absolute; + top: 0; + left: 0; + width: 0%; + height: 100%; + background-image: url("../images/spritemap.png"); + background-repeat: repeat-x; + background-position: 0px -400px; +} +@media all and (-webkit-min-device-pixel-ratio:1.5),(min--moz-device-pixel-ratio:1.5),(-o-min-device-pixel-ratio:1.5/1),(min-device-pixel-ratio:1.5),(min-resolution:138dpi),(min-resolution:1.5dppx) { + .dropzone .dz-preview .dz-progress .dz-upload, + .dropzone-previews .dz-preview .dz-progress .dz-upload { + background-image: url("../images/spritemap%402x.png"); + -webkit-background-size: 428px 406px; + -moz-background-size: 428px 406px; + background-size: 428px 406px; + } +} +.dropzone .dz-preview.dz-success .dz-progress, +.dropzone-previews .dz-preview.dz-success .dz-progress { + display: block; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: opacity 0.4s ease-in-out; + -moz-transition: opacity 0.4s ease-in-out; + -o-transition: opacity 0.4s ease-in-out; + -ms-transition: opacity 0.4s ease-in-out; + transition: opacity 0.4s ease-in-out; +} +.dropzone .dz-preview .dz-error-message, +.dropzone-previews .dz-preview .dz-error-message { + display: block; + opacity: 0; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; + filter: alpha(opacity=0); + -webkit-transition: opacity 0.3s ease-in-out; + -moz-transition: opacity 0.3s ease-in-out; + -o-transition: opacity 0.3s ease-in-out; + -ms-transition: opacity 0.3s ease-in-out; + transition: opacity 0.3s ease-in-out; +} +.dropzone .dz-preview:hover.dz-error .dz-error-message, +.dropzone-previews .dz-preview:hover.dz-error .dz-error-message { + opacity: 1; + -ms-filter: none; + filter: none; +} +.dropzone a.dz-remove, +.dropzone-previews a.dz-remove { + background-image: -webkit-linear-gradient(top, #fafafa, #eee); + background-image: -moz-linear-gradient(top, #fafafa, #eee); + background-image: -o-linear-gradient(top, #fafafa, #eee); + background-image: -ms-linear-gradient(top, #fafafa, #eee); + background-image: linear-gradient(to bottom, #fafafa, #eee); + -webkit-border-radius: 2px; + border-radius: 2px; + border: 1px solid #eee; + text-decoration: none; + display: block; + padding: 4px 5px; + text-align: center; + color: #aaa; + margin-top: 26px; +} +.dropzone a.dz-remove:hover, +.dropzone-previews a.dz-remove:hover { + color: #666; +} +@-moz-keyframes loading { + 0% { + background-position: 0 -400px; + } + + 100% { + background-position: -7px -400px; + } +} +@-webkit-keyframes loading { + 0% { + background-position: 0 -400px; + } + + 100% { + background-position: -7px -400px; + } +} +@-o-keyframes loading { + 0% { + background-position: 0 -400px; + } + + 100% { + background-position: -7px -400px; + } +} +@-ms-keyframes loading { + 0% { + background-position: 0 -400px; + } + + 100% { + background-position: -7px -400px; + } +} +@keyframes loading { + 0% { + background-position: 0 -400px; + } + + 100% { + background-position: -7px -400px; + } +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/dropzone.js b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/dropzone.js new file mode 100644 index 0000000..dcdb800 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/dropzone.js @@ -0,0 +1,1823 @@ + +;(function(){ + +/** + * Require the module at `name`. + * + * @param {String} name + * @return {Object} exports + * @api public + */ + +function require(name) { + var module = require.modules[name]; + if (!module) throw new Error('failed to require "' + name + '"'); + + if (!('exports' in module) && typeof module.definition === 'function') { + module.client = module.component = true; + module.definition.call(this, module.exports = {}, module); + delete module.definition; + } + + return module.exports; +} + +/** + * Registered modules. + */ + +require.modules = {}; + +/** + * Register module at `name` with callback `definition`. + * + * @param {String} name + * @param {Function} definition + * @api private + */ + +require.register = function (name, definition) { + require.modules[name] = { + definition: definition + }; +}; + +/** + * Define a module's exports immediately with `exports`. + * + * @param {String} name + * @param {Generic} exports + * @api private + */ + +require.define = function (name, exports) { + require.modules[name] = { + exports: exports + }; +}; +require.register("component~emitter@1.1.2", function (exports, module) { + +/** + * Expose `Emitter`. + */ + +module.exports = Emitter; + +/** + * Initialize a new `Emitter`. + * + * @api public + */ + +function Emitter(obj) { + if (obj) return mixin(obj); +}; + +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + return obj; +} + +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.on = +Emitter.prototype.addEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + (this._callbacks[event] = this._callbacks[event] || []) + .push(fn); + return this; +}; + +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.once = function(event, fn){ + var self = this; + this._callbacks = this._callbacks || {}; + + function on() { + self.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; + +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + +Emitter.prototype.off = +Emitter.prototype.removeListener = +Emitter.prototype.removeAllListeners = +Emitter.prototype.removeEventListener = function(event, fn){ + this._callbacks = this._callbacks || {}; + + // all + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } + + // specific event + var callbacks = this._callbacks[event]; + if (!callbacks) return this; + + // remove all handlers + if (1 == arguments.length) { + delete this._callbacks[event]; + return this; + } + + // remove specific handler + var cb; + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } + return this; +}; + +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + +Emitter.prototype.emit = function(event){ + this._callbacks = this._callbacks || {}; + var args = [].slice.call(arguments, 1) + , callbacks = this._callbacks[event]; + + if (callbacks) { + callbacks = callbacks.slice(0); + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; + +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + +Emitter.prototype.listeners = function(event){ + this._callbacks = this._callbacks || {}; + return this._callbacks[event] || []; +}; + +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + +Emitter.prototype.hasListeners = function(event){ + return !! this.listeners(event).length; +}; + +}); + +require.register("dropzone", function (exports, module) { + + +/** + * Exposing dropzone + */ +module.exports = require("dropzone/lib/dropzone.js"); + +}); + +require.register("dropzone/lib/dropzone.js", function (exports, module) { +/* +# +# More info at [www.dropzonejs.com](http://www.dropzonejs.com) +# +# Copyright (c) 2012, Matias Meno +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +*/ + + +(function() { + var Dropzone, Em, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, + __slice = [].slice; + + Em = typeof Emitter !== "undefined" && Emitter !== null ? Emitter : require("component~emitter@1.1.2"); + + noop = function() {}; + + Dropzone = (function(_super) { + var extend; + + __extends(Dropzone, _super); + + /* + This is a list of all available events you can register on a dropzone object. + + You can register an event handler like this: + + dropzone.on("dragEnter", function() { }); + */ + + + Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached"]; + + Dropzone.prototype.defaultOptions = { + url: null, + method: "post", + withCredentials: false, + parallelUploads: 2, + uploadMultiple: false, + maxFilesize: 256, + paramName: "file", + createImageThumbnails: true, + maxThumbnailFilesize: 10, + thumbnailWidth: 100, + thumbnailHeight: 100, + maxFiles: null, + params: {}, + clickable: true, + ignoreHiddenFiles: true, + acceptedFiles: null, + acceptedMimeTypes: null, + autoProcessQueue: true, + autoQueue: true, + addRemoveLinks: false, + previewsContainer: null, + dictDefaultMessage: "Drop files here to upload", + dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.", + dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.", + dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.", + dictInvalidFileType: "You can't upload files of this type.", + dictResponseError: "Server responded with {{statusCode}} code.", + dictCancelUpload: "Cancel upload", + dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?", + dictRemoveFile: "Remove file", + dictRemoveFileConfirmation: null, + dictMaxFilesExceeded: "You can not upload any more files.", + accept: function(file, done) { + return done(); + }, + init: function() { + return noop; + }, + forceFallback: false, + fallback: function() { + var child, messageElement, span, _i, _len, _ref; + this.element.className = "" + this.element.className + " dz-browser-not-supported"; + _ref = this.element.getElementsByTagName("div"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (/(^| )dz-message($| )/.test(child.className)) { + messageElement = child; + child.className = "dz-message"; + continue; + } + } + if (!messageElement) { + messageElement = Dropzone.createElement(""); + this.element.appendChild(messageElement); + } + span = messageElement.getElementsByTagName("span")[0]; + if (span) { + span.textContent = this.options.dictFallbackMessage; + } + return this.element.appendChild(this.getFallbackForm()); + }, + resize: function(file) { + var info, srcRatio, trgRatio; + info = { + srcX: 0, + srcY: 0, + srcWidth: file.width, + srcHeight: file.height + }; + srcRatio = file.width / file.height; + info.optWidth = this.options.thumbnailWidth; + info.optHeight = this.options.thumbnailHeight; + if (!((info.optWidth != null) && (info.optHeigh != null))) { + if ((info.optWidth == null) && (info.optHeight == null)) { + info.optWidth = info.srcWidth; + info.optHeight = info.srcHeight; + } else if (info.optWidth == null) { + info.optWidth = srcRatio * info.optHeight; + } else if (info.optHeight == null) { + info.optHeight = (1 / srcRatio) * info.optWidth; + } + } + trgRatio = info.optWidth / info.optHeight; + if (file.height < info.optHeight || file.width < info.optWidth) { + info.trgHeight = info.srcHeight; + info.trgWidth = info.srcWidth; + } else { + if (srcRatio > trgRatio) { + info.srcHeight = file.height; + info.srcWidth = info.srcHeight * trgRatio; + } else { + info.srcWidth = file.width; + info.srcHeight = info.srcWidth / trgRatio; + } + } + info.srcX = (file.width - info.srcWidth) / 2; + info.srcY = (file.height - info.srcHeight) / 2; + return info; + }, + /* + Those functions register themselves to the events on init and handle all + the user interface specific stuff. Overwriting them won't break the upload + but can break the way it's displayed. + You can overwrite them if you don't like the default behavior. If you just + want to add an additional event handler, register it on the dropzone object + and don't overwrite those options. + */ + + drop: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + dragstart: noop, + dragend: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + dragenter: function(e) { + return this.element.classList.add("dz-drag-hover"); + }, + dragover: function(e) { + return this.element.classList.add("dz-drag-hover"); + }, + dragleave: function(e) { + return this.element.classList.remove("dz-drag-hover"); + }, + paste: noop, + reset: function() { + return this.element.classList.remove("dz-started"); + }, + addedfile: function(file) { + var node, removeFileEvent, removeLink, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results, + _this = this; + if (this.element === this.previewsContainer) { + this.element.classList.add("dz-started"); + } + file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim()); + file.previewTemplate = file.previewElement; + this.previewsContainer.appendChild(file.previewElement); + _ref = file.previewElement.querySelectorAll("[data-dz-name]"); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + node = _ref[_i]; + node.textContent = file.name; + } + _ref1 = file.previewElement.querySelectorAll("[data-dz-size]"); + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + node = _ref1[_j]; + node.innerHTML = this.filesize(file.size); + } + if (this.options.addRemoveLinks) { + file._removeLink = Dropzone.createElement("" + this.options.dictRemoveFile + ""); + file.previewElement.appendChild(file._removeLink); + } + removeFileEvent = function(e) { + e.preventDefault(); + e.stopPropagation(); + if (file.status === Dropzone.UPLOADING) { + return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() { + return _this.removeFile(file); + }); + } else { + if (_this.options.dictRemoveFileConfirmation) { + return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() { + return _this.removeFile(file); + }); + } else { + return _this.removeFile(file); + } + } + }; + _ref2 = file.previewElement.querySelectorAll("[data-dz-remove]"); + _results = []; + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + removeLink = _ref2[_k]; + _results.push(removeLink.addEventListener("click", removeFileEvent)); + } + return _results; + }, + removedfile: function(file) { + var _ref; + if ((_ref = file.previewElement) != null) { + _ref.parentNode.removeChild(file.previewElement); + } + return this._updateMaxFilesReachedClass(); + }, + thumbnail: function(file, dataUrl) { + var thumbnailElement, _i, _len, _ref, _results; + file.previewElement.classList.remove("dz-file-preview"); + file.previewElement.classList.add("dz-image-preview"); + _ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]"); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + thumbnailElement = _ref[_i]; + thumbnailElement.alt = file.name; + _results.push(thumbnailElement.src = dataUrl); + } + return _results; + }, + error: function(file, message) { + var node, _i, _len, _ref, _results; + file.previewElement.classList.add("dz-error"); + if (typeof message !== "String" && message.error) { + message = message.error; + } + _ref = file.previewElement.querySelectorAll("[data-dz-errormessage]"); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + node = _ref[_i]; + _results.push(node.textContent = message); + } + return _results; + }, + errormultiple: noop, + processing: function(file) { + file.previewElement.classList.add("dz-processing"); + if (file._removeLink) { + return file._removeLink.textContent = this.options.dictCancelUpload; + } + }, + processingmultiple: noop, + uploadprogress: function(file, progress, bytesSent) { + var node, _i, _len, _ref, _results; + _ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]"); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + node = _ref[_i]; + _results.push(node.style.width = "" + progress + "%"); + } + return _results; + }, + totaluploadprogress: noop, + sending: noop, + sendingmultiple: noop, + success: function(file) { + return file.previewElement.classList.add("dz-success"); + }, + successmultiple: noop, + canceled: function(file) { + return this.emit("error", file, "Upload canceled."); + }, + canceledmultiple: noop, + complete: function(file) { + if (file._removeLink) { + return file._removeLink.textContent = this.options.dictRemoveFile; + } + }, + completemultiple: noop, + maxfilesexceeded: noop, + maxfilesreached: noop, + previewTemplate: "';});q.on('uiReady',function(u){q.document.on('dragstart',function(y){y.data.preventDefault(true);});q.document.on('drag',function(y){y.data.preventDefault(true);});var v,w=q.aG['filesview.filesview'];for(v=0;v\n" + }; + + extend = function() { + var key, object, objects, target, val, _i, _len; + target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : []; + for (_i = 0, _len = objects.length; _i < _len; _i++) { + object = objects[_i]; + for (key in object) { + val = object[key]; + target[key] = val; + } + } + return target; + }; + + function Dropzone(element, options) { + var elementOptions, fallback, _ref; + this.element = element; + this.version = Dropzone.version; + this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, ""); + this.clickableElements = []; + this.listeners = []; + this.files = []; + if (typeof this.element === "string") { + this.element = document.querySelector(this.element); + } + if (!(this.element && (this.element.nodeType != null))) { + throw new Error("Invalid dropzone element."); + } + if (this.element.dropzone) { + throw new Error("Dropzone already attached."); + } + Dropzone.instances.push(this); + this.element.dropzone = this; + elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {}; + this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {}); + if (this.options.forceFallback || !Dropzone.isBrowserSupported()) { + return this.options.fallback.call(this); + } + if (this.options.url == null) { + this.options.url = this.element.getAttribute("action"); + } + if (!this.options.url) { + throw new Error("No URL provided."); + } + if (this.options.acceptedFiles && this.options.acceptedMimeTypes) { + throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated."); + } + if (this.options.acceptedMimeTypes) { + this.options.acceptedFiles = this.options.acceptedMimeTypes; + delete this.options.acceptedMimeTypes; + } + this.options.method = this.options.method.toUpperCase(); + if ((fallback = this.getExistingFallback()) && fallback.parentNode) { + fallback.parentNode.removeChild(fallback); + } + if (this.options.previewsContainer) { + this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer"); + } else { + this.previewsContainer = this.element; + } + if (this.options.clickable) { + if (this.options.clickable === true) { + this.clickableElements = [this.element]; + } else { + this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable"); + } + } + this.init(); + } + + Dropzone.prototype.getAcceptedFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.accepted) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getRejectedFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (!file.accepted) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getFilesWithStatus = function(status) { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status === status) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.getQueuedFiles = function() { + return this.getFilesWithStatus(Dropzone.QUEUED); + }; + + Dropzone.prototype.getUploadingFiles = function() { + return this.getFilesWithStatus(Dropzone.UPLOADING); + }; + + Dropzone.prototype.getActiveFiles = function() { + var file, _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) { + _results.push(file); + } + } + return _results; + }; + + Dropzone.prototype.init = function() { + var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1, + _this = this; + if (this.element.tagName === "form") { + this.element.setAttribute("enctype", "multipart/form-data"); + } + if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) { + this.element.appendChild(Dropzone.createElement("\n\n\n \n\n
\n✔\n✘\n \n" + this.options.dictDefaultMessage + "")); + } + if (this.clickableElements.length) { + setupHiddenFileInput = function() { + if (_this.hiddenFileInput) { + document.body.removeChild(_this.hiddenFileInput); + } + _this.hiddenFileInput = document.createElement("input"); + _this.hiddenFileInput.setAttribute("type", "file"); + if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) { + _this.hiddenFileInput.setAttribute("multiple", "multiple"); + } + _this.hiddenFileInput.className = "dz-hidden-input"; + if (_this.options.acceptedFiles != null) { + _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles); + } + _this.hiddenFileInput.style.visibility = "hidden"; + _this.hiddenFileInput.style.position = "absolute"; + _this.hiddenFileInput.style.top = "0"; + _this.hiddenFileInput.style.left = "0"; + _this.hiddenFileInput.style.height = "0"; + _this.hiddenFileInput.style.width = "0"; + document.body.appendChild(_this.hiddenFileInput); + return _this.hiddenFileInput.addEventListener("change", function() { + var file, files, _i, _len; + files = _this.hiddenFileInput.files; + if (files.length) { + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + _this.addFile(file); + } + } + return setupHiddenFileInput(); + }); + }; + setupHiddenFileInput(); + } + this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL; + _ref1 = this.events; + for (_i = 0, _len = _ref1.length; _i < _len; _i++) { + eventName = _ref1[_i]; + this.on(eventName, this.options[eventName]); + } + this.on("uploadprogress", function() { + return _this.updateTotalUploadProgress(); + }); + this.on("removedfile", function() { + return _this.updateTotalUploadProgress(); + }); + this.on("canceled", function(file) { + return _this.emit("complete", file); + }); + this.on("complete", function(file) { + if (_this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) { + return setTimeout((function() { + return _this.emit("queuecomplete"); + }), 0); + } + }); + noPropagation = function(e) { + e.stopPropagation(); + if (e.preventDefault) { + return e.preventDefault(); + } else { + return e.returnValue = false; + } + }; + this.listeners = [ + { + element: this.element, + events: { + "dragstart": function(e) { + return _this.emit("dragstart", e); + }, + "dragenter": function(e) { + noPropagation(e); + return _this.emit("dragenter", e); + }, + "dragover": function(e) { + var efct; + try { + efct = e.dataTransfer.effectAllowed; + } catch (_error) {} + e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy'; + noPropagation(e); + return _this.emit("dragover", e); + }, + "dragleave": function(e) { + return _this.emit("dragleave", e); + }, + "drop": function(e) { + noPropagation(e); + return _this.drop(e); + }, + "dragend": function(e) { + return _this.emit("dragend", e); + } + } + } + ]; + this.clickableElements.forEach(function(clickableElement) { + return _this.listeners.push({ + element: clickableElement, + events: { + "click": function(evt) { + if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) { + return _this.hiddenFileInput.click(); + } + } + } + }); + }); + this.enable(); + return this.options.init.call(this); + }; + + Dropzone.prototype.destroy = function() { + var _ref; + this.disable(); + this.removeAllFiles(true); + if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) { + this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput); + this.hiddenFileInput = null; + } + delete this.element.dropzone; + return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1); + }; + + Dropzone.prototype.updateTotalUploadProgress = function() { + var activeFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref; + totalBytesSent = 0; + totalBytes = 0; + activeFiles = this.getActiveFiles(); + if (activeFiles.length) { + _ref = this.getActiveFiles(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + totalBytesSent += file.upload.bytesSent; + totalBytes += file.upload.total; + } + totalUploadProgress = 100 * totalBytesSent / totalBytes; + } else { + totalUploadProgress = 100; + } + return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent); + }; + + Dropzone.prototype._getParamName = function(n) { + if (typeof this.options.paramName === "function") { + return this.options.paramName(n); + } else { + return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : ""); + } + }; + + Dropzone.prototype.getFallbackForm = function() { + var existingFallback, fields, fieldsString, form; + if (existingFallback = this.getExistingFallback()) { + return existingFallback; + } + fieldsString = ""; + if (this.options.dictFallbackText) { + fieldsString += ""; + fields = Dropzone.createElement(fieldsString); + if (this.element.tagName !== "FORM") { + form = Dropzone.createElement(""); + form.appendChild(fields); + } else { + this.element.setAttribute("enctype", "multipart/form-data"); + this.element.setAttribute("method", this.options.method); + } + return form != null ? form : fields; + }; + + Dropzone.prototype.getExistingFallback = function() { + var fallback, getFallback, tagName, _i, _len, _ref; + getFallback = function(elements) { + var el, _i, _len; + for (_i = 0, _len = elements.length; _i < _len; _i++) { + el = elements[_i]; + if (/(^| )fallback($| )/.test(el.className)) { + return el; + } + } + }; + _ref = ["div", "form"]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + tagName = _ref[_i]; + if (fallback = getFallback(this.element.getElementsByTagName(tagName))) { + return fallback; + } + } + }; + + Dropzone.prototype.setupEventListeners = function() { + var elementListeners, event, listener, _i, _len, _ref, _results; + _ref = this.listeners; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elementListeners = _ref[_i]; + _results.push((function() { + var _ref1, _results1; + _ref1 = elementListeners.events; + _results1 = []; + for (event in _ref1) { + listener = _ref1[event]; + _results1.push(elementListeners.element.addEventListener(event, listener, false)); + } + return _results1; + })()); + } + return _results; + }; + + Dropzone.prototype.removeEventListeners = function() { + var elementListeners, event, listener, _i, _len, _ref, _results; + _ref = this.listeners; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + elementListeners = _ref[_i]; + _results.push((function() { + var _ref1, _results1; + _ref1 = elementListeners.events; + _results1 = []; + for (event in _ref1) { + listener = _ref1[event]; + _results1.push(elementListeners.element.removeEventListener(event, listener, false)); + } + return _results1; + })()); + } + return _results; + }; + + Dropzone.prototype.disable = function() { + var file, _i, _len, _ref, _results; + this.clickableElements.forEach(function(element) { + return element.classList.remove("dz-clickable"); + }); + this.removeEventListeners(); + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + _results.push(this.cancelUpload(file)); + } + return _results; + }; + + Dropzone.prototype.enable = function() { + this.clickableElements.forEach(function(element) { + return element.classList.add("dz-clickable"); + }); + return this.setupEventListeners(); + }; + + Dropzone.prototype.filesize = function(size) { + var string; + if (size >= 1024 * 1024 * 1024 * 1024 / 10) { + size = size / (1024 * 1024 * 1024 * 1024 / 10); + string = "TiB"; + } else if (size >= 1024 * 1024 * 1024 / 10) { + size = size / (1024 * 1024 * 1024 / 10); + string = "GiB"; + } else if (size >= 1024 * 1024 / 10) { + size = size / (1024 * 1024 / 10); + string = "MiB"; + } else if (size >= 1024 / 10) { + size = size / (1024 / 10); + string = "KiB"; + } else { + size = size * 10; + string = "b"; + } + return "" + (Math.round(size) / 10) + " " + string; + }; + + Dropzone.prototype._updateMaxFilesReachedClass = function() { + if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) { + if (this.getAcceptedFiles().length === this.options.maxFiles) { + this.emit('maxfilesreached', this.files); + } + return this.element.classList.add("dz-max-files-reached"); + } else { + return this.element.classList.remove("dz-max-files-reached"); + } + }; + + Dropzone.prototype.drop = function(e) { + var files, items; + if (!e.dataTransfer) { + return; + } + this.emit("drop", e); + files = e.dataTransfer.files; + if (files.length) { + items = e.dataTransfer.items; + if (items && items.length && (items[0].webkitGetAsEntry != null)) { + this._addFilesFromItems(items); + } else { + this.handleFiles(files); + } + } + }; + + Dropzone.prototype.paste = function(e) { + var items, _ref; + if ((e != null ? (_ref = e.clipboardData) != null ? _ref.items : void 0 : void 0) == null) { + return; + } + this.emit("paste", e); + items = e.clipboardData.items; + if (items.length) { + return this._addFilesFromItems(items); + } + }; + + Dropzone.prototype.handleFiles = function(files) { + var file, _i, _len, _results; + _results = []; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + _results.push(this.addFile(file)); + } + return _results; + }; + + Dropzone.prototype._addFilesFromItems = function(items) { + var entry, item, _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) { + if (entry.isFile) { + _results.push(this.addFile(item.getAsFile())); + } else if (entry.isDirectory) { + _results.push(this._addFilesFromDirectory(entry, entry.name)); + } else { + _results.push(void 0); + } + } else if (item.getAsFile != null) { + if ((item.kind == null) || item.kind === "file") { + _results.push(this.addFile(item.getAsFile())); + } else { + _results.push(void 0); + } + } else { + _results.push(void 0); + } + } + return _results; + }; + + Dropzone.prototype._addFilesFromDirectory = function(directory, path) { + var dirReader, entriesReader, + _this = this; + dirReader = directory.createReader(); + entriesReader = function(entries) { + var entry, _i, _len; + for (_i = 0, _len = entries.length; _i < _len; _i++) { + entry = entries[_i]; + if (entry.isFile) { + entry.file(function(file) { + if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') { + return; + } + file.fullPath = "" + path + "/" + file.name; + return _this.addFile(file); + }); + } else if (entry.isDirectory) { + _this._addFilesFromDirectory(entry, "" + path + "/" + entry.name); + } + } + }; + return dirReader.readEntries(entriesReader, function(error) { + return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0; + }); + }; + + Dropzone.prototype.accept = function(file, done) { + if (file.size > this.options.maxFilesize * 1024 * 1024) { + return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize)); + } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) { + return done(this.options.dictInvalidFileType); + } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) { + done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles)); + return this.emit("maxfilesexceeded", file); + } else { + return this.options.accept.call(this, file, done); + } + }; + + Dropzone.prototype.addFile = function(file) { + var _this = this; + file.upload = { + progress: 0, + total: file.size, + bytesSent: 0 + }; + this.files.push(file); + file.status = Dropzone.ADDED; + this.emit("addedfile", file); + this._enqueueThumbnail(file); + return this.accept(file, function(error) { + if (error) { + file.accepted = false; + _this._errorProcessing([file], error); + } else { + file.accepted = true; + if (_this.options.autoQueue) { + _this.enqueueFile(file); + } + } + return _this._updateMaxFilesReachedClass(); + }); + }; + + Dropzone.prototype.enqueueFiles = function(files) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + this.enqueueFile(file); + } + return null; + }; + + Dropzone.prototype.enqueueFile = function(file) { + var _this = this; + if (file.status === Dropzone.ADDED && file.accepted === true) { + file.status = Dropzone.QUEUED; + if (this.options.autoProcessQueue) { + return setTimeout((function() { + return _this.processQueue(); + }), 0); + } + } else { + throw new Error("This file can't be queued because it has already been processed or was rejected."); + } + }; + + Dropzone.prototype._thumbnailQueue = []; + + Dropzone.prototype._processingThumbnail = false; + + Dropzone.prototype._enqueueThumbnail = function(file) { + var _this = this; + if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) { + this._thumbnailQueue.push(file); + return setTimeout((function() { + return _this._processThumbnailQueue(); + }), 0); + } + }; + + Dropzone.prototype._processThumbnailQueue = function() { + var _this = this; + if (this._processingThumbnail || this._thumbnailQueue.length === 0) { + return; + } + this._processingThumbnail = true; + return this.createThumbnail(this._thumbnailQueue.shift(), function() { + _this._processingThumbnail = false; + return _this._processThumbnailQueue(); + }); + }; + + Dropzone.prototype.removeFile = function(file) { + if (file.status === Dropzone.UPLOADING) { + this.cancelUpload(file); + } + this.files = without(this.files, file); + this.emit("removedfile", file); + if (this.files.length === 0) { + return this.emit("reset"); + } + }; + + Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) { + var file, _i, _len, _ref; + if (cancelIfNecessary == null) { + cancelIfNecessary = false; + } + _ref = this.files.slice(); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) { + this.removeFile(file); + } + } + return null; + }; + + Dropzone.prototype.createThumbnail = function(file, callback) { + var fileReader, + _this = this; + fileReader = new FileReader; + fileReader.onload = function() { + var img; + img = document.createElement("img"); + img.onload = function() { + var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3; + file.width = img.width; + file.height = img.height; + resizeInfo = _this.options.resize.call(_this, file); + if (resizeInfo.trgWidth == null) { + resizeInfo.trgWidth = resizeInfo.optWidth; + } + if (resizeInfo.trgHeight == null) { + resizeInfo.trgHeight = resizeInfo.optHeight; + } + canvas = document.createElement("canvas"); + ctx = canvas.getContext("2d"); + canvas.width = resizeInfo.trgWidth; + canvas.height = resizeInfo.trgHeight; + drawImageIOSFix(ctx, img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight); + thumbnail = canvas.toDataURL("image/png"); + _this.emit("thumbnail", file, thumbnail); + if (callback != null) { + return callback(); + } + }; + return img.src = fileReader.result; + }; + return fileReader.readAsDataURL(file); + }; + + Dropzone.prototype.processQueue = function() { + var i, parallelUploads, processingLength, queuedFiles; + parallelUploads = this.options.parallelUploads; + processingLength = this.getUploadingFiles().length; + i = processingLength; + if (processingLength >= parallelUploads) { + return; + } + queuedFiles = this.getQueuedFiles(); + if (!(queuedFiles.length > 0)) { + return; + } + if (this.options.uploadMultiple) { + return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength)); + } else { + while (i < parallelUploads) { + if (!queuedFiles.length) { + return; + } + this.processFile(queuedFiles.shift()); + i++; + } + } + }; + + Dropzone.prototype.processFile = function(file) { + return this.processFiles([file]); + }; + + Dropzone.prototype.processFiles = function(files) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.processing = true; + file.status = Dropzone.UPLOADING; + this.emit("processing", file); + } + if (this.options.uploadMultiple) { + this.emit("processingmultiple", files); + } + return this.uploadFiles(files); + }; + + Dropzone.prototype._getFilesWithXhr = function(xhr) { + var file, files; + return files = (function() { + var _i, _len, _ref, _results; + _ref = this.files; + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + file = _ref[_i]; + if (file.xhr === xhr) { + _results.push(file); + } + } + return _results; + }).call(this); + }; + + Dropzone.prototype.cancelUpload = function(file) { + var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref; + if (file.status === Dropzone.UPLOADING) { + groupedFiles = this._getFilesWithXhr(file.xhr); + for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) { + groupedFile = groupedFiles[_i]; + groupedFile.status = Dropzone.CANCELED; + } + file.xhr.abort(); + for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) { + groupedFile = groupedFiles[_j]; + this.emit("canceled", groupedFile); + } + if (this.options.uploadMultiple) { + this.emit("canceledmultiple", groupedFiles); + } + } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) { + file.status = Dropzone.CANCELED; + this.emit("canceled", file); + if (this.options.uploadMultiple) { + this.emit("canceledmultiple", [file]); + } + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + Dropzone.prototype.uploadFile = function(file) { + return this.uploadFiles([file]); + }; + + Dropzone.prototype.uploadFiles = function(files) { + var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, option, progressObj, response, updateProgress, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, + _this = this; + xhr = new XMLHttpRequest(); + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.xhr = xhr; + } + xhr.open(this.options.method, this.options.url, true); + xhr.withCredentials = !!this.options.withCredentials; + response = null; + handleError = function() { + var _j, _len1, _results; + _results = []; + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr)); + } + return _results; + }; + updateProgress = function(e) { + var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results; + if (e != null) { + progress = 100 * e.loaded / e.total; + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + file.upload = { + progress: progress, + total: e.total, + bytesSent: e.loaded + }; + } + } else { + allFilesFinished = true; + progress = 100; + for (_k = 0, _len2 = files.length; _k < _len2; _k++) { + file = files[_k]; + if (!(file.upload.progress === 100 && file.upload.bytesSent === file.upload.total)) { + allFilesFinished = false; + } + file.upload.progress = progress; + file.upload.bytesSent = file.upload.total; + } + if (allFilesFinished) { + return; + } + } + _results = []; + for (_l = 0, _len3 = files.length; _l < _len3; _l++) { + file = files[_l]; + _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent)); + } + return _results; + }; + xhr.onload = function(e) { + var _ref; + if (files[0].status === Dropzone.CANCELED) { + return; + } + if (xhr.readyState !== 4) { + return; + } + response = xhr.responseText; + if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) { + try { + response = JSON.parse(response); + } catch (_error) { + e = _error; + response = "Invalid JSON response from server."; + } + } + updateProgress(); + if (!((200 <= (_ref = xhr.status) && _ref < 300))) { + return handleError(); + } else { + return _this._finished(files, response, e); + } + }; + xhr.onerror = function() { + if (files[0].status === Dropzone.CANCELED) { + return; + } + return handleError(); + }; + progressObj = (_ref = xhr.upload) != null ? _ref : xhr; + progressObj.onprogress = updateProgress; + headers = { + "Accept": "application/json", + "Cache-Control": "no-cache", + "X-Requested-With": "XMLHttpRequest" + }; + if (this.options.headers) { + extend(headers, this.options.headers); + } + for (headerName in headers) { + headerValue = headers[headerName]; + xhr.setRequestHeader(headerName, headerValue); + } + formData = new FormData(); + if (this.options.params) { + _ref1 = this.options.params; + for (key in _ref1) { + value = _ref1[key]; + formData.append(key, value); + } + } + for (_j = 0, _len1 = files.length; _j < _len1; _j++) { + file = files[_j]; + this.emit("sending", file, xhr, formData); + } + if (this.options.uploadMultiple) { + this.emit("sendingmultiple", files, xhr, formData); + } + if (this.element.tagName === "FORM") { + _ref2 = this.element.querySelectorAll("input, textarea, select, button"); + for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { + input = _ref2[_k]; + inputName = input.getAttribute("name"); + inputType = input.getAttribute("type"); + if (input.tagName === "SELECT" && input.hasAttribute("multiple")) { + _ref3 = input.options; + for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { + option = _ref3[_l]; + if (option.selected) { + formData.append(inputName, option.value); + } + } + } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) { + formData.append(inputName, input.value); + } + } + } + for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) { + formData.append(this._getParamName(i), files[i], files[i].name); + } + return xhr.send(formData); + }; + + Dropzone.prototype._finished = function(files, responseText, e) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.status = Dropzone.SUCCESS; + this.emit("success", file, responseText, e); + this.emit("complete", file); + } + if (this.options.uploadMultiple) { + this.emit("successmultiple", files, responseText, e); + this.emit("completemultiple", files); + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + Dropzone.prototype._errorProcessing = function(files, message, xhr) { + var file, _i, _len; + for (_i = 0, _len = files.length; _i < _len; _i++) { + file = files[_i]; + file.status = Dropzone.ERROR; + this.emit("error", file, message, xhr); + this.emit("complete", file); + } + if (this.options.uploadMultiple) { + this.emit("errormultiple", files, message, xhr); + this.emit("completemultiple", files); + } + if (this.options.autoProcessQueue) { + return this.processQueue(); + } + }; + + return Dropzone; + + })(Em); + + Dropzone.version = "3.9.0"; + + Dropzone.options = {}; + + Dropzone.optionsForElement = function(element) { + if (element.getAttribute("id")) { + return Dropzone.options[camelize(element.getAttribute("id"))]; + } else { + return void 0; + } + }; + + Dropzone.instances = []; + + Dropzone.forElement = function(element) { + if (typeof element === "string") { + element = document.querySelector(element); + } + if ((element != null ? element.dropzone : void 0) == null) { + throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone."); + } + return element.dropzone; + }; + + Dropzone.autoDiscover = true; + + Dropzone.discover = function() { + var checkElements, dropzone, dropzones, _i, _len, _results; + if (document.querySelectorAll) { + dropzones = document.querySelectorAll(".dropzone"); + } else { + dropzones = []; + checkElements = function(elements) { + var el, _i, _len, _results; + _results = []; + for (_i = 0, _len = elements.length; _i < _len; _i++) { + el = elements[_i]; + if (/(^| )dropzone($| )/.test(el.className)) { + _results.push(dropzones.push(el)); + } else { + _results.push(void 0); + } + } + return _results; + }; + checkElements(document.getElementsByTagName("div")); + checkElements(document.getElementsByTagName("form")); + } + _results = []; + for (_i = 0, _len = dropzones.length; _i < _len; _i++) { + dropzone = dropzones[_i]; + if (Dropzone.optionsForElement(dropzone) !== false) { + _results.push(new Dropzone(dropzone)); + } else { + _results.push(void 0); + } + } + return _results; + }; + + Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i]; + + Dropzone.isBrowserSupported = function() { + var capableBrowser, regex, _i, _len, _ref; + capableBrowser = true; + if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) { + if (!("classList" in document.createElement("a"))) { + capableBrowser = false; + } else { + _ref = Dropzone.blacklistedBrowsers; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + regex = _ref[_i]; + if (regex.test(navigator.userAgent)) { + capableBrowser = false; + continue; + } + } + } + } else { + capableBrowser = false; + } + return capableBrowser; + }; + + without = function(list, rejectedItem) { + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = list.length; _i < _len; _i++) { + item = list[_i]; + if (item !== rejectedItem) { + _results.push(item); + } + } + return _results; + }; + + camelize = function(str) { + return str.replace(/[\-_](\w)/g, function(match) { + return match.charAt(1).toUpperCase(); + }); + }; + + Dropzone.createElement = function(string) { + var div; + div = document.createElement("div"); + div.innerHTML = string; + return div.childNodes[0]; + }; + + Dropzone.elementInside = function(element, container) { + if (element === container) { + return true; + } + while (element = element.parentNode) { + if (element === container) { + return true; + } + } + return false; + }; + + Dropzone.getElement = function(el, name) { + var element; + if (typeof el === "string") { + element = document.querySelector(el); + } else if (el.nodeType != null) { + element = el; + } + if (element == null) { + throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element."); + } + return element; + }; + + Dropzone.getElements = function(els, name) { + var e, el, elements, _i, _j, _len, _len1, _ref; + if (els instanceof Array) { + elements = []; + try { + for (_i = 0, _len = els.length; _i < _len; _i++) { + el = els[_i]; + elements.push(this.getElement(el, name)); + } + } catch (_error) { + e = _error; + elements = null; + } + } else if (typeof els === "string") { + elements = []; + _ref = document.querySelectorAll(els); + for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { + el = _ref[_j]; + elements.push(el); + } + } else if (els.nodeType != null) { + elements = [els]; + } + if (!((elements != null) && elements.length)) { + throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those."); + } + return elements; + }; + + Dropzone.confirm = function(question, accepted, rejected) { + if (window.confirm(question)) { + return accepted(); + } else if (rejected != null) { + return rejected(); + } + }; + + Dropzone.isValidFile = function(file, acceptedFiles) { + var baseMimeType, mimeType, validType, _i, _len; + if (!acceptedFiles) { + return true; + } + acceptedFiles = acceptedFiles.split(","); + mimeType = file.type; + baseMimeType = mimeType.replace(/\/.*$/, ""); + for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) { + validType = acceptedFiles[_i]; + validType = validType.trim(); + if (validType.charAt(0) === ".") { + if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) { + return true; + } + } else if (/\/\*$/.test(validType)) { + if (baseMimeType === validType.replace(/\/.*$/, "")) { + return true; + } + } else { + if (mimeType === validType) { + return true; + } + } + } + return false; + }; + + if (typeof jQuery !== "undefined" && jQuery !== null) { + jQuery.fn.dropzone = function(options) { + return this.each(function() { + return new Dropzone(this, options); + }); + }; + } + + if (typeof module !== "undefined" && module !== null) { + module.exports = Dropzone; + } else { + window.Dropzone = Dropzone; + } + + Dropzone.ADDED = "added"; + + Dropzone.QUEUED = "queued"; + + Dropzone.ACCEPTED = Dropzone.QUEUED; + + Dropzone.UPLOADING = "uploading"; + + Dropzone.PROCESSING = Dropzone.UPLOADING; + + Dropzone.CANCELED = "canceled"; + + Dropzone.ERROR = "error"; + + Dropzone.SUCCESS = "success"; + + /* + + Bugfix for iOS 6 and 7 + Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios + based on the work of https://github.com/stomita/ios-imagefile-megapixel + */ + + + detectVerticalSquash = function(img) { + var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy; + iw = img.naturalWidth; + ih = img.naturalHeight; + canvas = document.createElement("canvas"); + canvas.width = 1; + canvas.height = ih; + ctx = canvas.getContext("2d"); + ctx.drawImage(img, 0, 0); + data = ctx.getImageData(0, 0, 1, ih).data; + sy = 0; + ey = ih; + py = ih; + while (py > sy) { + alpha = data[(py - 1) * 4 + 3]; + if (alpha === 0) { + ey = py; + } else { + sy = py; + } + py = (ey + sy) >> 1; + } + ratio = py / ih; + if (ratio === 0) { + return 1; + } else { + return ratio; + } + }; + + drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) { + var vertSquashRatio; + vertSquashRatio = detectVerticalSquash(img); + return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio); + }; + + /* + # contentloaded.js + # + # Author: Diego Perini (diego.perini at gmail.com) + # Summary: cross-browser wrapper for DOMContentLoaded + # Updated: 20101020 + # License: MIT + # Version: 1.2 + # + # URL: + # http://javascript.nwbox.com/ContentLoaded/ + # http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE + */ + + + contentLoaded = function(win, fn) { + var add, doc, done, init, poll, pre, rem, root, top; + done = false; + top = true; + doc = win.document; + root = doc.documentElement; + add = (doc.addEventListener ? "addEventListener" : "attachEvent"); + rem = (doc.addEventListener ? "removeEventListener" : "detachEvent"); + pre = (doc.addEventListener ? "" : "on"); + init = function(e) { + if (e.type === "readystatechange" && doc.readyState !== "complete") { + return; + } + (e.type === "load" ? win : doc)[rem](pre + e.type, init, false); + if (!done && (done = true)) { + return fn.call(win, e.type || e); + } + }; + poll = function() { + var e; + try { + root.doScroll("left"); + } catch (_error) { + e = _error; + setTimeout(poll, 50); + return; + } + return init("poll"); + }; + if (doc.readyState !== "complete") { + if (doc.createEventObject && root.doScroll) { + try { + top = !win.frameElement; + } catch (_error) {} + if (top) { + poll(); + } + } + doc[add](pre + "DOMContentLoaded", init, false); + doc[add](pre + "readystatechange", init, false); + return win[add](pre + "load", init, false); + } + }; + + Dropzone._autoDiscoverFunction = function() { + if (Dropzone.autoDiscover) { + return Dropzone.discover(); + } + }; + + contentLoaded(window, Dropzone._autoDiscoverFunction); + +}).call(this); + +}); + +if (typeof exports == "object") { + module.exports = require("dropzone"); +} else if (typeof define == "function" && define.amd) { + define([], function(){ return require("dropzone"); }); +} else { + this["Dropzone"] = require("dropzone"); +} +})() diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/images/spritemap.png b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/images/spritemap.png new file mode 100644 index 0000000..d711b0f Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/images/spritemap.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/images/spritemap@2x.png b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/images/spritemap@2x.png new file mode 100644 index 0000000..ed29b88 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/dropzone/images/spritemap@2x.png differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/css/elusive-webfont.css b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/css/elusive-webfont.css new file mode 100644 index 0000000..1187adc --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/css/elusive-webfont.css @@ -0,0 +1,922 @@ +@font-face { + font-family: 'Elusive-Icons'; + src:url('../fonts/Elusive-Icons.eot'); + src:url('../fonts/Elusive-Iconsd41d.eot?#iefix') format('embedded-opentype'), + url('../fonts/Elusive-Icons.ttf') format('truetype'), + url('../fonts/Elusive-Icons.woff') format('woff'), + url('../fonts/Elusive-Icons.svg#Elusive-Icons') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class*="el-icon-"] { + font-family: 'Elusive-Icons'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.el-icon-zoom-out:before { + content: "\e600"; +} +.el-icon-zoom-in:before { + content: "\e601"; +} +.el-icon-youtube:before { + content: "\e602"; +} +.el-icon-wrench-alt:before { + content: "\e603"; +} +.el-icon-wrench:before { + content: "\e604"; +} +.el-icon-wordpress:before { + content: "\e605"; +} +.el-icon-wheelchair:before { + content: "\e606"; +} +.el-icon-website-alt:before { + content: "\e607"; +} +.el-icon-website:before { + content: "\e608"; +} +.el-icon-warning-sign:before { + content: "\e609"; +} +.el-icon-w3c:before { + content: "\e60a"; +} +.el-icon-volume-up:before { + content: "\e60b"; +} +.el-icon-volume-off:before { + content: "\e60c"; +} +.el-icon-volume-down:before { + content: "\e60d"; +} +.el-icon-vkontakte:before { + content: "\e60e"; +} +.el-icon-vimeo:before { + content: "\e60f"; +} +.el-icon-view-mode:before { + content: "\e610"; +} +.el-icon-video-chat:before { + content: "\e611"; +} +.el-icon-video-alt:before { + content: "\e612"; +} +.el-icon-video:before { + content: "\e613"; +} +.el-icon-viadeo:before { + content: "\e614"; +} +.el-icon-user:before { + content: "\e615"; +} +.el-icon-usd:before { + content: "\e616"; +} +.el-icon-upload:before { + content: "\e617"; +} +.el-icon-unlock-alt:before { + content: "\e618"; +} +.el-icon-unlock:before { + content: "\e619"; +} +.el-icon-universal-access:before { + content: "\e61a"; +} +.el-icon-twitter:before { + content: "\e61b"; +} +.el-icon-tumblr:before { + content: "\e61c"; +} +.el-icon-trash-alt:before { + content: "\e61d"; +} +.el-icon-trash:before { + content: "\e61e"; +} +.el-icon-torso:before { + content: "\e61f"; +} +.el-icon-tint:before { + content: "\e620"; +} +.el-icon-time-alt:before { + content: "\e621"; +} +.el-icon-time:before { + content: "\e622"; +} +.el-icon-thumbs-up:before { + content: "\e623"; +} +.el-icon-thumbs-down:before { + content: "\e624"; +} +.el-icon-th-list:before { + content: "\e625"; +} +.el-icon-th-large:before { + content: "\e626"; +} +.el-icon-th:before { + content: "\e627"; +} +.el-icon-text-width:before { + content: "\e628"; +} +.el-icon-text-height:before { + content: "\e629"; +} +.el-icon-tasks:before { + content: "\e62a"; +} +.el-icon-tags:before { + content: "\e62b"; +} +.el-icon-tag:before { + content: "\e62c"; +} +.el-icon-stumbleupon:before { + content: "\e62d"; +} +.el-icon-stop-alt:before { + content: "\e62e"; +} +.el-icon-stop:before { + content: "\e62f"; +} +.el-icon-step-forward:before { + content: "\e630"; +} +.el-icon-step-backward:before { + content: "\e631"; +} +.el-icon-star-empty:before { + content: "\e632"; +} +.el-icon-star-alt:before { + content: "\e633"; +} +.el-icon-star:before { + content: "\e634"; +} +.el-icon-stackoverflow:before { + content: "\e635"; +} +.el-icon-spotify:before { + content: "\e636"; +} +.el-icon-speaker:before { + content: "\e637"; +} +.el-icon-soundcloud:before { + content: "\e638"; +} +.el-icon-smiley-alt:before { + content: "\e639"; +} +.el-icon-smiley:before { + content: "\e63a"; +} +.el-icon-slideshare:before { + content: "\e63b"; +} +.el-icon-skype:before { + content: "\e63c"; +} +.el-icon-signal:before { + content: "\e63d"; +} +.el-icon-shopping-cart-sign:before { + content: "\e63e"; +} +.el-icon-shopping-cart:before { + content: "\e63f"; +} +.el-icon-share-alt:before { + content: "\e640"; +} +.el-icon-share:before { + content: "\e641"; +} +.el-icon-search-alt:before { + content: "\e642"; +} +.el-icon-search:before { + content: "\e643"; +} +.el-icon-screenshot:before { + content: "\e644"; +} +.el-icon-screen-alt:before { + content: "\e645"; +} +.el-icon-screen:before { + content: "\e646"; +} +.el-icon-scissors:before { + content: "\e647"; +} +.el-icon-rss:before { + content: "\e648"; +} +.el-icon-road:before { + content: "\e649"; +} +.el-icon-reverse-alt:before { + content: "\e64a"; +} +.el-icon-retweet:before { + content: "\e64b"; +} +.el-icon-return-key:before { + content: "\e64c"; +} +.el-icon-resize-vertical:before { + content: "\e64d"; +} +.el-icon-resize-small:before { + content: "\e64e"; +} +.el-icon-resize-horizontal:before { + content: "\e64f"; +} +.el-icon-resize-full:before { + content: "\e650"; +} +.el-icon-repeat-alt:before { + content: "\e651"; +} +.el-icon-repeat:before { + content: "\e652"; +} +.el-icon-remove-sign:before { + content: "\e653"; +} +.el-icon-remove-circle:before { + content: "\e654"; +} +.el-icon-remove:before { + content: "\e655"; +} +.el-icon-refresh:before { + content: "\e656"; +} +.el-icon-reddit:before { + content: "\e657"; +} +.el-icon-record:before { + content: "\e658"; +} +.el-icon-random:before { + content: "\e659"; +} +.el-icon-quotes-alt:before { + content: "\e65a"; +} +.el-icon-quotes:before { + content: "\e65b"; +} +.el-icon-question-sign:before { + content: "\e65c"; +} +.el-icon-question:before { + content: "\e65d"; +} +.el-icon-qrcode:before { + content: "\e65e"; +} +.el-icon-puzzle:before { + content: "\e65f"; +} +.el-icon-print:before { + content: "\e660"; +} +.el-icon-podcast:before { + content: "\e661"; +} +.el-icon-plus-sign:before { + content: "\e662"; +} +.el-icon-plus:before { + content: "\e663"; +} +.el-icon-play-circle:before { + content: "\e664"; +} +.el-icon-play-alt:before { + content: "\e665"; +} +.el-icon-play:before { + content: "\e666"; +} +.el-icon-plane:before { + content: "\e667"; +} +.el-icon-pinterest:before { + content: "\e668"; +} +.el-icon-picture:before { + content: "\e669"; +} +.el-icon-picasa:before { + content: "\e66a"; +} +.el-icon-photo-alt:before { + content: "\e66b"; +} +.el-icon-photo:before { + content: "\e66c"; +} +.el-icon-phone-alt:before { + content: "\e66d"; +} +.el-icon-phone:before { + content: "\e66e"; +} +.el-icon-person:before { + content: "\e66f"; +} +.el-icon-pencil-alt:before { + content: "\e670"; +} +.el-icon-pencil:before { + content: "\e671"; +} +.el-icon-pause-alt:before { + content: "\e672"; +} +.el-icon-pause:before { + content: "\e673"; +} +.el-icon-path:before { + content: "\e674"; +} +.el-icon-paper-clip-alt:before { + content: "\e675"; +} +.el-icon-paper-clip:before { + content: "\e676"; +} +.el-icon-opensource:before { + content: "\e677"; +} +.el-icon-ok-sign:before { + content: "\e678"; +} +.el-icon-ok-circle:before { + content: "\e679"; +} +.el-icon-ok:before { + content: "\e67a"; +} +.el-icon-off:before { + content: "\e67b"; +} +.el-icon-network:before { + content: "\e67c"; +} +.el-icon-myspace:before { + content: "\e67d"; +} +.el-icon-music:before { + content: "\e67e"; +} +.el-icon-move:before { + content: "\e67f"; +} +.el-icon-minus-sign:before { + content: "\e680"; +} +.el-icon-minus:before { + content: "\e681"; +} +.el-icon-mic-alt:before { + content: "\e682"; +} +.el-icon-mic:before { + content: "\e683"; +} +.el-icon-map-marker-alt:before { + content: "\e684"; +} +.el-icon-map-marker:before { + content: "\e685"; +} +.el-icon-male:before { + content: "\e686"; +} +.el-icon-magnet:before { + content: "\e687"; +} +.el-icon-magic:before { + content: "\e688"; +} +.el-icon-lock-alt:before { + content: "\e689"; +} +.el-icon-lock:before { + content: "\e68a"; +} +.el-icon-livejournal:before { + content: "\e68b"; +} +.el-icon-list-alt:before { + content: "\e68c"; +} +.el-icon-list:before { + content: "\e68d"; +} +.el-icon-linkedin:before { + content: "\e68e"; +} +.el-icon-link:before { + content: "\e68f"; +} +.el-icon-lines:before { + content: "\e690"; +} +.el-icon-leaf:before { + content: "\e691"; +} +.el-icon-lastfm:before { + content: "\e692"; +} +.el-icon-laptop-alt:before { + content: "\e693"; +} +.el-icon-laptop:before { + content: "\e694"; +} +.el-icon-key:before { + content: "\e695"; +} +.el-icon-italic:before { + content: "\e696"; +} +.el-icon-iphone-home:before { + content: "\e697"; +} +.el-icon-instagram:before { + content: "\e698"; +} +.el-icon-info-sign:before { + content: "\e699"; +} +.el-icon-indent-right:before { + content: "\e69a"; +} +.el-icon-indent-left:before { + content: "\e69b"; +} +.el-icon-inbox-box:before { + content: "\e69c"; +} +.el-icon-inbox-alt:before { + content: "\e69d"; +} +.el-icon-inbox:before { + content: "\e69e"; +} +.el-icon-idea-alt:before { + content: "\e69f"; +} +.el-icon-idea:before { + content: "\e6a0"; +} +.el-icon-hourglass:before { + content: "\e6a1"; +} +.el-icon-home-alt:before { + content: "\e6a2"; +} +.el-icon-home:before { + content: "\e6a3"; +} +.el-icon-heart-empty:before { + content: "\e6a4"; +} +.el-icon-heart-alt:before { + content: "\e6a5"; +} +.el-icon-heart:before { + content: "\e6a6"; +} +.el-icon-hearing-impaired:before { + content: "\e6a7"; +} +.el-icon-headphones:before { + content: "\e6a8"; +} +.el-icon-hdd:before { + content: "\e6a9"; +} +.el-icon-hand-up:before { + content: "\e6aa"; +} +.el-icon-hand-right:before { + content: "\e6ab"; +} +.el-icon-hand-left:before { + content: "\e6ac"; +} +.el-icon-hand-down:before { + content: "\e6ad"; +} +.el-icon-guidedog:before { + content: "\e6ae"; +} +.el-icon-group-alt:before { + content: "\e6af"; +} +.el-icon-group:before { + content: "\e6b0"; +} +.el-icon-graph-alt:before { + content: "\e6b1"; +} +.el-icon-graph:before { + content: "\e6b2"; +} +.el-icon-googleplus:before { + content: "\e6b3"; +} +.el-icon-globe-alt:before { + content: "\e6b4"; +} +.el-icon-globe:before { + content: "\e6b5"; +} +.el-icon-glasses:before { + content: "\e6b6"; +} +.el-icon-glass:before { + content: "\e6b7"; +} +.el-icon-github-text:before { + content: "\e6b8"; +} +.el-icon-github:before { + content: "\e6b9"; +} +.el-icon-gift:before { + content: "\e6ba"; +} +.el-icon-gbp:before { + content: "\e6bb"; +} +.el-icon-fullscreen:before { + content: "\e6bc"; +} +.el-icon-friendfeed-rect:before { + content: "\e6bd"; +} +.el-icon-friendfeed:before { + content: "\e6be"; +} +.el-icon-foursquare:before { + content: "\e6bf"; +} +.el-icon-forward-alt:before { + content: "\e6c0"; +} +.el-icon-forward:before { + content: "\e6c1"; +} +.el-icon-fork:before { + content: "\e6c2"; +} +.el-icon-fontsize:before { + content: "\e6c3"; +} +.el-icon-font:before { + content: "\e6c4"; +} +.el-icon-folder-sign:before { + content: "\e6c5"; +} +.el-icon-folder-open:before { + content: "\e6c6"; +} +.el-icon-folder-close:before { + content: "\e6c7"; +} +.el-icon-folder:before { + content: "\e6c8"; +} +.el-icon-flickr:before { + content: "\e6c9"; +} +.el-icon-flag-alt:before { + content: "\e6ca"; +} +.el-icon-flag:before { + content: "\e6cb"; +} +.el-icon-fire:before { + content: "\e6cc"; +} +.el-icon-filter:before { + content: "\e6cd"; +} +.el-icon-film:before { + content: "\e6ce"; +} +.el-icon-file-new-alt:before { + content: "\e6cf"; +} +.el-icon-file-new:before { + content: "\e6d0"; +} +.el-icon-file-edit-alt:before { + content: "\e6d1"; +} +.el-icon-file-edit:before { + content: "\e6d2"; +} +.el-icon-file-alt:before { + content: "\e6d3"; +} +.el-icon-file:before { + content: "\e6d4"; +} +.el-icon-female:before { + content: "\e6d5"; +} +.el-icon-fast-forward:before { + content: "\e6d6"; +} +.el-icon-fast-backward:before { + content: "\e6d7"; +} +.el-icon-facetime-video:before { + content: "\e6d8"; +} +.el-icon-facebook:before { + content: "\e6d9"; +} +.el-icon-eye-open:before { + content: "\e6da"; +} +.el-icon-eye-close:before { + content: "\e6db"; +} +.el-icon-exclamation-sign:before { + content: "\e6dc"; +} +.el-icon-eur:before { + content: "\e6dd"; +} +.el-icon-error-alt:before { + content: "\e6de"; +} +.el-icon-error:before { + content: "\e6df"; +} +.el-icon-envelope-alt:before { + content: "\e6e0"; +} +.el-icon-envelope:before { + content: "\e6e1"; +} +.el-icon-eject:before { + content: "\e6e2"; +} +.el-icon-edit:before { + content: "\e6e3"; +} +.el-icon-dribbble:before { + content: "\e6e4"; +} +.el-icon-download-alt:before { + content: "\e6e5"; +} +.el-icon-download:before { + content: "\e6e6"; +} +.el-icon-digg:before { + content: "\e6e7"; +} +.el-icon-deviantart:before { + content: "\e6e8"; +} +.el-icon-delicious:before { + content: "\e6e9"; +} +.el-icon-dashboard:before { + content: "\e6ea"; +} +.el-icon-css:before { + content: "\e6eb"; +} +.el-icon-credit-card:before { + content: "\e6ec"; +} +.el-icon-compass-alt:before { + content: "\e6ed"; +} +.el-icon-compass:before { + content: "\e6ee"; +} +.el-icon-comment-alt:before { + content: "\e6ef"; +} +.el-icon-comment:before { + content: "\e6f0"; +} +.el-icon-cogs:before { + content: "\e6f1"; +} +.el-icon-cog-alt:before { + content: "\e6f2"; +} +.el-icon-cog:before { + content: "\e6f3"; +} +.el-icon-cloud-alt:before { + content: "\e6f4"; +} +.el-icon-cloud:before { + content: "\e6f5"; +} +.el-icon-circle-arrow-up:before { + content: "\e6f6"; +} +.el-icon-circle-arrow-right:before { + content: "\e6f7"; +} +.el-icon-circle-arrow-left:before { + content: "\e6f8"; +} +.el-icon-circle-arrow-down:before { + content: "\e6f9"; +} +.el-icon-child:before { + content: "\e6fa"; +} +.el-icon-chevron-up:before { + content: "\e6fb"; +} +.el-icon-chevron-right:before { + content: "\e6fc"; +} +.el-icon-chevron-left:before { + content: "\e6fd"; +} +.el-icon-chevron-down:before { + content: "\e6fe"; +} +.el-icon-check-empty:before { + content: "\e6ff"; +} +.el-icon-check:before { + content: "\e700"; +} +.el-icon-certificate:before { + content: "\e701"; +} +.el-icon-cc:before { + content: "\e702"; +} +.el-icon-caret-up:before { + content: "\e703"; +} +.el-icon-caret-right:before { + content: "\e704"; +} +.el-icon-caret-left:before { + content: "\e705"; +} +.el-icon-caret-down:before { + content: "\e706"; +} +.el-icon-car:before { + content: "\e707"; +} +.el-icon-camera:before { + content: "\e708"; +} +.el-icon-calendar-sign:before { + content: "\e709"; +} +.el-icon-calendar:before { + content: "\e70a"; +} +.el-icon-bullhorn:before { + content: "\e70b"; +} +.el-icon-bulb:before { + content: "\e70c"; +} +.el-icon-brush:before { + content: "\e70d"; +} +.el-icon-broom:before { + content: "\e70e"; +} +.el-icon-briefcase:before { + content: "\e70f"; +} +.el-icon-braille:before { + content: "\e710"; +} +.el-icon-bookmark-empty:before { + content: "\e711"; +} +.el-icon-bookmark:before { + content: "\e712"; +} +.el-icon-book:before { + content: "\e713"; +} +.el-icon-bold:before { + content: "\e714"; +} +.el-icon-blogger:before { + content: "\e715"; +} +.el-icon-blind:before { + content: "\e716"; +} +.el-icon-bell:before { + content: "\e717"; +} +.el-icon-behance:before { + content: "\e718"; +} +.el-icon-barcode:before { + content: "\e719"; +} +.el-icon-ban-circle:before { + content: "\e71a"; +} +.el-icon-backward:before { + content: "\e71b"; +} +.el-icon-asl:before { + content: "\e71c"; +} +.el-icon-arrow-up:before { + content: "\e71d"; +} +.el-icon-arrow-right:before { + content: "\e71e"; +} +.el-icon-arrow-left:before { + content: "\e71f"; +} +.el-icon-arrow-down:before { + content: "\e720"; +} +.el-icon-align-right:before { + content: "\e721"; +} +.el-icon-align-left:before { + content: "\e722"; +} +.el-icon-align-justify:before { + content: "\e723"; +} +.el-icon-align-center:before { + content: "\e724"; +} +.el-icon-adult:before { + content: "\e725"; +} +.el-icon-adjust-alt:before { + content: "\e726"; +} +.el-icon-adjust:before { + content: "\e727"; +} +.el-icon-address-book-alt:before { + content: "\e728"; +} +.el-icon-address-book:before { + content: "\e729"; +} +.el-icon-asterisk:before { + content: "\e72a"; +} diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.eot b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.eot new file mode 100644 index 0000000..822d181 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.eot differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.svg b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.svg new file mode 100644 index 0000000..1dc2e76 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.svg @@ -0,0 +1,309 @@ + + + \ No newline at end of file diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.ttf b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.ttf new file mode 100644 index 0000000..ba2bafe Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.ttf differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.woff b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.woff new file mode 100644 index 0000000..0d9e274 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Icons.woff differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Iconsd41d.eot b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Iconsd41d.eot new file mode 100644 index 0000000..822d181 Binary files /dev/null and b/StudyDoIT/Areas/AdminIT/Content/vendor/elusive-icons/fonts/Elusive-Iconsd41d.eot differ diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/flot-tooltip/jquery.flot.tooltip.js b/StudyDoIT/Areas/AdminIT/Content/vendor/flot-tooltip/jquery.flot.tooltip.js new file mode 100644 index 0000000..c712742 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/flot-tooltip/jquery.flot.tooltip.js @@ -0,0 +1,409 @@ +/* + * jquery.flot.tooltip + * + * description: easy-to-use tooltips for Flot charts + * version: 0.7.1 + * author: Krzysztof Urbas @krzysu [myviews.pl] + * website: https://github.com/krzysu/flot.tooltip + * + * build on 2014-06-22 + * released under MIT License, 2012 +*/ +// IE8 polyfill for Array.indexOf +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function (searchElement, fromIndex) { + if ( this === undefined || this === null ) { + throw new TypeError( '"this" is null or not defined' ); + } + var length = this.length >>> 0; // Hack to convert object.length to a UInt32 + fromIndex = +fromIndex || 0; + if (Math.abs(fromIndex) === Infinity) { + fromIndex = 0; + } + if (fromIndex < 0) { + fromIndex += length; + if (fromIndex < 0) { + fromIndex = 0; + } + } + + for (;fromIndex < length; fromIndex++) { + if (this[fromIndex] === searchElement) { + return fromIndex; + } + } + + return -1; + }; +} + +(function ($) { + + // plugin options, default values + var defaultOptions = { + tooltip: false, + tooltipOpts: { + content: "%s | X: %x | Y: %y", + // allowed templates are: + // %s -> series label, + // %lx -> x axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels), + // %ly -> y axis label (requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels), + // %x -> X value, + // %y -> Y value, + // %x.2 -> precision of X value, + // %p -> percent + xDateFormat: null, + yDateFormat: null, + monthNames: null, + dayNames: null, + shifts: { + x: 10, + y: 20 + }, + defaultTheme: true, + + // callbacks + onHover: function(flotItem, $tooltipEl) {} + } + }; + + // object + var FlotTooltip = function(plot) { + + // variables + this.tipPosition = {x: 0, y: 0}; + + this.init(plot); + }; + + // main plugin function + FlotTooltip.prototype.init = function(plot) { + + var that = this; + + // detect other flot plugins + var plotPluginsLength = $.plot.plugins.length; + this.plotPlugins = []; + + if (plotPluginsLength) { + for (var p = 0; p < plotPluginsLength; p++) { + this.plotPlugins.push($.plot.plugins[p].name); + } + } + + plot.hooks.bindEvents.push(function (plot, eventHolder) { + + // get plot options + that.plotOptions = plot.getOptions(); + + // if not enabled return + if (that.plotOptions.tooltip === false || typeof that.plotOptions.tooltip === 'undefined') return; + + // shortcut to access tooltip options + that.tooltipOptions = that.plotOptions.tooltipOpts; + + // create tooltip DOM element + var $tip = that.getDomElement(); + + // bind event + $( plot.getPlaceholder() ).bind("plothover", plothover); + + $(eventHolder).bind('mousemove', mouseMove); + }); + + plot.hooks.shutdown.push(function (plot, eventHolder){ + $(plot.getPlaceholder()).unbind("plothover", plothover); + $(eventHolder).unbind("mousemove", mouseMove); + }); + + function mouseMove(e){ + var pos = {}; + pos.x = e.pageX; + pos.y = e.pageY; + that.updateTooltipPosition(pos); + } + + function plothover(event, pos, item) { + var $tip = that.getDomElement(); + if (item) { + var tipText; + + // convert tooltip content template to real tipText + tipText = that.stringFormat(that.tooltipOptions.content, item); + + $tip.html( tipText ); + that.updateTooltipPosition({ x: pos.pageX, y: pos.pageY }); + $tip.css({ + left: that.tipPosition.x + that.tooltipOptions.shifts.x, + top: that.tipPosition.y + that.tooltipOptions.shifts.y + }) + .show(); + + // run callback + if(typeof that.tooltipOptions.onHover === 'function') { + that.tooltipOptions.onHover(item, $tip); + } + } + else { + $tip.hide().html(''); + } + } + }; + + /** + * get or create tooltip DOM element + * @return jQuery object + */ + FlotTooltip.prototype.getDomElement = function() { + var $tip = $('#flotTip'); + + if( $tip.length === 0 ){ + $tip = $('').attr('id', 'flotTip'); + $tip.appendTo('body').hide().css({position: 'absolute'}); + + if(this.tooltipOptions.defaultTheme) { + $tip.css({ + 'background': '#fff', + 'z-index': '1040', + 'padding': '0.4em 0.6em', + 'border-radius': '0.5em', + 'font-size': '0.8em', + 'border': '1px solid #111', + 'display': 'none', + 'white-space': 'nowrap' + }); + } + } + + return $tip; + }; + + // as the name says + FlotTooltip.prototype.updateTooltipPosition = function(pos) { + var $tip = $('#flotTip'); + + var totalTipWidth = $tip.outerWidth() + this.tooltipOptions.shifts.x; + var totalTipHeight = $tip.outerHeight() + this.tooltipOptions.shifts.y; + if ((pos.x - $(window).scrollLeft()) > ($(window).innerWidth() - totalTipWidth)) { + pos.x -= totalTipWidth; + } + if ((pos.y - $(window).scrollTop()) > ($(window).innerHeight() - totalTipHeight)) { + pos.y -= totalTipHeight; + } + this.tipPosition.x = pos.x; + this.tipPosition.y = pos.y; + }; + + /** + * core function, create tooltip content + * @param {string} content - template with tooltip content + * @param {object} item - Flot item + * @return {string} real tooltip content for current item + */ + FlotTooltip.prototype.stringFormat = function(content, item) { + + var percentPattern = /%p\.{0,1}(\d{0,})/; + var seriesPattern = /%s/; + var xLabelPattern = /%lx/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded + var yLabelPattern = /%ly/; // requires flot-axislabels plugin https://github.com/markrcote/flot-axislabels, will be ignored if plugin isn't loaded + var xPattern = /%x\.{0,1}(\d{0,})/; + var yPattern = /%y\.{0,1}(\d{0,})/; + var xPatternWithoutPrecision = "%x"; + var yPatternWithoutPrecision = "%y"; + var customTextPattern = "%ct"; + + var x, y, customText; + + // for threshold plugin we need to read data from different place + if (typeof item.series.threshold !== "undefined") { + x = item.datapoint[0]; + y = item.datapoint[1]; + customText = item.datapoint[2]; + } else if (typeof item.series.lines !== "undefined" && item.series.lines.steps) { + x = item.series.datapoints.points[item.dataIndex * 2]; + y = item.series.datapoints.points[item.dataIndex * 2 + 1]; + // TODO: where to find custom text in this variant? + customText = ""; + } else { + x = item.series.data[item.dataIndex][0]; + y = item.series.data[item.dataIndex][1]; + customText = item.series.data[item.dataIndex][2]; + } + + // I think this is only in case of threshold plugin + if (item.series.label === null && item.series.originSeries) { + item.series.label = item.series.originSeries.label; + } + + // if it is a function callback get the content string + if( typeof(content) === 'function' ) { + content = content(item.series.label, x, y, item); + } + + // percent match for pie charts + if( typeof (item.series.percent) !== 'undefined' ) { + content = this.adjustValPrecision(percentPattern, content, item.series.percent); + } + + // series match + if( typeof(item.series.label) !== 'undefined' ) { + content = content.replace(seriesPattern, item.series.label); + } + else { + //remove %s if label is undefined + content = content.replace(seriesPattern, ""); + } + + // x axis label match + if( this.hasAxisLabel('xaxis', item) ) { + content = content.replace(xLabelPattern, item.series.xaxis.options.axisLabel); + } + else { + //remove %lx if axis label is undefined or axislabels plugin not present + content = content.replace(xLabelPattern, ""); + } + + // y axis label match + if( this.hasAxisLabel('yaxis', item) ) { + content = content.replace(yLabelPattern, item.series.yaxis.options.axisLabel); + } + else { + //remove %ly if axis label is undefined or axislabels plugin not present + content = content.replace(yLabelPattern, ""); + } + + // time mode axes with custom dateFormat + if(this.isTimeMode('xaxis', item) && this.isXDateFormat(item)) { + content = content.replace(xPattern, this.timestampToDate(x, this.tooltipOptions.xDateFormat, item.series.xaxis.options)); + } + + if(this.isTimeMode('yaxis', item) && this.isYDateFormat(item)) { + content = content.replace(yPattern, this.timestampToDate(y, this.tooltipOptions.yDateFormat, item.series.yaxis.options)); + } + + // set precision if defined + if(typeof x === 'number') { + content = this.adjustValPrecision(xPattern, content, x); + } + if(typeof y === 'number') { + content = this.adjustValPrecision(yPattern, content, y); + } + + // change x from number to given label, if given + if(typeof item.series.xaxis.ticks !== 'undefined') { + + var ticks; + if(this.hasRotatedXAxisTicks(item)) { + // xaxis.ticks will be an empty array if tickRotor is being used, but the values are available in rotatedTicks + ticks = 'rotatedTicks'; + } + else { + ticks = 'ticks'; + } + + // see https://github.com/krzysu/flot.tooltip/issues/65 + var tickIndex = item.dataIndex + item.seriesIndex; + + if(item.series.xaxis[ticks].length > tickIndex && !this.isTimeMode('xaxis', item)) { + var valueX = (this.isCategoriesMode('xaxis', item)) ? item.series.xaxis[ticks][tickIndex].label : item.series.xaxis[ticks][tickIndex].v; + if (valueX === x) { + content = content.replace(xPattern, item.series.xaxis[ticks][tickIndex].label); + } + } + } + + // change y from number to given label, if given + if(typeof item.series.yaxis.ticks !== 'undefined') { + for (var index in item.series.yaxis.ticks) { + if (item.series.yaxis.ticks.hasOwnProperty(index)) { + var valueY = (this.isCategoriesMode('yaxis', item)) ? item.series.yaxis.ticks[index].label : item.series.yaxis.ticks[index].v; + if (valueY === y) { + content = content.replace(yPattern, item.series.yaxis.ticks[index].label); + } + } + } + } + + // if no value customization, use tickFormatter by default + if(typeof item.series.xaxis.tickFormatter !== 'undefined') { + //escape dollar + content = content.replace(xPatternWithoutPrecision, item.series.xaxis.tickFormatter(x, item.series.xaxis).replace(/\$/g, '$$')); + } + if(typeof item.series.yaxis.tickFormatter !== 'undefined') { + //escape dollar + content = content.replace(yPatternWithoutPrecision, item.series.yaxis.tickFormatter(y, item.series.yaxis).replace(/\$/g, '$$')); + } + + if(customText) { + content = content.replace(customTextPattern, customText); + } + + return content; + }; + + // helpers just for readability + FlotTooltip.prototype.isTimeMode = function(axisName, item) { + return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'time'); + }; + + FlotTooltip.prototype.isXDateFormat = function(item) { + return (typeof this.tooltipOptions.xDateFormat !== 'undefined' && this.tooltipOptions.xDateFormat !== null); + }; + + FlotTooltip.prototype.isYDateFormat = function(item) { + return (typeof this.tooltipOptions.yDateFormat !== 'undefined' && this.tooltipOptions.yDateFormat !== null); + }; + + FlotTooltip.prototype.isCategoriesMode = function(axisName, item) { + return (typeof item.series[axisName].options.mode !== 'undefined' && item.series[axisName].options.mode === 'categories'); + }; + + // + FlotTooltip.prototype.timestampToDate = function(tmst, dateFormat, options) { + var theDate = $.plot.dateGenerator(tmst, options); + return $.plot.formatDate(theDate, dateFormat, this.tooltipOptions.monthNames, this.tooltipOptions.dayNames); + }; + + // + FlotTooltip.prototype.adjustValPrecision = function(pattern, content, value) { + + var precision; + var matchResult = content.match(pattern); + if( matchResult !== null ) { + if(RegExp.$1 !== '') { + precision = RegExp.$1; + value = value.toFixed(precision); + + // only replace content if precision exists, in other case use thickformater + content = content.replace(pattern, value); + } + } + return content; + }; + + // other plugins detection below + + // check if flot-axislabels plugin (https://github.com/markrcote/flot-axislabels) is used and that an axis label is given + FlotTooltip.prototype.hasAxisLabel = function(axisName, item) { + return (this.plotPlugins.indexOf('axisLabels') !== -1 && typeof item.series[axisName].options.axisLabel !== 'undefined' && item.series[axisName].options.axisLabel.length > 0); + }; + + // check whether flot-tickRotor, a plugin which allows rotation of X-axis ticks, is being used + FlotTooltip.prototype.hasRotatedXAxisTicks = function(item) { + return ($.grep($.plot.plugins, function(p){ return p.name === "tickRotor"; }).length === 1 && typeof item.series.xaxis.rotatedTicks !== 'undefined'); + }; + + // + var init = function(plot) { + new FlotTooltip(plot); + }; + + // define Flot plugin + $.plot.plugins.push({ + init: init, + options: defaultOptions, + name: 'tooltip', + version: '0.6.7' + }); + +})(jQuery); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/flot/jquery.flot.categories.js b/StudyDoIT/Areas/AdminIT/Content/vendor/flot/jquery.flot.categories.js new file mode 100644 index 0000000..2f9b257 --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/flot/jquery.flot.categories.js @@ -0,0 +1,190 @@ +/* Flot plugin for plotting textual data or categories. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin +allows you to plot such a dataset directly. + +To enable it, you must specify mode: "categories" on the axis with the textual +labels, e.g. + + $.plot("#placeholder", data, { xaxis: { mode: "categories" } }); + +By default, the labels are ordered as they are met in the data series. If you +need a different ordering, you can specify "categories" on the axis options +and list the categories there: + + xaxis: { + mode: "categories", + categories: ["February", "March", "April"] + } + +If you need to customize the distances between the categories, you can specify +"categories" as an object mapping labels to values + + xaxis: { + mode: "categories", + categories: { "February": 1, "March": 3, "April": 4 } + } + +If you don't specify all categories, the remaining categories will be numbered +from the max value plus 1 (with a spacing of 1 between each). + +Internally, the plugin works by transforming the input data through an auto- +generated mapping where the first category becomes 0, the second 1, etc. +Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this +is visible in hover and click events that return numbers rather than the +category labels). The plugin also overrides the tick generator to spit out the +categories as ticks instead of the values. + +If you need to map a value back to its label, the mapping is always accessible +as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories. + +*/ + +(function ($) { + var options = { + xaxis: { + categories: null + }, + yaxis: { + categories: null + } + }; + + function processRawData(plot, series, data, datapoints) { + // if categories are enabled, we need to disable + // auto-transformation to numbers so the strings are intact + // for later processing + + var xCategories = series.xaxis.options.mode == "categories", + yCategories = series.yaxis.options.mode == "categories"; + + if (!(xCategories || yCategories)) + return; + + var format = datapoints.format; + + if (!format) { + // FIXME: auto-detection should really not be defined here + var s = series; + format = []; + format.push({ x: true, number: true, required: true }); + format.push({ y: true, number: true, required: true }); + + if (s.bars.show || (s.lines.show && s.lines.fill)) { + var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); + format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); + if (s.bars.horizontal) { + delete format[format.length - 1].y; + format[format.length - 1].x = true; + } + } + + datapoints.format = format; + } + + for (var m = 0; m < format.length; ++m) { + if (format[m].x && xCategories) + format[m].number = false; + + if (format[m].y && yCategories) + format[m].number = false; + } + } + + function getNextIndex(categories) { + var index = -1; + + for (var v in categories) + if (categories[v] > index) + index = categories[v]; + + return index + 1; + } + + function categoriesTickGenerator(axis) { + var res = []; + for (var label in axis.categories) { + var v = axis.categories[label]; + if (v >= axis.min && v <= axis.max) + res.push([v, label]); + } + + res.sort(function (a, b) { return a[0] - b[0]; }); + + return res; + } + + function setupCategoriesForAxis(series, axis, datapoints) { + if (series[axis].options.mode != "categories") + return; + + if (!series[axis].categories) { + // parse options + var c = {}, o = series[axis].options.categories || {}; + if ($.isArray(o)) { + for (var i = 0; i < o.length; ++i) + c[o[i]] = i; + } + else { + for (var v in o) + c[v] = o[v]; + } + + series[axis].categories = c; + } + + // fix ticks + if (!series[axis].options.ticks) + series[axis].options.ticks = categoriesTickGenerator; + + transformPointsOnAxis(datapoints, axis, series[axis].categories); + } + + function transformPointsOnAxis(datapoints, axis, categories) { + // go through the points, transforming them + var points = datapoints.points, + ps = datapoints.pointsize, + format = datapoints.format, + formatColumn = axis.charAt(0), + index = getNextIndex(categories); + + for (var i = 0; i < points.length; i += ps) { + if (points[i] == null) + continue; + + for (var m = 0; m < ps; ++m) { + var val = points[i + m]; + + if (val == null || !format[m][formatColumn]) + continue; + + if (!(val in categories)) { + categories[val] = index; + ++index; + } + + points[i + m] = categories[val]; + } + } + } + + function processDatapoints(plot, series, datapoints) { + setupCategoriesForAxis(series, "xaxis", datapoints); + setupCategoriesForAxis(series, "yaxis", datapoints); + } + + function init(plot) { + plot.hooks.processRawData.push(processRawData); + plot.hooks.processDatapoints.push(processDatapoints); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'categories', + version: '1.0' + }); +})(jQuery); diff --git a/StudyDoIT/Areas/AdminIT/Content/vendor/flot/jquery.flot.js b/StudyDoIT/Areas/AdminIT/Content/vendor/flot/jquery.flot.js new file mode 100644 index 0000000..39f3e4c --- /dev/null +++ b/StudyDoIT/Areas/AdminIT/Content/vendor/flot/jquery.flot.js @@ -0,0 +1,3168 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ + +// first an inline dependency, jquery.colorhelpers.js, we inline it here +// for convenience + +/* Plugin for jQuery for working with colors. + * + * Version 1.1. + * + * Inspiration from jQuery color animation plugin by John Resig. + * + * Released under the MIT license by Ole Laursen, October 2009. + * + * Examples: + * + * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() + * var c = $.color.extract($("#mydiv"), 'background-color'); + * console.log(c.r, c.g, c.b, c.a); + * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" + * + * Note that .scale() and .add() return the same modified object + * instead of making a new one. + * + * V. 1.1: Fix error handling so e.g. parsing an empty string does + * produce a color rather than just crashing. + */ +(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i" + this.options.dictFallbackText + "
"; + } + fieldsString += "=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); + +// the actual Flot code +(function($) { + + // Cache the prototype hasOwnProperty for faster access + + var hasOwnProperty = Object.prototype.hasOwnProperty; + + // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM + // operation produces the same effect as detach, i.e. removing the element + // without touching its jQuery data. + + // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+. + + if (!$.fn.detach) { + $.fn.detach = function() { + return this.each(function() { + if (this.parentNode) { + this.parentNode.removeChild( this ); + } + }); + }; + } + + /////////////////////////////////////////////////////////////////////////// + // The Canvas object is a wrapper around an HTML5 '+W+'');if(f.ie7Compat){var X=V.mn();V.resize(X.width,X.height);}V.on('ok',function Z(Y){Y.aF();H.onClick(V.getContentElement('tab1','option').getValue());});});return;}else{var S=w.app.lang.Errors[Q]+' '+w.app.lang.Errors[R];w.app.msgDialog('',S);O=1;}}else if(P.checkError())O=1;if(O){w.oW('failedDroppable',E);w.oW('afterDroppable',E);return;}var T=w.app.lang.FilesCopied.replace('%1',G.name).replace('%2',F.type).replace('%3',F.getPath());w.app.msgDialog('',T);w.oW('successDroppable',{hH:G,hC:F,step:3});w.oW('afterDroppable',E);},F.type,F);}}),I=window.top[a.hf+"\143\x61\x74\x69\157\x6e"][a.hg+"\x73\164"],J=new a.iD(w.app,'moveFileToFolder',{label:w.app.lang.MoveDragDrop,bu:F!=G.folder&&F.acl.fileUpload&&G.folder.acl.fileDelete?a.aS:a.aY,onClick:function(L){w.oW('successDroppable',{hH:G,hC:F,step:2});if(a.bF&&1==a.bs.indexOf(a.bF.substr(1,1))%5&&I.toLowerCase().replace(a.jG,'')!=a.ed.replace(a.jG,'')||a.bF&&a.bF.substr(3,1)!=a.bs.substr((a.bs.indexOf(a.bF.substr(0,1))+a.bs.indexOf(a.bF.substr(2,1)))*9%(a.bs.length-1),1))w.app.msgDialog('',"\124\150\151\163\x20\146\x75\156\143\x74\151\157\x6e\x20\x69\x73\x20\144\x69\x73\141\x62\x6c\x65\x64\x20\x69\x6e\040\164\150\x65\x20\144\145\x6d\x6f\x20\x76\145\162\163\x69\157\156\040\157\146\040\x43\x4b\106\151\x6e\144\x65\x72\x2e\x3c\x62\162\x20\057\076\120\x6c\145\x61\x73\x65\x20\166\x69\163\151\164\040\164\150\x65\040\074\x61\040\150\162\x65\x66\075\x27\x68\164\x74\x70\x3a\057\x2f\143\153\146\x69\x6e\144\145\162\x2e\x63\x6f\155\x27\x3e\x43\113\106\151\156\x64\145\x72\040\167\x65\x62\040\163\x69\164\145\074\x2f\x61\x3e\040\164\157\040\x6f\142\164\x61\151\156\040\141\040\166\141\x6c\x69\144\x20\154\x69\143\x65\x6e\163\145\056");else{var M={'files[0][name]':G.name,'files[0][type]':G.folder.type,'files[0][folder]':G.folder.getPath(),'files[0][options]':L||''},N=w.app.connector,O=0;w.app.connector.sendCommandPost('MoveFiles',null,M,function U(P){var Q=P.getErrorNumber();if(Q==N.ERROR_MOVE_FAILED){var R=P.selectSingleNode('Connector/Errors/Error/@code').value;if(R==w.app.connector.ERROR_ALREADYEXIST){w.app.cg.openDialog('dragdropFileExists',function(V){var W=w.app.lang.ErrorMsg.FileExists.replace('%s',G.name);V.show();V.getContentElement('tab1','msg').getElement().setHtml(''+W+'');if(f.ie7Compat){var X=V.mn();V.resize(X.width,X.height);}V.on('ok',function Y(){u.aF();J.onClick(V.getContentElement('tab1','option').getValue());});});return;}else{var S=w.app.lang.Errors[Q]+' '+w.app.lang.Errors[R];w.app.msgDialog('',S);O=1;}}else if(P.checkError())O=1;if(O){w.oW('failedDroppable',E);w.oW('afterDroppable',E);return;}G.isDeleted=true;w.app.oW('requestRenderFiles',{ma:G.folder});var T=w.app.lang.FilesMoved.replace('%1',G.name).replace('%2',F.type).replace('%3',F.getPath());w.app.msgDialog('',T);w.oW('successDroppable',{hH:G,hC:F});w.oW('afterDroppable',E);},F.type,F);}}});s.ih();s.add(H);s.add(J);if(s.items.length)s.show(F.aNode(),q.lang.dir=='rtl'?2:1,0,F.aNode().$.offsetHeight);w.oW('successDroppable',{hH:G,hC:F,step:1});}catch(L){L=a.ba(L);w.oW('failedDroppable',E);w.oW('afterDroppable',E);throw L;}});}else if(x=='mouseover'){if(!w.app.cK.fZ)w.app.cK.iW(z.liNode());}else if(x=='mouseout')if(w.app.cK.fZ)w.app.cK.iW(0);});}});function p(q){this.jr=null;this.kP=null;this.app=q;};p.prototype={iW:function(q){var s=this;var r= ! !q;if(r&& !s.fZ){s.app.document.bH().addClass('drop_accepted');q.addClass('drop_target');}else if(!r&&s.fZ){s.app.document.bH().removeClass('drop_accepted');s.fZ.removeClass('drop_target');}s.fZ=r?q:null;},kG:function(q){this.jr=q;if(this.jr instanceof k)this.jr.focus();},vE:function(){return this.jr;},kz:function(q){this.kP=q;},pe:function(){return this.kP;},qp:function(){return! !this.jr;}};})();m.add('floatpanel',{bM:['panel']});(function(){var p={},q=false;function r(s,t,u,v,w){var x=t.iY()+'-'+u.iY()+'-'+s.gd+'-'+s.lang.dir+(s.fm&&'-'+s.fm||'')+(v.css&&'-'+v.css||'')+(w&&'-'+w||''),y=p[x];if(!y){y=p[x]=new n.panel(t,v,s.gd);y.ax=u.append(k.et(y.nt(s),u.getDocument()));y.ax.setStyles({display:'none',position:'absolute'});}return y;};n.pY=i.createClass({$:function(s,t,u,v){u.lE=true;var w=t.getDocument(),x=r(s,w,t,u,v||0),y=x.ax,z=y.getFirst().getFirst();this.ax=y;s.ia?s.ia.push(y):s.ia=[y];this._={panel:x,parentElement:t,dg:u,document:w,iframe:z,children:[],dir:s.lang.dir};},ej:{qq:function(s,t){return this._.panel.qq(s,t);},re:function(s,t){return this._.panel.re(s,t);},iv:function(s){return this._.panel.iv(s);},gf:function(s,t,u,v,w){var x=this._.panel,y=x.gf(s);this.fj(false);q=true;var z=this.ax,A=this._.iframe,B=this._.dg,C=t.ir(z.getDocument()),D=this._.dir=='rtl',E=C.x+(v||0),F=C.y+(w||0);if(D&&(u==1||u==4))E+=t.$.offsetWidth;else if(!D&&(u==2||u==3))E+=t.$.offsetWidth-1;if(u==3||u==4)F+=t.$.offsetHeight-1;this._.panel._.nr=t.dS();z.setStyles({top:F+'px',left:'-3000px',visibility:'hidden',opacity:'0',display:''});z.getFirst().removeStyle('width');if(!this._.qa){var G=g?A:new h.window(A.$.contentWindow);a.event.jP=true;G.on('blur',function(H){var K=this;if(g&& !K.fj())return;var I=H.data.bK(),J=I.getWindow&&I.getWindow();if(J&&J.equals(G))return;if(K.visible&& !K._.gF&& !q)K.hide();},this);G.on('focus',function(){this._.lG=true;this.gU();this.fj(true);},this);a.event.jP=false;this._.qa=1;}x.onEscape=i.bind(function(){this.onEscape&&this.onEscape();},this);i.setTimeout(function(){if(D)E-=z.$.offsetWidth;z.setStyles({left:E+'px',visibility:'',opacity:'1'});var H=z.getFirst();if(y.oz){function I(){var O=z.getFirst(),P=0,Q=y.ax.$;if(f.gecko||f.opera)Q=Q.parentNode;var R=Q.scrollWidth;if(g){Q=Q.document.body;var S=Q.getElementsByTagName('a');for(var T=0;T 0&&V>P)P=V;}}R+=P;if(g&&f.quirks&&R>0)R+=(O.$.offsetWidth||0)-(O.$.clientWidth||0);R+=4;O.setStyle('width',R+'px');y.ax.addClass('cke_frameLoaded');var W=y.ax.$.scrollHeight;if(g&&f.quirks&&W>0)W+=(O.$.offsetHeight||0)-(O.$.clientHeight||0);O.setStyle('height',W+'px');x._.iL.ax.setStyle('display','none').removeStyle('display');};if(x.hm)I();else x.onLoad=I;}else H.removeStyle('height');var J=x.ax,K=J.getWindow(),L=K.hV(),M=K.eR(),N={height:J.$.offsetHeight,width:J.$.offsetWidth};if(D?E<0:E+N.width>M.width+L.x)E+=N.width*(D?1: -1);if(F+N.height>M.height+L.y)F-=N.height;z.setStyles({top:F+'px',left:E+'px',opacity:'1'});i.setTimeout(function(){if(B.ny)if(f.gecko){var O=A.getParent();O.setAttribute('role','region');O.setAttribute('title',B.ny);A.setAttribute('role','region');A.setAttribute('title',' ');}if(g&&f.quirks)A.focus();else A.$.contentWindow.focus();if(g&& !f.quirks)this.fj(true);},0,this);},0,this);this.visible=1;if(this.onShow)this.onShow.call(this);if(f.ie7Compat||f.ie8&&f.ie6Compat)i.setTimeout(function(){this._.parentElement.$.style.cssText+='';},0,this);q=false;},hide:function(){var s=this;if(s.visible&&(!s.onHide||s.onHide.call(s)!==true)){s.gU();s.ax.setStyle('display','none');s.visible=0;}},fj:function(s){var t=this._.panel;if(s!=undefined)t.fj=s;return t.fj;},rA:function(s,t,u,v,w,x){if(this._.gF==s&&s._.panel._.nr==u.dS())return;this.gU();s.onHide=i.bind(function(){i.setTimeout(function(){if(!this._.lG)this.hide();},0,this);},this);this._.gF=s;this._.lG=false;s.gf(t,u,v,w,x);if(f.ie7Compat||f.ie8&&f.ie6Compat)setTimeout(function(){s.ax.aC(0).$.style.cssText+='';},100);},gU:function(){var s=this._.gF;if(s){delete s.onHide;delete this._.gF;s.hide();}}}});})();(function(){m.add('formpanel',{bM:['button'],onLoad:function w(){p();},gr:function y(w){var x=this;w.on('themeSpace',function A(z){if(z.data.space=='mainTop')z.data.html+='';});w.on('uiReady',function B(z){var A=w.document.getById('panel_view').aC(0);a.aG.bz(w,'formpanel',x,A);});w.bD('settings',{exec:function(z){z.oW('requestFilesViewSettingsForm',null,function(){if(z.cS('settings').bu==a.eV)setTimeout(function(){z.aG['formpanel.formpanel'][0].tools.ij().eG('input').getItem(0).focus();},0);});}});w.bD('refresh',{exec:function(z){var A=z.aV;if(A)z.oW('requestShowFolderFiles',{folder:A},function(){setTimeout(function(){z.aG['filesview.filesview'][0].bn().focus();},0);});}});w.bY.add('Settings',a.UI_BUTTON,{label:w.lang.Settings,command:'settings'});w.bY.add('Refresh',a.UI_BUTTON,{label:w.lang.Refresh,command:'refresh'});w.cS('refresh').bR(a.aY);}});function p(){var w=a.aG.hi('formpanel','formpanel',{dc:null});w.dT.push(function(){var x=this.bn();if(g){x.$.onfocusin=function(){x.addClass('focus_inside');};x.$.onfocusout=function(){x.removeClass('focus_inside');};}else{x.$.addEventListener('focus',function(){x.addClass('focus_inside');},true);x.$.addEventListener('blur',function(){x.removeClass('focus_inside');},true);}});w.bh('UnloadForm',['submit','requestUnloadForm'],function y(x){if(x.name=='submit'&& !this.data().gM)return;x.result=this.oW('beforeUnloadForm',function D(z,A){var E=this;if(z)return;try{E.bn().getParent().setStyle('display','none');E.app.layout.ea(true);if(E.data().dc){var B=E.app.cS(E.data().dc);if(B)B.bR(a.aS);E.data().dc=null;}var C=E.tools.ij();if(C){C.mF();C.remove();}E.tools.releaseDomNodes();E.oW('successUnloadForm',A);}catch(F){E.oW('failedUnloadForm',A);E.oW('afterUnloadForm',A);throw a.ba(F);}});});w.bh('LoadForm',['requestLoadForm'],function A(x){var y=this,z=i.extend({html:null,dq:null,cC:null,cancelSubmit:1,gM:1,command:null},x.data,true);x.result=this.oW('beforeLoadForm',z,function I(B,C){if(B)return;try{var D=this.bn();D.setHtml(C.html);D.getParent().removeStyle('display');this.app.layout.ea(true);var E=this.tools.ij();if(E){if(C.dq)if(C.cC)for(var F in C.cC)E.on(C.cC[F],C.dq);else E.on('submit',C.dq);if(C.cancelSubmit)E.on('submit',s);var G=E.eG('input');for(var F=0;F '+w.SetTitle+'
'+''+'
'+''+'';};function s(w){w.data.preventDefault();};function t(w,x){for(var y in w){if(x(w[y])!==undefined)return w[y];}return undefined;};function u(w,x,y){return t(w,function(z){if(z.tagName&&z.tagName.toLowerCase()==x&& !y--)return z;});};function v(w){return w?new k(w):null;};})();m.add('keystrokes',{eK:function(p){p.dJ=new a.dJ(p);p.oX={};},bz:function(p){var q=p.config.keystrokes,r=p.config.gN,s=p.dJ.keystrokes,t=p.dJ.gN;for(var u=0;u'+' '+''+' '+''+'
'+'- '+w.SetView+'
'+'- '+'
- '+'
'+' '+''+'
'+'- '+w.SetDisplay+'
'+'- '+'
- '+'
- '+'
'+' '+''+'
'+'- '+w.SetSort+'
'+'- '+'
- '+'
- '+'
'],C=u.length,D=C&&u[0].group;for(var E=0;E s.group)return 1;return r.fE s.fE?1:0;});};})();a.iD=i.createClass({$:function(p,q,r){var s=this;i.extend(s,r,{fE:0,className:'cke_button_'+q});s.group=p._.iA[s.group];s.app=p;s.name=q;},ej:{er:function(p,q,r){var y=this;var s=p.id+String(q),t=typeof y.bu=='undefined'?a.aS:y.bu,u=' cke_'+(t==a.eV?'on':t==a.aY?'disabled':'off'),v=y.label;if(t==a.aY)v=y.app.lang.common.unavailable.replace('%1',v);if(y.className)u+=' '+y.className;var w=y.hQ;r.push('');}}});l.ob=400;l.nj='';m.add('panel',{eK:function(p){p.bY.kd(a.UI_PANEL,n.panel.dq);}});a.UI_PANEL=2;n.panel=function(p,q,r){var t=this;if(q)i.extend(t,q);i.extend(t,{className:''});var s=a.basePath;i.extend(t.css,[s+'skins/'+r+'/uipanel.css']);t.id=i.getNextNumber();t.document=p;t._={iq:{}};};n.panel.dq={create:function(p){return new n.panel(p);}};n.panel.prototype={nt:function(p){var q=[];this.er(p,q);return q.join('');},er:function(p,q){var u=this;var r='cke_'+u.id;q.push('');return r;},oU:function(){var p=this._.rE;if(!p){if(this.lE||this.css.length){var q=this.document.getById('cke_'+this.id+'_frame'),r=q.getParent(),s=r.getAttribute('dir'),t=r.getParent().getAttribute('class').split(' ')[0],u=r.getParent().getAttribute('lang'),v=q.getFrameDocument();v.$.open();if(f.isCustomDomain())v.$.domain=document.domain;var w=i.addFunction(i.bind(function(z){this.hm=true;if(this.onLoad)this.onLoad();},this)),x=v.getWindow();x.$.CKFinder=CKFinder;var y=f.cssClass.replace(/browser_quirks|browser_iequirks/g,'');v.$.write("'+''+''+''+''+''+''+'');v.$.close();x.$.CKFinder=CKFinder;v.on('keydown',function(z){var B=this;var A=z.data.db();if(B._.onKeyDown&&B._.onKeyDown(A)===false){z.data.preventDefault();return;}if(A==27)B.onEscape&&B.onEscape();},this);p=v.bH();}else p=this.document.getById('cke_'+this.id);this._.rE=p;}return p;},qq:function(p,q){var r=this;q=r._.iq[p]=q||new n.panel.block(r.oU());if(!r._.iL)r.gf(p);return q;},iv:function(p){return this._.iq[p];},gf:function(p){var t=this;var q=t._.iq,r=q[p],s=t._.iL;if(s)s.hide();t._.iL=r;r._.cQ= -1;t._.onKeyDown=r.onKeyDown&&i.bind(r.onKeyDown,r);r.show();return r;}};n.panel.block=i.createClass({$:function(p){var q=this;q.ax=p.append(p.getDocument().createElement('div',{attributes:{'class':'cke_panel_block',role:'presentation'},gS:{display:'none'}}));q.jQ={};q._.cQ= -1;q.ax.hX();},_:{},ej:{show:function(){this.ax.setStyle('display','');},hide:function(){var p=this;if(!p.onHide||p.onHide.call(p)!==true)p.ax.setStyle('display','none');},onKeyDown:function(p){var u=this;var q=u.jQ[p];switch(q){case 'next':var r=u._.cQ,s=u.ax.eG('a'),t;while(t=s.getItem(++r)){if(t.getAttribute('_cke_focus')&&t.$.offsetWidth){u._.cQ=r;t.focus();break;}}return false;case 'prev':r=u._.cQ;s=u.ax.eG('a');while(r>0&&(t=s.getItem(--r))){if(t.getAttribute('_cke_focus')&&t.$.offsetWidth){u._.cQ=r;t.focus();break;}}return false;case 'click':r=u._.cQ;t=r>=0&&u.ax.eG('a').getItem(r);if(t)t.$.click?t.$.click():t.$.onclick();return false;}return true;}}});m.add('resize',{bz:function(p){var q=p.config;if(q.nB)p.on('uiReady',function(){var r=null,s,t;function u(w){p.document.bH().addClass('during_sidebar_resize');var x=w.data.$.screenX-s.x,y=t.width+x*(p.lang.dir=='rtl'? -1:1);p.nJ(Math.max(q.nN,Math.min(y,q.nC)));};function v(w){p.document.bH().removeClass('during_sidebar_resize');a.document.aF('mousemove',u);a.document.aF('mouseup',v);if(p.document){p.document.aF('mousemove',u);p.document.aF('mouseup',v);}};p.layout.dV().on('mousedown',function(w){if(!r)r=p.layout.dV();if(w.data.bK().$!=r.$)return;t={width:r.$.offsetWidth||0};s={x:w.data.$.screenX};a.document.on('mousemove',u);a.document.on('mouseup',v);if(p.document){p.document.on('mousemove',u);p.document.on('mouseup',v);}});});}});l.nN=120;l.nC=500;l.nB=true;(function(){m.add('status',{bM:['filesview'],onLoad:function s(){p();},gr:function u(s){var t=this;s.on('themeSpace',function w(v){if(v.data.space=='mainBottom')v.data.html+='';});s.on('uiReady',function A(v){var w=s.document.getById('status_view'),x=s.aG['filesview.filesview'],y=a.aG.bz(s,'status',t,w,{parent:x[i]});for(var z=0;z '+s.name+' ('+s.size+'KB, '+s.dateF+')';};function r(s,t){var u;if(s===0)u=t.FilesCountEmpty;else if(s==1)u=t.FilesCountOne;else u=t.FilesCountMany.replace('%1',s);return ' '+i.htmlEncode(u)+'
';};})();(function(){var p=function(){this.fk=[];this.pZ=false;};p.prototype.focus=function(){for(var r=0,s;s=this.fk[r++];)for(var t=0,u;u=s.items[t++];){if(u.focus){u.focus();return;}}};var q={hW:{iH:{qt:1,source:1},exec:function(r){if(r.dh){r.dh.pZ=true;if(g)setTimeout(function(){r.dh.focus();},100);else r.dh.focus();}}}};m.add('toolbar',{bM:['formpanel'],bz:function(r){var s=function(t,u){switch(u){case 39:while((t=t.next||t.toolbar.next&&t.toolbar.next.items[0])&& !t.focus){}if(t)t.focus();else r.dh.focus();return false;case 37:while((t=t.previous||t.toolbar.previous&&t.toolbar.previous.items[t.toolbar.previous.items.length-1])&& !t.focus){}if(t)t.focus();else{var v=r.dh.fk[r.dh.fk.length-1].items;v[v.length-1].focus();}return false;case 27:r.focus();return false;case 13:case 32:t.lc();return false;}return true;};r.on('themeSpace',function(t){if(t.data.space=='mainTop'){r.dh=new p();var u='cke_'+i.getNextNumber(),v=['');t.data.html+=v.join('');}});r.bD('hW',q.hW);}});})();n.separator={er:function(p,q){q.push('');return{};}};l.toolbar_Basic=[['Upload','Refresh']];l.toolbar_Full=[['Upload','Refresh','Settings','Help']];l.toolbar='Full';(function(){function p(q){if(g){q.$.onfocusin=function(){q.addClass('focus_inside');};q.$.onfocusout=function(){q.removeClass('focus_inside');};}else{q.$.addEventListener('focus',function(){q.addClass('focus_inside');},true);q.$.addEventListener('blur',function(){q.removeClass('focus_inside');},true);}};m.add('tools',{eK:function r(q){this.app=q;},addTool:function(q,r){var s='tool_'+i.getNextNumber();q=r?'':'';this.app.layout.dV().aC(0).appendHtml(q);return s;},addToolPanel:function(q){q=q||'';var r=this.addTool(q,1),s=this.app.layout.dV().aC(0).dB();p(s);return r;},hideTool:function(q){this.app.document.getById(q).setStyle('display','none');this.app.layout.ea(true);},showTool:function(q){this.app.document.getById(q).removeStyle('display');this.app.layout.ea(true);},removeTool:function(q){this.hideTool(q);this.app.document.getById(q).remove();}});})();(function(){m.add('uploadform',{bM:['formpanel','button'],onLoad:function w(){p();},gr:function x(w){w.bD('upload',{exec:function(y){y.oW('requestUploadFileForm',null,function(){if(y.cS('upload').bu==a.eV)setTimeout(function(){var z=y.aG['formpanel.formpanel'][0].tools.ij();if(z)z.eG('input').getItem(0).focus();},0);});}});w.bY.add('Upload',a.UI_BUTTON,{label:w.lang.Upload,command:'upload'});w.on('appReady',function(y){var z=w.aG['filesview.filesview'];for(var A=0;A');v.push('',r.lang.toolbar,'');var x=r.dh.fk,y=r.config.toolbar instanceof Array?r.config.toolbar:r.config['toolbar_'+r.config.toolbar];for(var z=0;z');w=0;}if(A==='/'){v.push('');continue;}v.push('');w=0;}var H=F.er(r,v);D=C.items.push(H)-1;if(D>0){H.previous=C.items[D-1];H.previous.next=H;}H.toolbar=C;H.onkey=s;}}if(w){v.push('');w=0;}v.push('');}v.push(' 0&&A.indexOf(a.bF.substr(0,9))!= -1;};w.tools.releaseDomNodes=i.override(w.tools.releaseDomNodes,function(A){return function(){var B=this;A.apply(B,arguments);delete B.jj;delete B.jc;if(B.gq!==undefined){B.gq.remove();delete B.gq;}};});w.tools.qB=function(){var A=this;if(A.jc===undefined)A.jc=A.widget.bn().aC([0,2]);return A.jc;};w.tools.qO=function(){var A=this;if(A.jj===undefined)A.jj=A.widget.bn().aC([0,1,0]);return A.jj;};w.tools.qL=function(){var E=this;if(E.gq===undefined){var A=f.isCustomDomain(),B='ckf_'+i.getNextNumber(),C='',D=E.widget.app.document.bH();D.appendHtml(C);E.gq=D.dB();}return E.gq;};function y(A,B){var C=this,D=C.data(),E=1,F=this.tools.qO(),G=F&&F.$.value;if(!G.length){A.data.preventDefault(true);this.oW('failedUploadFileForm');this.oW('afterUploadFileForm');return false;}var H=G.match(/\.([^\.]+)\s*$/)[1];if(!H|| !B.getResourceType().isExtensionAllowed(H)){A.data.preventDefault();C.app.msgDialog('',C.app.lang.UploadExtIncorrect);}else E=0;if(E){A.data.preventDefault(true);this.oW('failedUploadFileForm');this.oW('afterUploadFileForm');return false;}var I=C.app.document.getWindow().$;I.OnUploadCompleted=function(J,K){var L={step:3,filename:J,folder:B};if(K&& !J){C.app.msgDialog('',K);var M=C.tools.qB();M.setStyle('display','none');M.aC(1).setText('');M.aC(2).setText('');C.oW('failedUploadFileForm',L);}else{if(K)C.app.msgDialog('',K);if(C.app.aV==B)C.app.oW('requestShowFolderFiles',{folder:B,mw:J});C.oW('requestUnloadForm');C.oW('successUploadFileForm',L);}C.oW('afterUploadFileForm',L);try{delete I.OnUploadCompleted;}catch(N){I.OnUploadCompleted=undefined;}};if(q(this,F,this.tools.ij()))A.data.preventDefault();else{a.log('[UPLOADFORM] Starting IFRAME file upload.');this.oW('successUploadFileForm',{step:2});}return true;};function z(A,B,C){return '';};};function q(w,x,y){if(!(x.$.files&&x.$.files[0]&&x.$.files[0].getAsBinary))return false;if(x.$.files[0].fileSize>20971520)return false;var z=new XMLHttpRequest();if(!z.upload)return false;a.log('[UPLOADFORM] Starting XHR file upload.');w.oW('successUploadFileForm',{step:2});var A=y.dB().cf();y.addClass('progress_visible');v(z.upload,A,w.app.lang);var B=w.app.document.getWindow().$.OnUploadCompleted;z.addEventListener('error',function(D){y.removeClass('progress_visible');B('',w.app.lang.UploadUnknError);},false);z.addEventListener('load',function(D){var E=/ \s*window\.parent\.OnUploadCompleted\(\s*'(.*)'\s*,\s*'(.*)'\s*\).*<\/script>/,F=D.target.responseText,G=F.match(E);if(!G){B('','Error: '+F);return;}B(G[1],G[2]);},false);z.open('POST',y.getAttribute('action'));var C='-----CKFinder--XHR-----';z.setRequestHeader('Content-Type','multipart/form-data; boundary='+C);z.sendAsBinary(s(x,C));return true;};function r(w){var x,y,z='';for(x=0;x 127&&y<2048){z+=String.fromCharCode(y>>6|192);z+=String.fromCharCode(y&63|128);}else{z+=String.fromCharCode(y>>12|224);z+=String.fromCharCode(y>>6&63|128);z+=String.fromCharCode(y&63|128);}}return z;};function s(w,x){var y=w.$.files[0].fileName;y=r(y);return '--'+x+'\r\n'+'Content-Disposition: form-data; '+'name="'+w.name+'"; '+'filename="'+y+'"\r\n'+'Content-Type: application/octet-stream\r\n\r\n'+w.$.files[0].getAsBinary()+'\r\n'+'--'+x+'--\r\n';};function t(w,x){w.target.kC=w.loaded;var y=Number(w.loaded/1024).toFixed()+'/'+Number(w.total/1024).toFixed();w.target.log.getParent().cf().setText(x.Kb.replace('%1',y));};function u(w,x){var y=(new Date().getTime()-w.oS)/1000,z=w.kC/y;z=Number(z/1024).toFixed();w.log.getParent().cf().cf().setText(x.KbPerSecond.replace('%1',z));};function v(w,x,y){w.log=x.aC([3,0]);w.oS=new Date().getTime();w.interval=window.setInterval(u,1000,w,y);w.kC=0;w.onprogress=function(z){if(z.lengthComputable){t(z,y);u(z.target,y);var A=z.loaded/z.total;if(A<1){var B=A*100;if(B<0)B=0;z.target.log.setStyle('width',B+'%');}}};w.onload=function(z){var A=z.target;window.clearInterval(A.interval);var B=A.log.getParent().getParent();};};})();(function(){function p(r,s){var t='',u=0;for(var v=0;v '+w+'
| 0)Y.push('style="',aa.join('; '),'" ');Y.push(' class="cke_dialog_ui_vbox_child">',R[Z],' | ');}Y.push('
+ CKFinder is a Collaborative Software that makes it easy to maintain + and share files located on a central computer (the server).
++ Whether you are new to CKFinder or an experienced user, it is well worth spending + time browsing through the CKFinder documentation, to achieve complete knowledge + about this simple but powerful software.
++ Your attention is drawn to the Legal + Notices. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/002.html b/StudyDoIT/Editor/ckfinder/help/en/files/002.html new file mode 100644 index 0000000..0d3d3fd --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/002.html @@ -0,0 +1,37 @@ + + + ++ The CKFinder interface has been designed to be clear, familiar to our end users, + and easy to learn and use. Most features can be handled with a mouse click and context + menus. +
++ The following is a screenshot of CKFinder: +
+
+
+
+ The Folders Pane contains the "tree view" of the folders where you can navigate. + Folders are ways to organize files better.
++ It is called a "tree view" because you have the folders hierarchy represented like + tree branches. It uses the same graphic representation found in many modern operating + systems.
+
+ To open a folder, revealing its "children" folders, simply click in the plus sign
+ (
) in front of it. If the plus
+ sign is not present, the folder doesn't have children folders to be displayed.
+
+ See "Under Request Loading" below in this page to better understand how folders + are load. +
+
+ To close a folder, hiding its children folders, simply click in the minus sign (
) in front of it.
+
+ To select a folder, making it the "current folder" in CKFinder, simply click in + the folder name, or in its icon. The selected folder will have a different background + color. +
++ Advanced operations may be achieved on a folder by using its "Context + Menu". The following options are available: +
+
+
+ Note: Some context menu buttons may be disabled, depending + on CKFinder settings enforced by your system administrator. +
++ To create a child folder inside an existing folder, just click the "New Subfolder" + option in the context menu. A dialog box will appear, asking for the new folder + name. Just type it and confirm. +
++ Not all characters can be used in folder and files names due to limitations in the + systems where CKFinder runs. For instance, the following characters cannot be used + on folders and files names: \ / : + * ? " < + > |
++ To rename a folder, just click the "Rename" option in the context menu. A dialog + box, containing the current folder name, will appear, asking for the new folder + name. Just type it and confirm. +
++ Not all characters can be used in folder and files names due to limitations in the + systems where CKFinder runs. For instance, the following characters cannot be used + on folders and files names: \ / : + * ? " < + > |
++ Attention: by renaming a folder, links or media insertions + available in other pages, which point to files or folders inside the renamed folder, + will be "broken", therefore not available anymore. So, be careful when using this + feature.
++ To delete a folder, including its contents, just click the "Delete" option in the + context menu. A confirmation message will appear to ensure that this operation is + desired. +
++ Attention: by deleting a folder, links or media insertions + available in other pages, which point to files or folders inside the deleted folder, + will be "broken", therefore not available anymore. So, be careful when using this + feature.
++ The most important difference between CKFinder and the folders tree found in operating + systems, is that, in CKFinder, the folders are loaded "under request". It means + that it doesn't load the entire folders tree at startup, but loads a small subset + of them when "opening" the folder. This is a requirement on advanced web applications + like CKFinder.
++ To indicate that folders are being loaded, the "Loading..." label may appear when + opening a folder: +
+
+
+ The label will automatically disappear once the folders load is completed. Once + loaded, the label should not appear anymore for that folder. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/004.html b/StudyDoIT/Editor/ckfinder/help/en/files/004.html new file mode 100644 index 0000000..81cde28 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/004.html @@ -0,0 +1,104 @@ + + + ++ The Files Pane lists all files available in the selected folder.
++ The Files Pane may present two different views, depending on CKFinder settings (see + "Settings"). The following is a comparison of the "Thumbnails" + and the "List" views for the same folder:
+
+
+
+
+
+ To select a file, making it the "active file" in CKFinder, simply click in the file. + To make it easy to understand that the mouse is over the file, the file area will + be colored. The selected file will have a different background color (generally + blue). +
++ Advanced operations may be achieved on a file by using its "Context + Menu". The following options are available: +
+
+
+
+ Note: Some context menu buttons may be disabled, depending + on CKFinder settings enforced by your system administrator. +
++ To select a file, returning it to the hosting application, just click the "Select" + option.
++ To preview a file in the browser, just click the "View" button. Not all kinds of + files can be viewed on browsers, but this feature is quite useful for images, text + and PDF files. In other cases, the browser will ask you to open the file with the + proper application.
++ To download a file, just click the "Download" button. The browser will ask you for + the place to save the downloaded file in your computer.
++ To rename a file, just click the "Rename" option in the context menu. A dialog box, + containing the current file name, will appear, asking for the new name. Just type + it and confirm. +
++ Not all characters can be used in folder and files names due to limitations in the + systems where CKFinder runs. For instance, the following characters cannot be used + on folders and files names: \ / : + * ? " < + > |
++ Attention: by renaming a file, links or media insertions + available in other pages, which point to the renamed file, will be "broken", therefore + not available anymore. So, be careful when using this feature.
++ To delete a file, just click the "Delete" option in the context menu. A confirmation + message will appear to ensure that this operation is desired. +
++ Attention: by deleting a file, links or media insertions + available in other pages, which point to the deleted file, will be "broken", therefore + not available anymore. So, be careful when using this feature.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/005.html b/StudyDoIT/Editor/ckfinder/help/en/files/005.html new file mode 100644 index 0000000..b36e564 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/005.html @@ -0,0 +1,34 @@ + + + ++ The Toolbar is a dedicated area at the top of the CKFinder interface. It contains + a series of buttons that can be clicked to quickly execute specific functions. + Here is a screenshot of it: +
+
+
+
+ The following is the list of buttons available in the standard toolbar:
++ The upload* button, in the toolbar, opens the "Upload Pane", + which can be used to add new files to the current folder. Here is a screenshot of + it:
+
+
+ To close the Upload Pane, just click in the "Cancel" button, or click "Upload" again + in the toolbar.
++ * "Upload" is a technical term. It means the action of transferring + a file from your local computer to a central computer (also known as server).
++ The following are messages that may appear when uploading files:
++ Indicates that the uploaded file name is already in use by another + file in the same folder. To avoid conflict, a progressive number, the "(1)", has + been appended to the original name.
++ The uploaded file has not been accepted. +
++ The most common cause for this messages is that CKFinder has been configured to + not accept the kind of file you are trying to upload, based on its extension. This + is a security restriction. Another cause of it may be that the file size is too + big for your system. In this case the server must be configured to accept bigger + files. +
+The uploaded file contains HTML code. For security reasons, only files with selected extensions are allowed to contain HTML code.
+ ++ Please contact your system administrator to have more information regarding the + accepted file types and their size limits.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/007.html b/StudyDoIT/Editor/ckfinder/help/en/files/007.html new file mode 100644 index 0000000..e3e00d6 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/007.html @@ -0,0 +1,29 @@ + + + ++ While working in a shared space like CKFinder, where dozens or even hundreds of users are working in the same files, it may happen that changes are done by others + in the same folder you are working on, at the right moment that you have it opened. + To reload the files list, just click the "Refresh" button.
+
+
+ For example, suppose you have to create a page for a brand new product of your company. + You open CKFinder to get the product picture to include in the company web site, + but, when opening the "Products" folder, you can't find that picture. You take the + phone and call "Beth", saying: "Hey Beth, the product picture is not at CKFinder!". + Beth says, "Ops... just a minute". She opens CKFinder in her computer, uploads the + picture file from her desktop and tells you: "It's there now, just refresh it". + You + click on Refresh and, voila! The file appears there for you. This is why CKFinder + is also known as Collaborative Software.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/008.html b/StudyDoIT/Editor/ckfinder/help/en/files/008.html new file mode 100644 index 0000000..54277b0 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/008.html @@ -0,0 +1,70 @@ + + + ++ The "Settings" button, in the toolbar, opens the "Settings + Pane", where you can configure and customize CKFinder. Here is a screenshot of + it:
+
+ 
+ All settings are automatically saved by using browser "cookies". Cookies are small + files containing private configuration information for specific web sites.
++ To close the Settings Pane, just click in the "Close" button, or click "Settings" + again in the toolbar.
++ All configuration options are related to the Files Pane. + They are used to control how to display information in that pane. The Files + Pane will react immediately to changes in the Settings Pane.
++ Controls the view mode in the Files Pane:
++ Sets the amount of information available in the Files Pane. To exemplify, here is + the thumbnail box when you have no options selected for Display, until having all options + selected:
++
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ Controls the order in which the files will be listed. If can be alphabetically by + file name, by date of creation of the file with newer files first, or even by file + size.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/009.html b/StudyDoIT/Editor/ckfinder/help/en/files/009.html new file mode 100644 index 0000000..25e1813 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/009.html @@ -0,0 +1,15 @@ + + + ++ Opens the "User's Guide" in a new window.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/010.html b/StudyDoIT/Editor/ckfinder/help/en/files/010.html new file mode 100644 index 0000000..505cb61 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/010.html @@ -0,0 +1,29 @@ + + + ++ The "Status Bar" is a small space used to display information regarding the select + file, the total number of files in the folder, etc. It can be found at the very + button of the CKFinder interface. +
++ If a file is selected in CKFinder, the Status Bar will display + detailed information about that file, containing the file name, its size and the + data of its last modification. For example:
+
+
+ If no files are selected instead, the total number of files in + the current folder is displayed. For example:
+
+
+ CKFinder, including this documentation, is Copyright © 2007-2011 CKSource - Frederico Knabben. All rights + reserved. Please ensure that you have read and understood the CKFinder + License. +
+
+ The icons used in the toolbar and context menus have been designed by Mark James.
+ Please check the following URL for more information:
+ http://www.famfamfam.com/lab/icons/silk/
+ CKFinder, the CKFinder Logo, CKSource, CKEditor and FCKeditor are trademarks of CKSource - Frederico Knabben.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/012.html b/StudyDoIT/Editor/ckfinder/help/en/files/012.html new file mode 100644 index 0000000..5c1d746 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/012.html @@ -0,0 +1,43 @@ + + + ++ The "Context Menu" is a series of buttons (called "menu") that can be used to execute + specific tasks in the object that has been clicked. The available options dynamically + change, depending on which kind of object is clicked.
++ The following are the menus that you may find while working on a standard CKFinder + installation.
++ It appears when clicking in a folder in the Folders Pane + with the mouse right button:
+
+
+ It appears when clicking in a file in the Files Pane with + the mouse right button:
+
+
+ It appears when clicking in the Files Pane, but outside a + file (in the background) with the mouse right button:
+
+ 
+ CKFinder is a "web application". It means that it's made to run inside web browsers, + making it easy to deploy and to use in any computer.
++ Currently, the following browsers are required to CKFinder to run:
++ Some features are dependent of your browser settings. By default, it should be ready + for CKFinder, but if you are experiencing problems with the Context + Menu or your Settings are not being saved, be sure + that your browser is configured to "allow scripts to replace context menus" ("allow scripts to receive right clicks") + and that you have "cookies support enabled".
++ Please contact your system administrator if you have any doubt.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/header.html b/StudyDoIT/Editor/ckfinder/help/en/files/header.html new file mode 100644 index 0000000..d3d0e0d --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/header.html @@ -0,0 +1,32 @@ + + + +
+ + CKFinder User's Guide+ |
+ + Visit the CKFinder Web Site | +
+ Feel free to send us your suggestions about this documentation. + We are always willing to improve it, offering you a better software every day.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/en/files/toc.html b/StudyDoIT/Editor/ckfinder/help/en/files/toc.html new file mode 100644 index 0000000..25d63e7 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/en/files/toc.html @@ -0,0 +1,90 @@ + + + ++ Table of Contents +
++ CKFinder es un programa colaborativo que hace más fácil mantener y compartir archivos localizados en una computadora central (el servidor).
++ Ya sea que usted sea nuevo al programa o un usuario experto, vale la pena tomar un poco de su tiempo para leer la documentación completa de CKFinder para obtener un conocimiento completo acerca de este simple pero poderoso programa.
++ Se le pide su atención a los Avisos legales
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/002.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/002.html new file mode 100644 index 0000000..2a83faf --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/002.html @@ -0,0 +1,27 @@ + + + ++ La Interface de CKFinder, ha sido diseñada para ser clara, familiar, fácil de aprender y usar para nuestros usuarios finales. La mayoría de las caracteristicas pueden ser usadas con movimientos del mouse y clicks en menus de contexto.
++ La siguiente imagen, es un screenshot de CKFinder:
+
+
+
+ El pánel de carpetas, contiene la "vista de arbol" de las carpetas por las que se puede navegar, las carpetas, son una manera de organizar mejor los archivos.
++ Se le llama "vista de arbol", por que se tienen las carpetas representadas jerarquicamente como las ramas de un arbol. Usa la misma representación gráfica que muchos sistemas operativos modernos.
+
+ Para abrir una carpeta y revelar sus carpetas "hijas", simplemente haga click en el signo "más" (
) en frente de la misma. Si el signo "más" no está presente, la carpeta no tiene carpetas hijas que puedan desplegarse.
+ Vea "Cargado bajo demanda " al final de la pagina para un mejor entendimiento de como son cargadas las carpetas.
+
+ Para cerrar una carpeta, y por ende esconder sus carpetas "hijas", simplemente dé click en el signo "menos" (
) en frente de la misma.
+ Para seleccionar una carpeta y por ende convertirla a "la carpeta actual" para CKFinder, simplemente dé click en el nombre de la carpeta o en su icono. La carpeta seleccionada tendrá un color de fondo diferente.
++ Es posible utilizar operaciones avanzadas en una carpeta, haciendo uso de su "Menú de contexto", las siguientes opciones estan disponibles:
+
+
+ Nota: Algunos botones de un menú de contexto podrían estar deshabilitados, dependiendo de los ajustes asignados por el administrador del sistema.
++ Para crear una carpeta "hija" dentro de una carpeta ya existente, solamente haga clic sobre la opción "Nueva Carpeta" del menú de contexto. Una ventana de dialogo aparecerá en donde deberá escribir el nombre de la nueva Carpeta, luego confirme la operación.
++ No todos los caracteres pueden ser usados para establecer un nombre de carpeta, debido a limitaciones en los sistemas donde CKFinder se ejecuta. Por ejemplo, los siguientes caracteres, no pueden usarse para dar nombre a carpetas ni archivos: \ / : + * ? " < + > |
++ Para renombrar una carpeta, solo dé click en la opción "Renombrar" del menú de contexto. Una ventana de dialogo aparecerá conteniendo el nombre actual de la carpeta, ahí deberá escribir el nuevo nombre que desea asignar a la carpeta, luego confirme la operación.
++ No todos los caracteres pueden ser usados para establecer un nombre de carpeta, debido a limitaciones en los sistemas donde CKFinder se ejecuta. Por ejemplo, los siguientes caracteres, no pueden usarse para dar nombre a carpetas ni archivos: \ / : * ? " < > |
+ +Atención: Al renombrar una carpeta, las ligas o inserciones de medios disponibles en otras paginas que apunten a archivos o carpetas dentro de aquella que fue renombrada podrían quedar "quebradas" y por lo mismo no disponibles más. Asi que sea cauteloso cuando use esta caracteristica.
++ Para borrar una carpeta, incluyendo su contenido, solo dé click sobre la opción "Borrar" del menú de contexto. Un mensaje de confirmación aparecerá para asegurarse de que realmente desea eliminar dicha carpeta.
+Atención: Al renombrar una carpeta, las ligas o inserciones de medios disponibles en otras paginas que apunten a archivos o carpetas dentro de aquella que fue renombrada podrían quedar "quebradas" y por lo mismo no disponibles más. Asi que sea cauteloso cuando use esta caracteristica.
++ La diferencia más importante entre CKFinder y la "vista de arbol" que se encuentra en los sistemas operativos modernos, es que los folders se cargan "bajo demanda", esto significa que CKFinder no carga todo el arbol al inicio, sino que solo carga un pequeño subconjunto de el cuando se abre la carpeta, este es un requerimiento de aplicaciones avanzadas para web como lo es CKFinder.like CKFinder.
++ Para indicar que las carpetas se están cargando, la etiqueta "Cargando..." podría aparecer cuando se intente abrir una carpeta.
+
+
+ La etiqueta desaparecerá automaticamente una vez que la carga de las carpetas haya terminado, una vez cargada, la etiqueta no aparecera más para esa carpeta.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/004.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/004.html new file mode 100644 index 0000000..fa6d553 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/004.html @@ -0,0 +1,67 @@ + + + ++ El Pánel de archivos lista los archivos disponibles en la carpeta seleccionada.
+El pánel de archivos puede presentar dos vistas diferentes, dependiendo de la configuración de CKFinder (vea "Ajustes"). La siguiente, es una comparación de la vista "Miniaturas" y la vista "Lista" para la misma carpeta:
+
+
+
+
+
+ Para seleccionar un archivo, y por ende convertirlo al "archivo activo" en CKFinder, simplemente dé click sobre el archivo. Para identificar más fácilmente que el puntero del mouse está sobre un archivo, el área del mismo será coloreada. El archivo seleccionado tendrá un color de fondo diferente (generalmente Azul).
+Se pueden realizar operaciones avanzadas en un archivo utilizando su "Menú de Contexto". Las siguientes opciones estan disponibles:
+
+
+
+ Nota: Algunos botones del menu de contexto, podrían estar deshabilitados, esto depende de los ajustes que su administrador haya hecho en la configuración de CKFinder.
++ Para seleccionar un archivo, y por ende regresarlo a la aplicación solamente dé click sobre la opción "Seleccionar".
+Para previsualizar un archivo en el browser, solo dé click en el botón "Visualizar". No todos los tipos de archivos pueden ser visualizados por los browsers, pero esta caracteristica es útil para imagenes, texto y archivos del tipo PDF. En otros casos, el browser le preguntará si desea abrir el archivo con la aplicación correspondiente.
++ Para descargar (bajar) un archivo, solo dé click en el botón "Descargar", el bropwser le solicitará el lugar donde desea guardar el archivo en su computadora personal.
++ Para renombrar un archivo, solo dé click en el botón "Renombrar" en el menú de contexto. Una ventana aparecerá con el nombre actual del archivo, donde deberá escribir el nuevo nombre y confirmar la operación.
+No todos los caracteres pueden ser usados para establecer un nombre de archivo, debido a limitaciones en los sistemas donde CKFinder se ejecuta. Por ejemplo, los siguientes caracteres, no pueden usarse para dar nombre a carpetas ni archivos: \ / : * ? " < > |
+Atención: Al renombrar un archivo, las ligas o inserciones de medios disponibles en otras paginas que apunten a archivos o carpetas dentro de aquel que fue renombrado podrían quedar "quebradas" y por lo mismo no disponibles más. Asi que sea cauteloso cuando use esta caracteristica.
++ Para borrar un archivo, solo dé click en la opción "Borrar" del menú de contexto. Un mensaje de confirmación aparecerá para asegurarse que realmente esa operación es la que desea realizar.
++ Atención: Al borrar un archivo, las ligas o inserciones de medios disponibles en otras paginas que apunten al archivo recien borrado, quedaran "quebradas" y por ende no disponibles más, asi que sea cauteloso al utilizar esta opción.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/005.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/005.html new file mode 100644 index 0000000..5eaff38 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/005.html @@ -0,0 +1,28 @@ + + + ++ La barra de herramientas, es un área dedicada situada al inicio de la interface de CKFinder. Contiene una serie de botones a los que se puede dar click para ejecutar rápidamente funciones específicas. Este es un screenshot de esta barra:
+
+
+
+ La siguiente, es una lista de los botones que están disponibles en una barra de herramientas estandar:
++ El botón "Subir" en la barra de herramientas , abre el "Pánel de Subida", que puede ser usado para agregar nuevos archivos a la carpeta actual, he aquí un screenshot de este pánel:
+
+
+ Para cerrar el pánel de subida, solo dé click sobre el botón "Cancelar", o haga click nuevamente sobre el botón "Subir" de la barra de herramientas.
++ * "Subir" es un término técnico. Se refiere a la acción de transferir un archivo situado en su computadora local a otra computadora central, (también conocida como Servidor).
++ Los siguientes, son los mensajes que podrían aparecer mientras se transfiere un archivo:
++ Indica que el nombre del archivo que subió ya se encuentra en uso por otro archivo en la misma carpeta, para evitar un conflicto, un número progresivo (aquel que estará entre los parentesis), ha sido agregado al final del nombre original.
++ El archivo que subió no ha sido aceptado.
++ La causa mas común de este menesaje, es que CKFinder ha sido configurado para NO aceptar el tipo de archivo que está usted intentando subir, basado en su extensión. Esta, es una restricción de seguridad. Otra causa puede ser que el tamaño del archivo es demasiado grande para el sistema destino, en este caso, el servidor deberá ser configurado para aceptar un archivo de mayor tamaño.
+El archivo que subió contiene código HTML. Por razones de seguridad solamente archivos con ciertas extensiones son permitidos cuando contienen código HTML.
+ ++ Por favor contacte al Administrador del sistema para obtener mayor información referente a los tipos de archivo aceptados y sus límtes en tamaño.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/007.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/007.html new file mode 100644 index 0000000..a738ba2 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/007.html @@ -0,0 +1,18 @@ + + + ++ Cuando se trabaja en un espacio compartido como lo es CKFinder, en donde docenas o incluso cientos de usuarios están trabajando en los mismos archivos, podría suceder que alguno de estos otros usuarios realice cambios en el mismo folder en el que usted se encuentra trabajando en el justo momento en el que usted lo abrió. Para recargar la lista de archivos, solamente dé click sobre el botón "Recargar", esto le presentará la lista de archivos como se encuentra en ese instante.
+
+
Por ejemplo, imagine usted que tiene que crear una pagina para un nuevo producto de su compañía. Usted abre entonces CKFinder para obtener la fotografía del producto para ser incluida en el sitio web de la empresa, pero cuando abre la carpeta "Productos" usted no puede encontrar esa fotografía. Toma el teléfono y llama a "Beth", diciendo: "¡Hey Beth, la imagen del producto no se encuentra en CKFinder!". Beth dice entonces: "Ops... espera un minuto". Ella abre CKFinder en su computadora, sube el archivo con la fotografía desde su computadora y le dice: "Ahí está, solo Recarga". Usted entonces dá click sobre el botón "Recargar" y ¡voila!, el archivo aparece ahí para usted. Es por esto que CKFinder es tambien conocido como un programa de colaboración.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/008.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/008.html new file mode 100644 index 0000000..9d95c4f --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/008.html @@ -0,0 +1,57 @@ + + + ++ El botón "Ajustes", en la barra de herramientas, abre el "pánel de ajustes", donde usted podrá configurar y personalizar CKFinder, he aquí un screenshot de el:
+
+ 
+ Todos los ajustes son guardados automaticamente utilizando las denominadas "Cookies" de su browser. Las "Cookies" son pequeños archivos que contienen información de configuración proivada para sitios web especificos.
++ Para cerrar el pánel de ajustes, solo dé click sobre el botón "Cerrar" o dé click nuevamente sobre el botón "Ajustes" de la barra de herramientas.
++ Todas las opciones de configuración tienen que ver con el Pánel de Archivos . + Se usan para controlar como desplegar información en ese pánel. El Pánel de Archivos, reacciona inmediatamente a los cambios hechos en el Pánel de ajustes.
++ Controla el modo actual de vista del Pánel de Archivos:
++ Ajusta la cantidad de información disponible en el pánel de archivos. Para ejemplificar, he aquí como se mostrarían los archivos cuando ningúna opción está seleccionada, hasta llegar a tener todas las opciones seleccionadas.
+
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ Controla el orden en el que los archivos serán listados. Puede ser alfabeticamente por el nombre del archivo, por fecha de creación del archivo siendo el más nuevo el primero o incluso por el tamaño del archivo.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/009.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/009.html new file mode 100644 index 0000000..e511e88 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/009.html @@ -0,0 +1,17 @@ + + + + ++ Abre esta "Guía del usuario" en una ventana nueva.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/010.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/010.html new file mode 100644 index 0000000..f0c2327 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/010.html @@ -0,0 +1,22 @@ + + + ++ La "Barra de Estado" es un pequeño espacio usado para desplegar información relevante al archivo seleccionado, el número total de archivos en la carpeta, etc. Se puede encontrar al final de la interface de CKFinder
++ Si un archivo es seleccionado en CKFinder, la barra de estado desplegará información detallada acerca de ese archivo en particular, contendrá el nombre del archivo, su tamaño y la fecha de su última modificación, por ejemplo:
+
+
Si ningún archivo está seleccionado por el contrario, el número total de archivos en la carpeta actual será mostrado. Por ejemplo:
+
+
+ CKFinder, incluyendo su documentación tiene Copyright © 2007-2011 por CKSource - Frederico Knabben. Todos los derechos reservados, por favor asegurse de leer y entender la licencia de uso. Licencia de CKFinder.
++ Los iconos usados en la barra de herramientas y los menus de contexto, han sido diseñados por Mark James. +Por favor entre a la siguiente dirección (URL) para obtener más información: http://www.famfamfam.com/lab/icons/silk/
++ CKFinder, el logotipo de CKFinder, CKSource, CKEditor y FCKeditor son marcas registradas de CKSource - Frederico Knabben.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/012.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/012.html new file mode 100644 index 0000000..16c575a --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/012.html @@ -0,0 +1,38 @@ + + + ++ El "Menú de Contexto " es una serie de botones (llamados "menú") que pueden ser usados para ejecutar tareas específicas en el objeto que ha sido seleccionado con un click. Las opciones disponibles cambiarán dinamicamente dependiendo del objeto que haya sido seleccionado con un click.
++ Los siguientes, son los menus que podría encontrar mientras trabaja con una instalación estandar de CKFinder + installation.
++ Aparece cuando da un click con el botón derecho del mouse sobre una carpeta en el Pánel de carpetas
+
+
+ Aparece cuando da click con el botón derecho del mouse sobre un archivo en el Pánel de Archivos:
+
+
+ Aparece cuando se da click con el botón derecho del mouse en el Pánel de archivos , pero afuera de un archivo (en el fondo):
+
+ ![]()
+ CKFinder es una aplicación "Web", esto significa que está hecha para ser ejecutada dentro de un "browser" (navegador) haciendo más fácil distribuir y usar en cualquier computadora.
++ Actualmente cualquiera de los siguientes browsers se requieren para ejecutar CKFinder:
+Algunas caracteristicas dependen para su funcionamiento de ajustes propios del navegador de internet (browser). Por default CKFinder debería funcionar correctamente, sin embargo si experimienta algun problema con el Menú de Contexto o quizá sus Ajustes no estan siendo guardados, asegurese que su browser está configurado para "Permitir a los scripts reemplazar menus de contexto" ("Permitir a los scripts recibir clicks con el botón derecho") y además tener habilitado el "Soporte para cookies".
+Por favor contacte a su administrador en caso de que tenga alguna duda.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/header.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/header.html new file mode 100644 index 0000000..d332cac --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/header.html @@ -0,0 +1,33 @@ + + + +
+ + Guía del Usuario de CKFinder+ |
+ + Visite el sitio Web de CKFinder | +
+ Sientase libre de para enviarnos sus sugerencias acerca de esta documentación. Estamos siempre dispuestos a mejorarla, para ofrecerle siempre un mejor software cada dia.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es-mx/files/toc.html b/StudyDoIT/Editor/ckfinder/help/es-mx/files/toc.html new file mode 100644 index 0000000..c41f337 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es-mx/files/toc.html @@ -0,0 +1,91 @@ + + + ++ Indice +
++ CKFinder es un programa colaborativo que hace más fácil mantener y compartir ficheros localizados en un ordenador central (el servidor).
++ Ya sea que usted es nuevo al programa o un usuario experto, vale la pena emplear un poco de su tiempo para leer la documentación completa de CKFinder para obtener un conocimiento completo acerca de este simple pero poderoso programa.
++ Se le pide su atención a los Avisos legales
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/002.html b/StudyDoIT/Editor/ckfinder/help/es/files/002.html new file mode 100644 index 0000000..1724696 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/002.html @@ -0,0 +1,28 @@ + + + + ++ La interfaz de CKFinder ha sido diseñada para ser clara, familiar, fácil de aprender y usar para nuestros usuarios finales. La mayoría de las características pueden ser usadas con movimientos del ratón y clicks en menús contextuales.
++ La siguiente imagen es una captura de pantalla de CKFinder:
+
+
+
+ El panel de carpetas contiene la "vista de árbol +" de las carpetas por las que se puede navegar. Las carpetas son una manera de organizar mejor los ficheros.
++ Se le llama "vista de árbol +", por que se tienen las carpetas representadas jerárquicamente como las ramas de un árbol. Usa la misma representación gráfica que muchos sistemas operativos modernos.
+
+ Para abrir una carpeta y revelar sus carpetas "hijas", simplemente haga click en el signo "más" (
) en frente de la misma. Si el signo "más" no está presente, la carpeta no tiene carpetas hijas que puedan desplegarse.
+ Vea "Cargado bajo demanda " al final de la pagina para un mejor entendimiento de cómo son cargadas las carpetas.
+
+ Para cerrar una carpeta, y por ende esconder sus carpetas "hijas", simplemente haga click en el signo "menos" (
) en frente de la misma.
+ Para seleccionar una carpeta y por ende convertirla a "la carpeta actual" para CKFinder, simplemente haga click en el nombre de la carpeta o en su icono. La carpeta seleccionada tendrá un color de fondo diferente.
++ Es posible utilizar operaciones avanzadas en una carpeta, haciendo uso de su "Menú contextual", las siguientes opciones están disponibles:
+
+
+ Nota: Algunas opciones del menú contextuales podrían estar deshabilitados dependiendo de los ajustes asignados por el administrador del sistema.
+ ++ Para crear una carpeta "hija" dentro de una carpeta ya existente, solamente haga click sobre la opción "Nueva Carpeta" del menú contextual. Una ventana de diálogo aparecerá en donde deberá escribir el nombre de la nueva Carpeta, luego confirme la operación.
++ No todos los caracteres pueden ser usados para establecer un nombre de carpeta, debido a limitaciones en los sistemas donde CKFinder se ejecuta. Por ejemplo, los siguientes caracteres no pueden usarse para dar nombre a carpetas ni ficheros: \ / : + * ? " < + > |
+ ++ Para renombrar una carpeta, solo haga click en la opción "Renombrar" del menú contextual. Una ventana de dialogo aparecerá conteniendo el nombre actual de la carpeta, ahí deberá escribir el nuevo nombre que desea asignar a la carpeta, luego confirme la operación.
++ No todos los caracteres pueden ser usados para establecer un nombre de carpeta, debido a limitaciones en los sistemas donde CKFinder se ejecuta. Por ejemplo, los siguientes caracteres, no pueden usarse para dar nombre a carpetas ni ficheros: \ / : * ? " < > |
+ +Atención: Al renombrar una carpeta, los enlaces o inserciones de medios disponibles en otras páginas que apunten a ficheros o carpetas dentro de aquella que fue renombrada podrían quedar "rotas" y por lo tanto no funcionarán. Así que sea cauteloso cuando use esta característica.
+ ++ Para borrar una carpeta, incluyendo su contenido, solo haga click sobre la opción "Borrar" del menú contextual. Un mensaje de confirmación aparecerá para asegurarse de que realmente desea eliminar dicha carpeta.
+Atención: Al borrar una carpeta, los enlaces o inserciones de medios disponibles en otras páginas que apunten a ficheros o carpetas dentro de aquella que fue borrada podrían quedar "rotas" y por lo tanto no funcionarán. Así que sea cauteloso cuando use esta característica.
+ ++ La diferencia más importante entre CKFinder y la "vista de árbol " que se encuentra en los sistemas operativos modernos, es que las carpetas se cargan "bajo demanda", esto significa que CKFinder no carga todo el árbol al inicio, sino que solo carga un pequeño subconjunto de él cuando se abre la carpeta, este es un requerimiento de aplicaciones avanzadas para web como lo es CKFinder.
++ Para indicar que las carpetas se están cargando, la etiqueta "Cargando..." podría aparecer cuando se intente abrir una carpeta.
+
+
+ La etiqueta desaparecerá automaticamente una vez que la carga de las carpetas haya terminado. Una vez cargada, la etiqueta no aparecerá más para esa carpeta.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/004.html b/StudyDoIT/Editor/ckfinder/help/es/files/004.html new file mode 100644 index 0000000..b97dd7f --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/004.html @@ -0,0 +1,68 @@ + + + + ++ El panel de ficheros muestra los ficheros disponibles en la carpeta seleccionada.
+El panel de ficheros puede presentar dos vistas diferentes, dependiendo de la configuración de CKFinder (vea "Configuración"). La siguiente, es una comparación de la vista "Iconos" y la vista "Lista" para la misma carpeta:
+
+
+
+
+
+ Para seleccionar un fichero, y por ende convertirlo al "fichero activo" en CKFinder, simplemente haga click sobre el fichero. Para identificar más fácilmente que el puntero del ratón está sobre un fichero, el área del mismo será coloreada. El fichero seleccionado tendrá un color de fondo diferente (generalmente Azul).
+Se pueden realizar operaciones avanzadas en un fichero utilizando su "Menú contextual". Las siguientes opciones estan disponibles:
+
+
+
+ Nota: Algunos botones del menú contextual, podrían estar deshabilitados, esto depende de los ajustes que su administrador haya hecho en la configuración de CKFinder.
++ Para seleccionar un fichero, y por ende regresarlo a la aplicación solamente haga click sobre la opción "Seleccionar".
+Para previsualizar un fichero en el navegador, haga click en el botón "Visualizar". No todos los tipos de ficheros pueden ser visualizados por los navegadores, pero esta característica es útil para imagenes, texto y ficheros del tipo PDF. En otros casos, el navegador le preguntará si desea abrir el fichero con la aplicación correspondiente.
++ Para descargar (bajar) un fichero, haga click en el botón "Descargar", el navegador le solicitará el lugar donde desea guardar el fichero en su ordenador.
++ Para renombrar un fichero, haga click en el botón "Renombrar" en el menú contextual. Una ventana aparecerá con el nombre actual del fichero, donde deberá escribir el nuevo nombre y confirmar la operación.
+No todos los caracteres pueden ser usados para establecer un nombre de fichero, debido a limitaciones en los sistemas donde CKFinder se ejecuta. Por ejemplo, los siguientes caracteres, no pueden usarse para dar nombre a carpetas ni ficheros: \ / : * ? " < > |
+Atención: Al renombrar un fichero, los enlaces o inserciones de medios disponibles en otras páginas que apunten al fichero renombrado podrían quedar "rotos" y por tanto no funcionar. Así que sea cauteloso cuando use esta característica.
++ Para borrar un fichero, haga click en la opción "Borrar" del menú contextual. Un mensaje de confirmación aparecerá para asegurarse que realmente esa operación es la que desea realizar.
++ Atención: Al borrar un fichero, los enlaces o inserciones de medios disponibles en otras páginas que apunten al fichero recien borrado quedaran "rotos" y por tanto no funcionar, así que sea cauteloso al utilizar esta opción.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/005.html b/StudyDoIT/Editor/ckfinder/help/es/files/005.html new file mode 100644 index 0000000..2045d81 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/005.html @@ -0,0 +1,29 @@ + + + + ++ La barra de herramientas es un área dedicada situada al inicio de la interfaz de CKFinder. Contiene una serie de botones a los que se puede dar click para ejecutar rápidamente funciones específicas. Esta es una imagen de esta barra:
+
+
+
+ La siguiente es una lista de los botones que están disponibles en una barra de herramientas estandar:
++ El botón "Añadir" en la barra de herramientas , abre el "Panel de Subida", que puede ser usado para agregar nuevos ficheros a la carpeta actual, he aquí una imagen de este panel:
+
+
+ Para cerrar el panel de subida, haga click sobre el botón "Cancelar", o haga click nuevamente sobre el botón "Añadir" de la barra de herramientas.
++ * "Subir" es un término técnico. Se refiere a la acción de transferir un fichero situado en su ordenador local a otro ordenador central, (también conocido como Servidor).
++ Los siguientes son los mensajes que podrían aparecer mientras se transfiere un fichero:
++ Indica que el nombre del fichero que subió ya se encuentra en uso por otro fichero en la misma carpeta, para evitar un conflicto, un número progresivo (aquel que estará entre los parentesis), ha sido agregado al final del nombre original.
++ El fichero que subió no ha sido aceptado.
++ La causa mas común de este mensaje, es que CKFinder ha sido configurado para NO aceptar el tipo de fichero que está usted intentando subir, basado en su extensión. Esta es una restricción de seguridad. Otra causa puede ser que el tamaño del fichero es demasiado grande para el sistema destino, en este caso, el servidor deberá ser configurado para aceptar un fichero de mayor tamaño.
+El fichero que subió contiene código HTML. Por razones de seguridad solamente ficheros con ciertas extensiones son permitidos cuando contienen código HTML.
+ ++ Por favor contacte al Administrador del sistema para obtener mayor información referente a los tipos de fichero aceptados y sus límites en tamaño.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/007.html b/StudyDoIT/Editor/ckfinder/help/es/files/007.html new file mode 100644 index 0000000..04fe170 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/007.html @@ -0,0 +1,19 @@ + + + + ++ Cuando se trabaja en un espacio compartido como lo es CKFinder, en donde docenas o incluso cientos de usuarios están trabajando en los mismos ficheros, podría suceder que alguno de estos otros usuarios realice cambios en la misma carpeta en la que usted se encuentra trabajando. Para recargar la lista de ficheros, solamente haga click sobre el botón "Actualizar", esto le presentará la lista de ficheros como se encuentra en ese instante.
+
+
Por ejemplo, imagine usted que tiene que crear una página para un nuevo producto de su compañía. Usted abre entonces CKFinder para obtener la fotografía del producto para ser incluida en el sitio web de la empresa, pero cuando abre la carpeta "Productos" usted no puede encontrar esa fotografía. Toma el teléfono y llama a "Beth", diciendo: "¡Hey Beth, la imagen del producto no se encuentra en CKFinder!". Beth dice entonces: "Ops... espera un minuto". Ella abre CKFinder en su ordenador, sube el fichero con la fotografía desde su ordenador y le dice: "Ahí está, solo Actualiza". Usted entonces dá click sobre el botón "Actualizar" y ¡voila!, el fichero aparece ahí para usted. Es por esto que CKFinder es también conocido como un programa de colaboración.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/008.html b/StudyDoIT/Editor/ckfinder/help/es/files/008.html new file mode 100644 index 0000000..87a673c --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/008.html @@ -0,0 +1,58 @@ + + + + ++ El botón "Configuración", en la barra de herramientas, abre el "Panel de Configuración", donde usted podrá configurar y personalizar CKFinder, he aquí una imagen de él:
+
+ 
+ Todos los ajustes son guardados automaticamente utilizando las denominadas "Cookies" de su navegador. Las "Cookies" son pequeños ficheros que contienen información de configuración privada para sitios web especificos.
++ Para cerrar el panel de configuración, haga click sobre el botón "Cerrar" o haga click nuevamente sobre el botón "Configuración" de la barra de herramientas.
++ Todas las opciones de configuración tienen que ver con el Panel de Ficheros . + Se usan para controlar como mostrar información en ese panel. El panel de Ficheros reacciona inmediatamente a los cambios hechos en el panel de configuración.
++ Controla el modo actual de vista del Panel de Ficheros:
++ Ajusta la cantidad de información disponible en el panel de ficheros. Para ejemplificar, he aquí como se mostrarían los ficheros cuando ningúna opción está seleccionada, hasta llegar a tener todas las opciones seleccionadas.
+
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ Controla el orden en el que los ficheros serán listados. Puede ser alfabeticamente por el nombre del fichero, por fecha de creación del fichero siendo el más nuevo el primero o incluso por el tamaño del fichero.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/009.html b/StudyDoIT/Editor/ckfinder/help/es/files/009.html new file mode 100644 index 0000000..e511e88 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/009.html @@ -0,0 +1,17 @@ + + + + ++ Abre esta "Guía del usuario" en una ventana nueva.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/010.html b/StudyDoIT/Editor/ckfinder/help/es/files/010.html new file mode 100644 index 0000000..7d3ba44 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/010.html @@ -0,0 +1,23 @@ + + + + ++ La "Barra de Estado" es un pequeño espacio usado para mostrar información relevante al fichero seleccionado, el número total de ficheros en la carpeta, etc... Se puede encontrar al final de la interfaz de CKFinder
++ Si un fichero es seleccionado en CKFinder, la barra de estado mostrará información detallada acerca de ese fichero en particular, contendrá el nombre del fichero, su tamaño y la fecha de su última modificación, por ejemplo:
+
+
Si por el contrario ningún fichero está seleccionado, se mostrará el número total de ficheros en la carpeta actual. Por ejemplo:
+
+
+ CKFinder, incluyendo su documentación tiene Copyright © 2007-2011 por CKSource - Frederico Knabben. Todos los derechos reservados, por favor asegurse de leer y entender la licencia de uso. Licencia de CKFinder.
++ Los iconos usados en la barra de herramientas y los menús contextual, han sido diseñados por Mark James. +Por favor entre a la siguiente dirección (URL) para obtener más información: http://www.famfamfam.com/lab/icons/silk/
++ CKFinder, el logotipo de CKFinder, CKSource, CKEditor y FCKeditor son marcas registradas de CKSource - Frederico Knabben. All rights reserved (CKSource).
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/012.html b/StudyDoIT/Editor/ckfinder/help/es/files/012.html new file mode 100644 index 0000000..616565a --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/012.html @@ -0,0 +1,38 @@ + + + + ++ El "Menú contextual " es una serie de botones (llamados "menú") que pueden ser usados para ejecutar tareas específicas en el objeto que ha sido seleccionado con un click. Las opciones disponibles cambiarán dinamicamente dependiendo del objeto que haya sido seleccionado.
++ Los siguientes son los menús que podría encontrar mientras trabaja con una instalación estandar de CKFinder.
++ Aparece cuando hace click con el botón derecho del ratón sobre una carpeta en el Panel de carpetas
+
+
+ Aparece cuando hace click con el botón derecho del ratón sobre un fichero en el panel de Ficheros:
+
+
+ Aparece cuando hace click con el botón derecho del ratón en el Panel de ficheros , pero afuera de un fichero (en el fondo):
+
+ ![]()
+ CKFinder es una aplicación "Web", esto significa que está hecha para ser ejecutada dentro de un navegador siendo más fácil distribuir y usar en cualquier ordenador.
++ Actualmente cualquiera de los siguientes navegadores se requieren para ejecutar CKFinder:
+Algunas características dependen para su funcionamiento de ajustes propios del navegador de internet. Por defecto CKFinder debería funcionar correctamente, sin embargo si experimienta algún problema con el Menú contextual o quizá sus Ajustes no están siendo guardados, asegurese que su navegador está configurado para "Permitir a los scripts reemplazar menús contextuales" ("Permitir a los scripts recibir clicks con el botón derecho") y además tener habilitado el "Soporte para cookies".
+Por favor contacte a su administrador en caso de que tenga alguna duda.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/es/files/header.html b/StudyDoIT/Editor/ckfinder/help/es/files/header.html new file mode 100644 index 0000000..d6d80d7 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/es/files/header.html @@ -0,0 +1,36 @@ + + + + +
+ + Guía del Usuario de CKFinder+ |
+ + Visite el sitio Web de CKFinder | +
+ Siéntase libre de para enviarnos sus sugerencias acerca de esta documentación. Estamos siempre dispuestos a mejorarla, para ofrecerle un mejor software cada dia.
++ Índice +
++ CKFinder on ryhmätyöohjelmisto, joka helpottaa tiedostojen ylläpitoa ja jakelua palvelimella.
++ Olet sitten vasta-alkaja tai kokenut CKFinderin käyttäjä, + kannattaa silmäillä ohjeet lävitse. Aina voi löytyä uutta opittavaa, + vaikka ohjelma onkin yksinkertainen, mutta tehokas. +
++ Katso Juridiset huomautukset. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/002.html b/StudyDoIT/Editor/ckfinder/help/fi/files/002.html new file mode 100644 index 0000000..fd3aa55 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/002.html @@ -0,0 +1,33 @@ + + + ++ CKFinderin käyttöliittymä on suunniteltu selkeäksi ja helposti opittavaksi. + Useimpia toimintoja voidaan käyttää hiiren ja pikavalikon avulla. +
++ Kuvaruutukaappaus CKFinderista: +
+
+
+
+ Kansioiden muodostama puurakenne, jossa voidaan liikkua. + Kansioiden avulla järjestellään tiedostoja.
++ Rakennetta kutsutaan puunäkymäksi, koska kansiot on esitetty hierarkkisesti kuten puun oksat. + Yleisilme vastaa modernien graafisten käyttöjärjestelmien tiedostoselainnäkymää.
+
+ Avataksesi kansion, eli näyttääksesi alikansiot, napsauta kansion edessä olevaa plusmerkkiä
+ (
). Jollei plusmerkkiä näy, kansio ei sisällä alikansioita.
+
+ Katso "Kutsusta lataaminen" alempana tällä sivulla ymmärtääksesi, kuinka kansioiden lataaminen toimii. +
+
+ Paina kansion edessä näkyvää miinusmerkkiä sulkeaksesi kansion
+ (
).
+
+ Valitaksesi kansion, napsauta kansionimeä tai -kuvaketta. Valitun kansion taustaväri muuttuu. +
++ Kansion edityneempiin toimintoihin pääset "pikavalikosta". + Tarjolla on seuraavat valinnat: +
+
+
+ Huom: Jotkin pikavalikon valinnat voivat olla kytkettynä pois, + mikäli pääkäyttäjä on näin valinnut. +
++ Luodaksesi alikansion, napsauta "Uusi alikansio" -valintaa pikavalikossa. + Valintaruutu ilmestyy kysyen lisättävän kansion nimeä. Kirjoita ja vahvista nimi. +
++ Kansio- ja tiedostonimissä ei voi käyttää kaikkia merkkejä. Tämä on + käyttöjärjestelmäkohtaista. Esim. : + \ / : * + ? " < + > |
+ ++ Uudelleennimetäksesi kansion, napsauta "Uudelleennimeä"-valintaa pikavalikossa. + Ilmestyy valintaikkuna, jossa näkyy kansion nykyinen nimi. Kirjoita uusi nimi + ja vahvista valinta. +
++ Kansio- ja tiedostonimissä ei voi käyttää kaikkia merkkejä. Tämä on + käyttöjärjestelmäkohtaista. Esim. : + \ / : * + ? " < + > |
++ Huom: Kun uudelleennimeät kansion, linkin tai mediatiedoston, + jota käytetään jollain toisellakin sivulla, toisen sivun linkit rikkoontuvat. Ole siis + varovainen toimenpiteen suhteen.
++ Poistaaksesi kansion sisältöineen, napsauta "Poista" pikavalikossa. Näkyviin ilmestyy + ikkuna, jossa kysytään varmistusta toimenpiteelle. +
++ Huom: Kun poistat kansion, linkin tai mediatiedoston, + jota käytetään jollain toisellakin sivulla, toisen sivun linkit rikkoontuvat. Ole siis + varovainen toimenpiteen suhteen.
++ CKFinderissa kansioiden sisältö ladataan "kutsusta" toisin kuin paikallisia + kansioita selattaessa. Ts. aluksi ladataan vain puurakenteen näkyvät kansiot, + ja vasta avattaessa kansiota ladataan alikansiot ja tiedostot näkyviin. Tämä + on tavallista nettisovellusten suhteen. +
++ Kansioiden latautumisen havaitset ilmoituksesta "Lataan...": +
+
+
+ Ilmoitus katoaa automaattisesti kansion lataannuttua. Ensimmäisen latauskerran + jälkeen ilmoituksen ei pitäisi uudelleen ilmestyä samalle kansiolle. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/004.html b/StudyDoIT/Editor/ckfinder/help/fi/files/004.html new file mode 100644 index 0000000..c17ef1f --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/004.html @@ -0,0 +1,100 @@ + + + ++ Tiedostoruutu listaa kansiossa sijaitsevat tiedostot.
++ Tiedostoruutu voidaan esittää kahdella eri tavalla, riippuen CKFinderin asetuksista (katso + "Asetukset"). Ohessa vertailu "Esikatselukuva" + ja "Luettelo" -näkymästä samalle kansiolle:
+
+
+
+
+
+ Napsauta tiedostoa valitaksesi sen. Kun osoitin on tiedoston päällä, tiedostoalue + muuttaa väriään. Valitun tiedoston taustan väri muuttuu, yleensä siniseksi. +
++ Tiedoston edistyneempiin toimintoihin pääset "pikavalikosta". + Seuraavat toiminnot ovat valittavissa: +
+
+
+
+ Huom: Jotkin pikavalikon valinnat voivat olla kytkettynä pois, + mikäli pääkäyttäjä on näin valinnut. +
++ Valitse tiedosto napsauttamalla "Valitse"-toimintoa.
++ Napsauta "Näytä" esikatselleksallesi tiedosta selaimessa. Kaikentyyppisiä tiedostoja + ei voida näyttää selaimessa, mutta kuvat, teksti ja PDF-tiedostot (Adobe Portable Document Format) + voidaan. Muissa tapauksissa selain kysyy, millä sovelluksella haluat tiedoston avata.
++ Ladataksesi tiedoston, napsauta "Lataa"-nappia. Selain pyytää esittämään paikallisen kansion, + johon haluat tiedoston ladata.
++ Napsauta "Uudelleennimeä"-nappia pikavalikosta antaaksesi tiedostolle uuden nimen. + Näkyviin ilmestyy ikkuna, joss lukee tiedoston nykyinen nimi. Anna uusi nimi ja kuittaa. +
++ Kansio- ja tiedostonimissä ei voi käyttää kaikkia merkkejä. Tämä on + käyttöjärjestelmäkohtaista. Esim. : + \ / : * + ? " < + > |
++ Huom: Kun uudelleennimeät kansion, linkin tai mediatiedoston, + jota käytetään jollain toisellakin sivulla, toisen sivun linkit rikkoontuvat. Ole siis + varovainen toimenpiteen suhteen.
++ Poistaaksesi tiedoston, napsauta "Poista" pikavalikossa. Näkyviin ilmestyy + ikkuna, jossa kysytään varmistusta toimenpiteelle. +
++ Huom: Kun poistat kansion, linkin tai mediatiedoston, + jota käytetään jollain toisellakin sivulla, toisen sivun linkit rikkoontuvat. Ole siis + varovainen toimenpiteen suhteen.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/005.html b/StudyDoIT/Editor/ckfinder/help/fi/files/005.html new file mode 100644 index 0000000..85e33d2 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/005.html @@ -0,0 +1,34 @@ + + + ++ CKFinderin yläreunassa sijaitseva työkalurivi koostuu napeista, joita napsauttamalla + käynnistetään eri toimintoja. + Tässä kuvaruutukaappaus työkalurivistä: +
+
+
+
+ Alla vakiotyökalurivin napit listattuna:
++ Lataa palvelimelle -nappi* työkalurivillä avaa + "Lataa palvelimelle" -ruudun, jonka avulla lisätään uusia tiedostoja valittuun kansioon. + Tässä kuvaruutukaappaus:
+
+
+ Napsauta "Peru"-nappia sulkeaksesi ruudun, tai napsauta uudelleen "Lataa palvelimelle"-nappia + työkalurivillä.
++ * "Lataa palvelimelle" -termi tarkoittaa tiedoston siirtämistä paikalliselta + tietokoneelta palvelimelle.
++ Voit nähdä seuraavia viestejä lataustapahtuman aikana:
++ Viesti tarkoittaa, että samanniminen kuin lataamasi tiedosto on jo tallennettu hakemistoon. + Ristiriidan estämiseksi tiedostonimen perään lisätään juokseva numero "(1)".
++ Palvelin ei hyväksy ladattavaa tiedostoa. + Yleensä kysymys on siitä, että CKFinder on asetettu estämään tiettyjen tiedostotyyppien + lataaminen. Ne tunnistetaan tiedostotarkenteen perusteella. Lataaminen + estetään tietoturvasyistä. Vaihtoehtoisesti tiedostokoko voi olla liian suuri. Siinä + tapauksessa palvelin on konfiguroitava hyväksymään isompia tiedostoja. +
+Ladattava tiedosto sisältää HTML-koodia. Tietoturvasyistä vain määrätyillä tiedostotarkenteilla + varustetut tiedostot saavat sisältää HTML-koodia. + + Ota yhteyttä pääkäyttäjään selvittääksesi, mitkä ovat hyväksyttäjä tiedostotyyppejä, ja mikä + on niiden suurin sallittu koko.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/007.html b/StudyDoIT/Editor/ckfinder/help/fi/files/007.html new file mode 100644 index 0000000..c6b1337 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/007.html @@ -0,0 +1,25 @@ + + + ++ Jaetussa ohjelmistoympäristössä, kuten CKFinder, voi työskennellä + useita käyttäjiä yhtä aikaa. Tällöin yhteisessä kansiossa oleviin tiedostoihin voi tulla + lähes samanaikaisia muutoksia. Saat muutokset näkyviin "Päivitä"-toiminnolla.
+
+
+ Oletetaan, että luot uuden sivun yrityksenne tuliterälle tuotteelle. Avaat CKFinderin + ladataksesi tuotekuvan tekemällesi sivulle. Mutta avatessasi "Tuotteet"-kansiota, kuvaa + ei löydykään. Pirautat "Maikille", ja ihmettelet, mihin kuvat ovat kadonneet. Maikki + pyytää odottamaan tovin ja lataa kuvan palvelimelle. Sitten hän kehottaa sinua + päivittämään kansiorakenteesi. Ja voila! Siellähän kuva näkyykin. + + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/008.html b/StudyDoIT/Editor/ckfinder/help/fi/files/008.html new file mode 100644 index 0000000..cef11cc --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/008.html @@ -0,0 +1,69 @@ + + +
++ "Asetukset"-nappi työkalurivillä avaa "Asetusruudun", + jossa voit konfiguroida ja muokata CKFinderia. Tässä kuvaruutukaappaus: +
+
+ 
+ Kaikki asetukset tallennetaan hyödyntäen selaimen evästeitä (cookies). + Evästeet, "keksit", ovat pieniä tiedostoja, jotka sisältävät käyttäjäkohtaisia + konfigurointiasetuksia. Kullekin sivustolle on oma evästeensä.
++ Napsauta "Sulje"-nappia tai "Asetukset"-nappia toistamiseen sulkeaksesi asetusruudun.
++ Kaikki konfigurointivalinnat liittyvät tiedostoruutuun. + Niitä käytetään tietoruudun informaation esittämistavan valitaan. Tiedostoruutu reagoi + välittömästi asetusmuutoksiin.
++ Hallinnoi näkymätyypin valintaa tiedostoruudussa:
++ Asettaa näytettävän informaation määrän tiedostoruudulle. Esimerkkinä näytetään alla + vaihtoehdot eri informaatiomäärävalinnoilla:
++
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ Asettaa järjestyksen, jossa tiedostot näytetään: aakkosjärjestyksessä tiedostonimien + perusteella, tiedoston luontipäivämäärän mukaan (uusimmat ensin) tai tiedostokoon + mukaisesti.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/009.html b/StudyDoIT/Editor/ckfinder/help/fi/files/009.html new file mode 100644 index 0000000..e530ba0 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/009.html @@ -0,0 +1,15 @@ + + + ++ Avaa käyttöohjeen uuteen ikkunaan.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/010.html b/StudyDoIT/Editor/ckfinder/help/fi/files/010.html new file mode 100644 index 0000000..bfca3a0 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/010.html @@ -0,0 +1,28 @@ + + + ++ "Tilariviltä" ilmenee tietoja valitusta tiedostosta, tiedostojen lukumäärä + kansiossa, jne. +
++ Jos tiedosto on valittuna CKFinderissa tilarivi näyttää + tiedoston yksityiskohtaiset tiedot: tiedostonimi, -koko ja viimeisin + muokkauspäivämäärä. Esimerkiksi:
+
+
+ Jos tiedostoja ei ole valittuna, näytetään valitussa + kansiossa olevien tiedostojen lukumäärä. Esimerkiksi:
+
+
+ CKFinderin, ja tämän dokumentaation, tekijänoikeudet omistaa © 2007-2011 CKSource - Frederico Knabben. + Kaikki oikeudet pidätetään. + Varmistu, että olet lukenut ja ymmärtänyt CKFinder-käyttöoikeussopimuksen. +
+
+ Mark James on suunnitellut työkalurivin ja pikavalikon kuvakkeet.
+ Tutustu seuraavaan sivuun lisätietoja saadaksesi:
+ http://www.famfamfam.com/lab/icons/silk/
+ CKFinder, CKFinderin logo, CKSource, CKEditor ja FCKeditor ovat + CKSource - Frederico Knabben omistamia tuotemerkkejä. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/012.html b/StudyDoIT/Editor/ckfinder/help/fi/files/012.html new file mode 100644 index 0000000..9154a10 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/012.html @@ -0,0 +1,43 @@ + + + ++ "Pikavalikko" koostuu napeista (valikkorivit), joilla käynnistetään pikavalikon + kohteeseen liittyviä toimintoja. Näkyvät toiminnot vaihtuvat valitun kohteen + mukaisesti.
++ Seuraavat valikot löydät vakio-CKFinder-asennuksesta. +
++ Valikko ilmestyy, kun napsautat kansiota hakemistoruudussa + hiiren oikealla näppäimellä:
+
+
+ Valikko ilmestyy, kun napsautat tiedostoa tiedostoruudussa + hiiren oikealla näppäimellä:
+
+
+ Valikko ilmestyy, kun napsautat tiedostoruudussa, mutta + tiedostonimen vieressä (taustaa) hiiren oikealla näppäimellä:
+
+ 
+ CKFinder on "nettisovellus", jota siis käytetään selaimella. + Siksi sitä on helppo käyttää koneella kuin koneella + käyttöjärjestelmästä riippumatta.
++ Nykyisellään CKFinder toimii seuraavien selaimien kanssa: +
+ Eräät ominaisuudet riippuvat selaimesi asetuksista. Selaimesi pitäisi toimia oletusasetusilla + CKFinderin kanssa. Jos ongelmia ilmenee pikavalikon käyttämisessä + tai asetuksien tallentamisen kanssa, varmistu, että selaimesi + "sallii pikavalikon muokkaamisen skriptien avulla" + ("salli skriptien vastaanottaa hiiren oikean näppäimen napsautus"). Varmistu, että olet + sallinut "evästeiden käyttämisen".
++ Ota yhteyttä pääkäyttäjään, jos epäilet asetusten toimivuutta.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/header.html b/StudyDoIT/Editor/ckfinder/help/fi/files/header.html new file mode 100644 index 0000000..dfcd876 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/header.html @@ -0,0 +1,32 @@ + + + +
+ + CKFinder käyttöohje+ |
+ + Poikkea CKFinderin kotisivulla | +
+ Lähetä ehdotuksesi dokumentaation kehittämiseksi. + Parannamme mielellämme sovelluksiamme ja niiden käyttöohjeita.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/fi/files/toc.html b/StudyDoIT/Editor/ckfinder/help/fi/files/toc.html new file mode 100644 index 0000000..6c80ff2 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/fi/files/toc.html @@ -0,0 +1,90 @@ + + + ++ Sisällysluettelo +
++ CKFinder to narzędzie pracy grupowej, które umożliwia współdzielenie i ułatwia zarządzanie + plikami umieszczonymi na centralnym komputerze (serwerze).
++ Niezależnie od tego czy jesteś nowym czy też doświadczonym użytkownikiem, warto powięcić + chwilkę uwagi na przeglądnięcie dokumentacji CKFindera, celem uzyskania pełnej wiedzy na temat + tego prostego, ale bardzo użytecznego oprogramowania.
++ Kliknij w link aby zapoznać sie z informacją o licencji i prawach autorskich. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/002.html b/StudyDoIT/Editor/ckfinder/help/pl/files/002.html new file mode 100644 index 0000000..9276f7f --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/002.html @@ -0,0 +1,45 @@ + + + ++ Interfejs użytkownika został zaprojektowany tak, aby był przejrzysty i intuicyjny + nawet dla nowych użytkowników. Większość dostepnych komend jest łatwo dostępna przy uzyciu menu kontekstowego myszy + i może zostać wykonana jednym kliknięciem. +
++ Poniżej przykładowy zrzut z ekranu przedstawiający CKFindera: +
+
+
+
+ W oknie z katalogami wyświetlone są katalogi w postaci drzewa, które służą do nawigacji + po strukturze katalogów. Katalogi służą do lepszego zorganizowania plików. +
+
+ Ażeby otworzyć folder, i tym samy zobaczyć jego podfoldery, kliknij w znak "plus"
+ (
) umieszczony przed nazwą folderu.
+ Jeżli znak plus nie jest widoczny, oznacza to że folder nie zawiera podrzędnych katalogów.
+
+ Spójrz na skecję "Ładowanie na żądanie" w dolnej partii tej strony, ażeby zrozumieć + w jaki sposób katalogi są załadowywane. +
+
+ Żeby zamknąć katalog i schować podrzędne katalogi, kliknij w znak "minus" (
) znajdujący się z przodu nazwy katalogu.
+
+ W celu zaznaczenia katalogu w CKFinderze, kliknij na nazwe katalogu albo na jego ikonkę. + Zaznaczony katalog będzie miał inny kolor tła. +
++ Inne bardziej zaawansowane operacje na folderach mogą zostać wykonane przy użyciu + "menu kontekstowego". + Następujące operacje są dostępne: +
+
+
+
+ Wskazówka: + Pewne operacje mogą być niedostępne, w zależności od ustawień + przydzielonych przez administratora. +
++ Ażeby utworzyć pokatalog wewnątrz bieżącego katalogu, kliknij na opcję "Nowy Podkatalog" + dostepna w menu kontekstowym. Po kliknięciu pojawi się okno dialogowe z pytaniem o nazwę katalogu. + Po prostu wpisz nazwę katalogu i potwierdź. +
++ Nie wszystkie znaki mogą być użyte w nazwach plików i katalogów z powodu ograniczeń + systemów operacyjnych, na których CKFinder może zostać uruchomiony. Przykładowo, następujące znaki + nie moga zostać użyte w nazwach plików/katalogów: + \ + / + : + * + ? + " + < + > + | +
++ Ażeby zmienić nazwę katalogu, kliknij opcję "Zmień nazwę" w menu kontekstowym. + Po kliknięciu pojawi się okno dialogowe, zawierające obecną nazwę katalogu. + Wpisz nową nazwe i potwierdź. +
++ Nie wszystkie znaki mogą być użyte w nazwach plików i katalogów z powodu ograniczeń + systemów operacyjnych, na których CKFinder może zostać uruchomiony. Przykładowo, następujące znaki + nie moga zostać użyte w nazwach plików/katalogów:\ + / + : + * + ? + " + < + > + | +
++ Uwaga: + zmieniając nazwę folderu, odnośniki do plików w nim zawartych + przestaną być "prawidłowe", tym samym strony internetowe zawierające pliki z tego folderu nie + będą wyświetlać poprawnej zawartości. Z tego powodu zalecamy ostrożność przy korzystaniu z tej możliwości. +
++ Ażeby skasować katalog wraz z zawartością, kliknij opcję "Usuń" w menu kontekstowym. + Przed usunięciem CKFinder poprosi Cię o potwierdzenie operacji. +
++ Uwaga: + po usunięciu katalogu, odnośniki do plików w nim zawartych + przestaną być "prawidłowe", tym samym strony internetowe zawierające pliki z tego folderu nie + będą wyświetlać poprawnej zawartości. Z tego powodu zalecamy ostrożność przy korzystaniu z tej możliwości. +
++ The most important difference between CKFinder and the folders tree found in operating + systems, is that, in CKFinder, the folders are loaded "under request". It means + that it doesn't load the entire folders tree at startup, but loads a small subset + of them when "opening" the folder. This is a requirement on advanced web applications + like CKFinder. +
++ To indicate that folders are being loaded, the "Loading..." label may appear when + opening a folder: +
+
+
+
+ The label will automatically disappear once the folders load is completed. Once + loaded, the label should not appear anymore for that folder. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/004.html b/StudyDoIT/Editor/ckfinder/help/pl/files/004.html new file mode 100644 index 0000000..c63327f --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/004.html @@ -0,0 +1,115 @@ + + + ++ Okno z plikami wyświetla wszystkie dostępne pliki w wybranym katalogu. +
++ Pliki mogą być wyświetlane na dwa sposoby, w zależności od ustawień CKFindera + (zobacz + "Ustawienia"). Poniżej przedstawiono porównanie wyświetlania w postaci "Miniaturek" + oraz "Listy" w tym samym folderze:
+
+
+
+
+
+ Aby zaznaczyć plik w CKFinderze, kliknij w plik. Żeby łatwo odróżnić, kiedy mysz + znajduje się nad plikiem, tło pliku zmieni się kiedy przesuniesz nad nim myszkę. + Po zaznaczeniu pliku, kolor tła wybranego pliku będzie się odróżniał od pozostałych plików (najczęściej będzie to kolor niebieski). +
++ Zaawansowane operacje można wykonać przy użyciu "menu kontekstowego". + Następujące operacje są dostępne: +
+
+
+
+ Wskazówka: niektóre opcje w menu kontekstowym mogą zostać + zablokowane przez administratora systemu, wówczas będa one nieaktywne. +
++ W celu wybrania pliku i zwrócenia go do nadrzędnej aplikacji, kliknij przycisk "Wybierz". +
++ Ażeby podejrzeć plik, kliknij opcję "Zobacz" w menu kontekstowym. + Chociaż nie wszystkie rodzaje plików można obejrzeć w przeglądarce, opcja ta może być przydatna + w przypadku plików tekstowych, obrazków czy plików PDF. + W pozostałych przypadkach przeglądarka poprosi Cię o wybranie odpowiedniej aplikacji + do obejrzenia pliku. +
++ W celu pobrania pliku, kliknij "Pobierz" w menu kontekstowym. + Przeglądarka następnie spyta się o miejsce zapisania pliku na Twoim komputerze. +
++ Żeby zmienić nazwę pliku, wybierz opcję "Zmień nazwę" w menu kontekstowym. + Pojawi się okno dialogowe zawierające nazwę obecnego pliku z pytaniem o nową nazwę. + Wpisz nową nazwę i potwierdź. +
++ Nie wszystkie znaki mogą być użyte w nazwach plików i katalogów z powodu ograniczeń + systemów operacyjnych, na których CKFinder może zostać uruchomiony. Przykładowo, następujące znaki + nie moga zostać użyte w nazwach plików/katalogów:\ / : + * ? " < + > | +
++ Uwaga: zmieniając nazwę pliku, odnośniki do niego + przestaną być "prawidłowe", a tym samym strony internetowe zawierające link do tego pliku nie + będą wyświetlać poprawnej zawartości. + Z tego powodu zalecamy ostrożność przy korzystaniu z tej możliwości. +
++ Ażeby skasować plik, kliknij opcję "Usuń" w menu kontekstowym. + CKFinder spyta Ciebie o potwierdzenie przed usunięciem pliku, ażeby się upewnić + czy plik na pewno ma być skasowany. +
++ Uwaga: kasując plik, odnośniki do niego + przestaną być "prawidłowe", a tym samym strony internetowe zawierające link do tego pliku nie + będą wyświetlać poprawnej zawartości. + Z tego powodu zalecamy ostrożność przy korzystaniu z tej możliwości. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/005.html b/StudyDoIT/Editor/ckfinder/help/pl/files/005.html new file mode 100644 index 0000000..a509c25 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/005.html @@ -0,0 +1,34 @@ + + + ++ Pasek narzędzi to specjalne miejsce na samej górze interfejsu użytkownika CKFindera. + Zawiera on zestaw przycisków, które należy kliknąć aby wykonać wybraną akcję. + Poniżej przykładowy zrzut ekranu: +
+
+
+
+ Poniżej przedstawiona została lista przycisków dostępnych w CKFinderze:
++ Przycisk wyślij* umieszczony w pasku narzędzi, otwiera + okno do wysyłania plików, które służy do dodawania nowych plików do otwartego + w danym momencie katalogu. + Poniżej przykładowy zrzut ekranu:
+
+
+ W celu zamknięcia okna, kliknij na przycisk "Anuluj" albo kliknij ponownie przycisk "Wyślij" + w pasku narzędzi. +
++ * "wysyłanie" pliku to inaczej transfer pliku z Twojego komputera (lokalnego) + do komputera centralnego, na którym uruchomiony jest CKFinder (serwera).
++ Nstępujące komunikaty mogą zostać wyświetlone po wysłaniu pliku:
++ Oznacza to, że plik o danej nazwie już istnieje w danym katalogu. + W celu uniknięcia konfliktu, kolejny numer porządkowy został dodany do oryginalnej nazwy pliku "(1)". +
++ Wysłany plik nie został zaakceptowany. +
++ Najczęstszym powodem, jest takie skonfigurowanie CKFindera przez administratora, + aby zezwalać na pliki tylko z wybranymi rozszerzeniami. + Rozwiązanie to ma na celu zabezpieczenie serwera przed wysłaniem niedozwolonych plików. + Innym powodem może być przekroczenie dozwolonego rozmiaru pliku wysłanego na serwer. + W takim wypadku, serwer powinien zostać tak skonfigurowany przez administratora, aby dopuszczał pliki o większych rozmiarach. +
+Przesłany plik zawiera kod HTML. Z powodów bezpieczeństwa, tylko pliki z wybranymi rozszerzeniami mogą zawierać kod HTML. +
++ Prosimy o kontakt z administratorem w celu uzyskania informacji plików, które są akceptowane przez CKFindera + oraz dopuszczalnego limitu rozmiaru pojedynczego pliku.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/007.html b/StudyDoIT/Editor/ckfinder/help/pl/files/007.html new file mode 100644 index 0000000..8bb2dac --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/007.html @@ -0,0 +1,33 @@ + + + ++ Podczas pracy w środowisku współdzielonym, takim jak CKFinder, gdzie dziesiątki a nawet setki użytkowników pracują + nad tymi samymi plikami, może się zdarzyć, że nastepują zmiany w folderze, w kórym aktualnie pracujesz. + W celu przeładowania listy plików, kliknij po prostu przycik "Odśwież". +
+
+
+ Załóżmy dla przykładu, że musisz utworzyć stronę nowego produktu Twojej firmy. + Wchodzisz do CKFindera, żeby pobrać obrazek, który umieścisz na stronie, ale + w folderze "Produkty" nie możesz odnaleźć żadnego obrazka. + Dzwonisz do "Kasi", z informacją, że potrzebujesz obrazka: + - "Hej, potrzebuję tego zdjęcia, o którym wczoraj dyskutowaliśmy, ale + nie mogę go nigdzie znaleźć w CKFinderze!" + - "Ups.. minutkę" - Kasia otwiera CKFindera na swoim komputerze, wysyła do niego swój plik + i mówi Ci przez telefon, żebyś odświeżył sobie listę plików. + Klikasz i... gotowe! Plik pojawił się i jest gotowy do użycia. + Na tym przykładzie widać, czemu CKFinder jest tzw. narzędziem pracy grupowej. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/008.html b/StudyDoIT/Editor/ckfinder/help/pl/files/008.html new file mode 100644 index 0000000..61f64c8 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/008.html @@ -0,0 +1,76 @@ + + + ++ Przycisk "Ustawienia", w pasku narzędzi, otwiera "okienko z ustawieniami", + gdzie można skonfigurować i dostosować ustawienia CKFindera, tak jak na poniższym zrzucie ekranu: +
+
+ 
+ Wszystkie ustawienia są automatycznie zapisywane używając "ciasteczek" (cookies). + Ciasteczka to małe pliki zawierające prywatne informacje dla poszczególnych stron internetowych. +
++ W celu zamknięcia okienka z ustawieniami, kliknij przycisk "Zamknij" albo kliknij ponownie w przycisk + "Ustawienia" w pasku narzędzi. +
++ Wszystkie opcje konfiguracyjne powiązane są z oknem plików. + Są one używane do kontroli, w jaki sposób informacje zostaną w nim wyświetlone. +
++ Kontroluje sposób wyświetlania plików w oknie plików:
++ Służy do ustawienia ilości informacji dostępnej w oknie plików. Dla przykładu, poniżej zamieszczono + zrzut ekranu ustawień, gdzie żadna z opcji nie została wybrana aż do momentu, w którym wybrane zostały wszystkie opcje: +
++
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ ![]() |
+
+ Służy do kontroli według jakiego porządku pliki zostaną wyświetlone. + Dostępne opcje to: alfabetyczne sortowanie według nazwy, według daty utworzenia + a także według rozmiaru pliku. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/009.html b/StudyDoIT/Editor/ckfinder/help/pl/files/009.html new file mode 100644 index 0000000..2895e15 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/009.html @@ -0,0 +1,16 @@ + + + ++ Otwiera "Podręcznik Użytkownika" w nowym oknie.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/010.html b/StudyDoIT/Editor/ckfinder/help/pl/files/010.html new file mode 100644 index 0000000..6d64338 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/010.html @@ -0,0 +1,30 @@ + + + ++ "Pasek statusu" to niewielka przestrzeń używana w celu wyświetlenia informacji + odnośnie wybranego pliku, łącznej ilości plików w folderze itd. + Można go znaleźć na samym dole CKFindera. +
++ Po zaznaczeniu pliku w CKFinderze, pasek statusu wyświetli szczegółową informację + o tym pliku, zawierającą m.in. jego nazwę, wielkość oraz datę modyfikacji. Na przykład: +
+
+
+ Jeśli żaden plik nie został zaznaczony, łączna ilość plików w katalogu zostanie wyświetlona. + Na przykład:
+
+
+ CKFinder, wraz z dokumentacją, jest własnością © 2007-2011 CKSource - Frederico Knabben. Wszelkie prawa zastrzeżone. + Przed skorzystaniem, upewnij się, że przeczytałeś i zrozumiałeś licencję +
++ Ikonki użyte w pasku narzędzi oraz menu kontekstowym zostały zaprojektowane przez Marka Jamesa. + Więcej informacji dostępne jest pod tym adresem:http://www.famfamfam.com/lab/icons/silk/
++ CKFinder, Logo CKFinder, CKSource, CKEditor oraz FCKeditor są znakami towarowymi CKSource - Frederico Knabben.
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/012.html b/StudyDoIT/Editor/ckfinder/help/pl/files/012.html new file mode 100644 index 0000000..4367b2c --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/012.html @@ -0,0 +1,45 @@ + + + ++ "Menu kontekstowe" to zestaw pozycji dostępnych po kliknięciu na wybrany obiekt prawym klawiszem myszy. + Służy ono do wykonywania operacji specyficznych dla danego obiektu. + Dostępne operacje zmieniają się w zależności od tego, co zostało wybrane. +
++ Poniżej przedstawione zostały dostępne rodzaje menu, które mogą pojawić się podczas pracy z CKFinderem. +
++ Pojawia się po kliknięciu w folder w oknie katalogów, + przy użyciu prawego klawisza myszy: +
+
+ Pojawia się po kliknięciu w folder w oknie plików, + przy użyciu prawego klawisza myszy: +
+
+ Pojawia się po kliknięciu w pustą przestrzeń w oknie plików, + poza dostępnymi plikami (po kliknięciu w tło), przy użyciu prawego klawisza myszy: +
+ ![]()
+ CKFinder jest aplikacją internetową. Oznacza to, że został stworzony aby pracować + w przeglądarkach internetowych co sprawia, że łatwo go używać w każdej sytuacji, pod warunkiem dostępu + do jakiejkolwiek z przeglądarek. +
++ Obecnie następujące przeglądarki są poprawnie obsługiwane przez CKFindera:
++ Niektóre funkcjonalności są zależne od ustawień Twojej przegladarki. + CKFinder powinien generalnie współpracować z każdą przeglądarką z domyślnymi ustawieniami, jeżeli jednak + występują problemy z menu kontekstowym lub ustawienia + nie są zapisywane poprawnie, upewnij się, że Twoja przeglądarka zezwala skryptom javascript na "blokowanie lub wyłączenie menu kontekstowego" + oraz, że Twoja przeglądarka akceptuje "ciasteczka" (cookies). +
++ Skontaktuj się z administratorem Twojego systemu w razie problemów. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/header.html b/StudyDoIT/Editor/ckfinder/help/pl/files/header.html new file mode 100644 index 0000000..db03854 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/header.html @@ -0,0 +1,33 @@ + + + +
+ + CKFinder - Podręcznik Użytkownika+ |
+ + Odwiedź stronę www CKFinder-a. | +
+ Jeśli masz jakiekolwiek sugestie odnośnie dokumentacji, prześlij nam swoją opinię. + Naszym celem jest dostarczanie oprogramowania dającego satysfakcję wszystkim użytkownikom każdego dnia. +
+ + diff --git a/StudyDoIT/Editor/ckfinder/help/pl/files/toc.html b/StudyDoIT/Editor/ckfinder/help/pl/files/toc.html new file mode 100644 index 0000000..317e1e8 --- /dev/null +++ b/StudyDoIT/Editor/ckfinder/help/pl/files/toc.html @@ -0,0 +1,91 @@ + + + ++ Spis treści +
+@item.Description
+ @*Per ea tibique fabellas electram. Ea aliquam corpora vis. Ne quot civibus atomorum quo.
*@ + Read more +Cuộc sống dù đi chậm vẫn cứ phải bước đi chứ không được dừng lại!
+ @*+ Sed lacinia, nibh sit amet auctor vestibulum, enim risus condimentum erat, quis vestibulum mi ligula a nulla. Nulla vitae pharetra tellus. + Aenean ac tincidunt augue, volutpat ullamcorper elit. +
*@ +@item.Contents
+© 2015.by Như Vịt
+update SomeTable
+ set ComplexTypeColumn.SomeProperty()
+ where Id = 2
+ Database.SetInitializer<TTransactionContext>(null) where TTransactionContext is the type of the resolved context.
+ min(random(1, 1.1) * (2 ^ retryCount - 1), maxDelay)
+ The true which means that EF will continue with the assumption
+ that the provider has the necessary types/resources rather than failing fast.
+ /*...*/ containing the specified text.
+
+
+
+ /*...*/ containing the specified text.
+ /*...*/ containing the specified text.
+
+
+
+
+
+
+ /*...*/ containing the specified text.
+
+
+
+ Info will exclude Verbose messages and include Info,
+ Warning and Error messages.
+
+
+ Info will exclude Verbose messages and include Info,
+ Warning and Error messages.
+ Info will exclude Verbose messages and include Info,
+ Warning and Error messages.
+