diff --git a/.gitignore b/.gitignore index a6e99c5..67fa262 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ packages/ *.user TestResults/ */App_Data/ -*.suo \ No newline at end of file +*.suo +.vs diff --git a/.vs/CalDav/config/applicationhost.config b/.vs/CalDav/config/applicationhost.config new file mode 100644 index 0000000..c54b7dd --- /dev/null +++ b/.vs/CalDav/config/applicationhost.config @@ -0,0 +1,1037 @@ + + + + + + + + +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+ + +
+
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.vs/VSWorkspaceState.json b/.vs/VSWorkspaceState.json new file mode 100644 index 0000000..7f3f169 --- /dev/null +++ b/.vs/VSWorkspaceState.json @@ -0,0 +1,7 @@ +{ + "ExpandedNodes": [ + "" + ], + "SelectedNode": "\\CalDav.sln (CalDav.sln)", + "PreviewInSolutionExplorer": false +} \ No newline at end of file diff --git a/.vs/slnx.sqlite b/.vs/slnx.sqlite new file mode 100644 index 0000000..0fc515c Binary files /dev/null and b/.vs/slnx.sqlite differ diff --git a/Backup/Demo.MVC.csproj b/Backup/Demo.MVC.csproj new file mode 100644 index 0000000..4c28463 --- /dev/null +++ b/Backup/Demo.MVC.csproj @@ -0,0 +1,174 @@ + + + + + Debug + AnyCPU + + + 2.0 + {9164611E-4CAF-4FE1-B707-397CC1D515C0} + {E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Demo.MVC + Demo.MVC + v4.0 + false + true + + + + + ..\ + true + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + ..\packages\EntityFramework.5.0.0\lib\net45\EntityFramework.dll + + + True + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + True + ..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.Helpers.dll + + + True + ..\packages\Microsoft.AspNet.Mvc.3.0.20105.1\lib\net40\System.Web.Mvc.dll + + + ..\packages\Microsoft.AspNet.Providers.Core.1.1\lib\net40\System.Web.Providers.dll + + + True + ..\packages\Microsoft.AspNet.Razor.1.0.20105.408\lib\net40\System.Web.Razor.dll + + + True + ..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.dll + + + True + ..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.Deployment.dll + + + True + ..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.Razor.dll + + + + + + Global.asax + + + + + + + + + + Web.config + + + Web.config + + + + + + + + + + + + + + + + + {471ea68f-fb1f-4df8-aac1-31022c7316ab} + CalDav.Server + + + {01a4c4cf-5ad1-4324-a391-dc922c84be1c} + CalDav + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + + + + True + True + 0 + / + http://localhost:59780/ + False + False + + + False + + + + + + + \ No newline at end of file diff --git a/Backup/Global.asax b/Backup/Global.asax new file mode 100644 index 0000000..eaaf9a9 --- /dev/null +++ b/Backup/Global.asax @@ -0,0 +1 @@ +<%@ Application Codebehind="Global.asax.cs" Inherits="Demo.MVC.MvcApplication" Language="C#" %> diff --git a/Backup/Global.asax.cs b/Backup/Global.asax.cs new file mode 100644 index 0000000..6549a0a --- /dev/null +++ b/Backup/Global.asax.cs @@ -0,0 +1,38 @@ +using System.Data.Entity; +using System.Data.Entity.Infrastructure; +using System.Web.Mvc; +using System.Web.Routing; + +namespace Demo.MVC { + // Note: For instructions on enabling IIS6 or IIS7 classic mode, + // visit http://go.microsoft.com/?LinkId=9394801 + + public class MvcApplication : System.Web.HttpApplication { + public static void RegisterGlobalFilters(GlobalFilterCollection filters) { + filters.Add(new HandleErrorAttribute()); + } + + public static void RegisterRoutes(RouteCollection routes) { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + CalDav.Server.Controllers.CalDavController.RegisterRoutes(routes); + + routes.MapRoute( + "Default", // Route name + "{controller}/{action}/{id}", // URL with parameters + new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults + ); + + + } + + protected void Application_Start() { + AreaRegistration.RegisterAllAreas(); + + // Use LocalDB for Entity Framework by default + Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True"); + + RegisterGlobalFilters(GlobalFilters.Filters); + RegisterRoutes(RouteTable.Routes); + } + } +} \ No newline at end of file diff --git a/Backup/Models/Calendar.cs b/Backup/Models/Calendar.cs new file mode 100644 index 0000000..c0a33a9 --- /dev/null +++ b/Backup/Models/Calendar.cs @@ -0,0 +1,59 @@ +using System; +using System.Linq; + +namespace CalDav.MVC.Models { + public class CalendarInfo : CalDav.Calendar, CalDav.Server.Models.ICalendarInfo { + public string Filename { get; set; } + public DateTime LastModified { + get { + return System.IO.File.GetLastWriteTimeUtc(Filename); + } + } + + private string this[string name] { + get { + name = name.ToUpper(); + if (!name.StartsWith("X-")) name = "X-" + name; + var prop = Properties.FirstOrDefault(x => x.Item1.Is(name)); + if (prop == null) return null; + return prop.Item2; + } + set { + name = name.ToUpper(); + if (!name.StartsWith("X-")) name = "X-" + name; + var newprop = Tuple.Create(name, value, (System.Collections.Specialized.NameValueCollection)null); + var prop = Properties.FirstOrDefault(x => x.Item1.Is(name)); + if (prop != null) Properties.Remove(prop); + Properties.Add(newprop); + } + } + + public string Name { + get { + return this["Name"]; + } + set { + this["Name"] = value; + } + } + + public string Description { + get { + return this["Description"]; + } + set { + this["Description"] = value; + } + } + + public string ID { + get { + return this["ID"]; + } + set { + this["ID"] = value; + } + } + + } +} \ No newline at end of file diff --git a/Backup/Models/CalendarRepository.cs b/Backup/Models/CalendarRepository.cs new file mode 100644 index 0000000..884468b --- /dev/null +++ b/Backup/Models/CalendarRepository.cs @@ -0,0 +1,127 @@ +using CalDav.Server.Models; +using System; +using System.Linq; +using System.Security.Principal; + +namespace CalDav.MVC.Models { + public class CalendarRepository : ICalendarRepository { + private string _Directory; + + public CalendarRepository(IPrincipal user) { + _Directory = System.IO.Path.Combine(System.Web.HttpRuntime.AppDomainAppPath, "App_Data\\Calendars"); + System.IO.Directory.CreateDirectory(_Directory); + } + + public IQueryable GetCalendars() { + var files = System.IO.Directory.GetDirectories(_Directory, "*.ical", System.IO.SearchOption.AllDirectories); + if (files.Length == 0) + return new[] { CreateCalendar("me") }.AsQueryable(); + + var serializer = new Serializer(); + return files.Select(x => { + using (var file = System.IO.File.OpenText(x)) { + var cal = new CalendarInfo(); + cal.Deserialize(file, serializer); + cal.Filename = x; + cal.ID = System.IO.Path.GetDirectoryName(x) + .Trim(System.IO.Path.DirectorySeparatorChar) + .Split(System.IO.Path.DirectorySeparatorChar) + .LastOrDefault(); + return cal; + } + }).Where(x => x != null).AsQueryable(); + } + + private static string MakePathSafe(string input) { + if (input == null) return null; + foreach (var c in System.IO.Path.GetInvalidFileNameChars()) + input = input.Replace(c, '_'); + return input.Trim('_'); + } + + public ICalendarInfo CreateCalendar(string id) { + if (string.IsNullOrEmpty(id)) return null; + id = MakePathSafe(id); + var filename = System.IO.Path.Combine(_Directory, id + "\\_.ical"); + var ical = new CalendarInfo(); + var serializer = new Serializer(); + System.IO.Directory.CreateDirectory(System.IO.Path.Combine(_Directory, id)); + using (var file = System.IO.File.OpenWrite(filename)) + serializer.Serialize(file, ical); + ical.Filename = filename; + return ical; + } + + public ICalendarInfo GetCalendarByID(string id) { + if (string.IsNullOrEmpty(id)) id = "me"; + id = MakePathSafe(id); + var filename = System.IO.Path.Combine(_Directory, id + "\\_.ical"); + if (!System.IO.File.Exists(filename)) { + if (id == "me") return CreateCalendar("me"); + return null; + } + + var calendar = new CalendarInfo(); + using (var file = System.IO.File.OpenText(filename)) { + calendar.Deserialize(file); + calendar.Filename = filename; + calendar.ID = id; + return calendar; + } + } + + public ICalendarObject GetObjectByUID(ICalendarInfo calendar, string uid) { + var filename = System.IO.Path.Combine(_Directory, calendar.ID, uid + ".ics"); + if (!System.IO.File.Exists(filename)) return null; + var serializer = new Serializer(); + using (var file = System.IO.File.OpenText(filename)) { + var ical = (serializer.Deserialize(file))[0]; + return ical.Events.OfType() + .Union(ical.ToDos) + .Union(ical.FreeBusy) + .Union(ical.JournalEntries) + .FirstOrDefault(); + } + } + + public void Save(ICalendarInfo calendar, ICalendarObject e) { + var filename = System.IO.Path.Combine(_Directory, calendar.ID, e.UID + ".ics"); + var ical = new CalDav.Calendar(); + ical.AddItem(e); + var serializer = new Serializer(); + using (var file = System.IO.File.Open(filename, System.IO.FileMode.Create)) + serializer.Serialize(file, ical); + } + + public IQueryable GetObjectsByFilter(ICalendarInfo calendar, Filter filter) { + throw new NotImplementedException(); + } + + public IQueryable GetObjects(ICalendarInfo calendar) { + if (calendar == null) return new ICalendarObject[0].AsQueryable(); + var directory = System.IO.Path.Combine(_Directory, calendar.ID); + var files = System.IO.Directory.GetFiles(directory, "*.ics"); + var serializer = new Serializer(); + return files + .SelectMany(x => serializer.Deserialize(x)) + .SelectMany(x => x.Items) + .AsQueryable(); + } + + public ICalendarObject GetObjectByPath(string path) { + var calendar = GetCalendarByID(path); + var uid = path.Split('/').Last().Split('.').FirstOrDefault(); + return GetObjectByUID(calendar, uid); + } + + public void DeleteObject(ICalendarInfo calendar, string path) { + var uid = path.Split('/').Last().Split('.').FirstOrDefault(); + var obj = GetObjectByUID(calendar, uid); + if (obj == null) return; + var filename = System.IO.Path.Combine(_Directory, calendar.ID, obj.UID + ".ics"); + if (!System.IO.File.Exists(filename)) + return; + System.IO.File.Delete(filename); + } + } +} \ No newline at end of file diff --git a/Backup/Properties/AssemblyInfo.cs b/Backup/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..b8035dd --- /dev/null +++ b/Backup/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Demo.MVC")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Demo.MVC")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("3fb7599d-a6a9-4202-99e5-d780f734cf9b")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Backup/Views/Shared/Error.cshtml b/Backup/Views/Shared/Error.cshtml new file mode 100644 index 0000000..7618dc4 --- /dev/null +++ b/Backup/Views/Shared/Error.cshtml @@ -0,0 +1,15 @@ +@{ + Layout = null; +} + + + + + Error + + +

+ Sorry, an error occurred while processing your request. +

+ + \ No newline at end of file diff --git a/Backup/Views/Shared/_Layout.cshtml b/Backup/Views/Shared/_Layout.cshtml new file mode 100644 index 0000000..73ddad9 --- /dev/null +++ b/Backup/Views/Shared/_Layout.cshtml @@ -0,0 +1,12 @@ + + + + @ViewBag.Title + + + + + + @RenderBody() + + diff --git a/Backup/Views/Web.config b/Backup/Views/Web.config new file mode 100644 index 0000000..a4def2a --- /dev/null +++ b/Backup/Views/Web.config @@ -0,0 +1,58 @@ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Backup/Views/_ViewStart.cshtml b/Backup/Views/_ViewStart.cshtml new file mode 100644 index 0000000..efda124 --- /dev/null +++ b/Backup/Views/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "~/Views/Shared/_Layout.cshtml"; +} \ No newline at end of file diff --git a/Backup/Web.Debug.config b/Backup/Web.Debug.config new file mode 100644 index 0000000..2c6dd51 --- /dev/null +++ b/Backup/Web.Debug.config @@ -0,0 +1,30 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Backup/Web.Release.config b/Backup/Web.Release.config new file mode 100644 index 0000000..4122d79 --- /dev/null +++ b/Backup/Web.Release.config @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/Backup/Web.config b/Backup/Web.config new file mode 100644 index 0000000..fa06dd1 --- /dev/null +++ b/Backup/Web.config @@ -0,0 +1,75 @@ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Backup/packages.config b/Backup/packages.config new file mode 100644 index 0000000..bb29542 --- /dev/null +++ b/Backup/packages.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CalCli.API/AlarmActions.cs b/CalCli.API/AlarmActions.cs new file mode 100644 index 0000000..0b2cb03 --- /dev/null +++ b/CalCli.API/AlarmActions.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CalCli.API +{ + public enum AlarmActions + { + NONE, + AUDIO, + DISPLAY, + EMAIL + } +} diff --git a/CalCli.API/CalCli.API.csproj b/CalCli.API/CalCli.API.csproj new file mode 100644 index 0000000..038a825 --- /dev/null +++ b/CalCli.API/CalCli.API.csproj @@ -0,0 +1,67 @@ + + + + + Debug + AnyCPU + {2C258FAE-97ED-4916-B5A3-4723700D675D} + Library + Properties + CalCli.API + CalCli.API + v4.8 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/CalCli.API/IAlarm.cs b/CalCli.API/IAlarm.cs new file mode 100644 index 0000000..ddb505a --- /dev/null +++ b/CalCli.API/IAlarm.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CalCli.API +{ + public interface IAlarm + { + AlarmActions Action { get; set; } + string Description { get; set; } + ITrigger Trigger { get; set; } + } +} diff --git a/CalCli.API/ICalendar.cs b/CalCli.API/ICalendar.cs new file mode 100644 index 0000000..07fa9e3 --- /dev/null +++ b/CalCli.API/ICalendar.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CalCli.API +{ + public interface ICalendar + { + string Name { get; set; } + string Description { get; set; } + void Save(IEvent e); + void Save(IToDo t); + IToDo createToDo(); + ITrigger createTrigger(); + IAlarm createAlarm(); + IEvent createEvent(); + } +} diff --git a/CalCli.API/IConnection.cs b/CalCli.API/IConnection.cs new file mode 100644 index 0000000..d4303f3 --- /dev/null +++ b/CalCli.API/IConnection.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Net; +using System.IO; + +namespace CalCli.API +{ + public interface IConnection + { + WebRequest Authorize(WebRequest request); + } +} diff --git a/CalCli.API/IEvent.cs b/CalCli.API/IEvent.cs new file mode 100644 index 0000000..11db4b7 --- /dev/null +++ b/CalCli.API/IEvent.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CalCli.API +{ + public interface IEvent + { + ICollection Alarms { get; set; } + ICollection Categories { get; set; } + DateTime? Created { get; set; } + string Description { get; set; } + DateTime? Start { get; set; } + DateTime? End { get; set; } + string Summary { get; set; } + string UID { get; set; } + Uri Url { get; set; } + } +} diff --git a/CalCli.API/IServer.cs b/CalCli.API/IServer.cs new file mode 100644 index 0000000..551f270 --- /dev/null +++ b/CalCli.API/IServer.cs @@ -0,0 +1,12 @@ +using System; + +namespace CalCli.API +{ + public interface IServer + { + Uri Url { get; set; } + IConnection Connection { get; set; } + ICalendar[] GetCalendars(); + void CreateCalendar(ICalendar calendar); + } +} diff --git a/CalCli.API/IToDo.cs b/CalCli.API/IToDo.cs new file mode 100644 index 0000000..3377ef2 --- /dev/null +++ b/CalCli.API/IToDo.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CalCli.API +{ + public interface IToDo + { + string UID { get; set; } + DateTime? Start { get; set; } + DateTime? Due { get; set; } + string Summary { get; set; } + ICollection Categories { get; set; } + int? Priority { get; set; } + int? Sequence { get; set; } + Statuses? Status { get; set; } + DateTime? Completed { get; set; } + } +} diff --git a/CalCli.API/ITrigger.cs b/CalCli.API/ITrigger.cs new file mode 100644 index 0000000..a51c6ea --- /dev/null +++ b/CalCli.API/ITrigger.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CalCli.API +{ + public interface ITrigger + { + Relateds Related { get; set; } + TimeSpan? Duration { get; set; } + DateTime? DateTime { get; set; } + } +} diff --git a/CalCli.API/Properties/AssemblyInfo.cs b/CalCli.API/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..29a202b --- /dev/null +++ b/CalCli.API/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CalCli.API")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CalCli.API")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("2c258fae-97ed-4916-b5a3-4723700d675d")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CalCli.API/Relateds.cs b/CalCli.API/Relateds.cs new file mode 100644 index 0000000..290c698 --- /dev/null +++ b/CalCli.API/Relateds.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CalCli.API +{ + public enum Relateds + { + Start, End + } +} diff --git a/CalDav/Statuses.cs b/CalCli.API/Statuses.cs similarity index 79% rename from CalDav/Statuses.cs rename to CalCli.API/Statuses.cs index 828a67b..2972458 100644 --- a/CalDav/Statuses.cs +++ b/CalCli.API/Statuses.cs @@ -1,5 +1,5 @@  -namespace CalDav { +namespace CalCli.API { public enum Statuses { COMPLETED, CANCELED, TENTATIVE, NEEDS_ACTION, DRAFT } diff --git a/CalCli.Util/AutoConfiguration.cs b/CalCli.Util/AutoConfiguration.cs new file mode 100644 index 0000000..d5bfef6 --- /dev/null +++ b/CalCli.Util/AutoConfiguration.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using CalCli; +using OutlookClient; +using CalCli.API; +using System.IO; +using CalCli.Connections; +using CalCli.UI; + +namespace CalCli.Util +{ + public class AutoConfiguration + { + private static IConnection refreshGoogleToken() + { + IConnection connection; + GoogleOAuthForm form = new GoogleOAuthForm(); + form.ShowDialog(); + connection = new GoogleConnection(form.Result.Token); + StreamWriter sw = new StreamWriter("token"); + sw.WriteLine(form.Result.Token); + sw.Close(); + return connection; + } + public static IServer GetCalendarServer(CalendarTypes calendarTypes, string username = null, string password = null) + { + IServer server; + if(calendarTypes == CalendarTypes.Outlook) + { + return new OutlookServer(); + } + else + { + IConnection connection; + if (calendarTypes == CalendarTypes.Google) + { + if (File.Exists("token")) + { + StreamReader sr = new StreamReader("token"); + connection = new GoogleConnection(sr.ReadLine()); + sr.Close(); + } + else + { + connection = refreshGoogleToken(); + } + server = null; + } + else + { + connection = new BasicConnection(username , password); + server = null; + } + if (server == null) + { + try + { + server = new CalDav.Client.Server(urlFromCalendarType(calendarTypes), connection, username, password); + + } + catch (Exception ex) + { + if (ex.Message == "Authentication is required" && connection.GetType().Equals(new GoogleConnection("").GetType())) + { + connection = refreshGoogleToken(); + server = new CalDav.Client.Server(urlFromCalendarType(calendarTypes), connection, username, password); + + } + else + throw ex; + } + } + return server; + } + } + + private static string urlFromCalendarType(CalendarTypes calendarTypes) + { + switch (calendarTypes) { + case CalendarTypes.Google: + return "https://apidata.googleusercontent.com/caldav/v2/"; + case CalendarTypes.iCloud: + return "https://caldav.icloud.com/"; + case CalendarTypes.Yahoo: + return "https://caldav.calendar.yahoo.com/dav/"; + case CalendarTypes.Outlook: + return "Outlook"; + } + return null; + } + } +} + + + diff --git a/CalCli.Util/CalCli.Util.csproj b/CalCli.Util/CalCli.Util.csproj new file mode 100644 index 0000000..8b73cfb --- /dev/null +++ b/CalCli.Util/CalCli.Util.csproj @@ -0,0 +1,75 @@ + + + + + Debug + AnyCPU + {00B20F5C-EE2C-4A3D-9BB6-EA426A02C985} + Library + Properties + CalCli.Util + CalCli.Util + v4.8 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + {2c258fae-97ed-4916-b5a3-4723700d675d} + CalCli.API + + + {dbefed7e-dc69-48c0-9ac3-428b2168a17a} + CalCli + + + {1b9b42a0-a34b-4bf6-a5d5-21c46ed0d9b3} + CalDav.Client + + + {01af789a-f9ce-47f7-a66c-d3bae82aecc3} + OutlookClient + + + + + \ No newline at end of file diff --git a/CalCli.Util/CalendarTypes.cs b/CalCli.Util/CalendarTypes.cs new file mode 100644 index 0000000..a59ed6c --- /dev/null +++ b/CalCli.Util/CalendarTypes.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CalCli.Util +{ + public enum CalendarTypes + { + Outlook, + Google, + Yahoo, + iCloud + } +} diff --git a/CalCli.Util/Properties/AssemblyInfo.cs b/CalCli.Util/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..0412bc2 --- /dev/null +++ b/CalCli.Util/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CalCli.Util")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CalCli.Util")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("00b20f5c-ee2c-4a3d-9bb6-ea426a02c985")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.1.1.0")] +[assembly: AssemblyFileVersion("1.1.1.0")] diff --git a/CalCli/CalCli.csproj b/CalCli/CalCli.csproj new file mode 100644 index 0000000..71e77c1 --- /dev/null +++ b/CalCli/CalCli.csproj @@ -0,0 +1,91 @@ + + + + + Debug + AnyCPU + {DBEFED7E-DC69-48C0-9AC3-428B2168A17A} + Library + Properties + CalCli + CalCli + v4.8 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll + True + + + + + + + + + + + + + + + + + + Form + + + GoogleOAuthForm.cs + + + + + + {2c258fae-97ed-4916-b5a3-4723700d675d} + CalCli.API + + + {1b9b42a0-a34b-4bf6-a5d5-21c46ed0d9b3} + CalDav.Client + + + {01a4c4cf-5ad1-4324-a391-dc922c84be1c} + CalDav + + + + + GoogleOAuthForm.cs + + + + + + + + \ No newline at end of file diff --git a/CalCli/Connections/BasicConnection.cs b/CalCli/Connections/BasicConnection.cs new file mode 100644 index 0000000..71674aa --- /dev/null +++ b/CalCli/Connections/BasicConnection.cs @@ -0,0 +1,38 @@ +using System; +using System.Net; +using CalCli.API; + +namespace CalCli +{ + public class BasicConnection : IConnection, ICredentials + { + private string username; + private string password; + + public BasicConnection(string username, string password) + { + this.username = username; + this.password = password; + } + + public WebRequest Authorize(WebRequest request) + { + request.Credentials = this; + + if (request.Credentials != null) + { + //req.Credentials = credentials; + var b64 = username + ":" + password; + b64 = System.Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(b64)); + request.Headers[HttpRequestHeader.Authorization] = "Basic " + b64; + } + ((HttpWebRequest)request).UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2"; + return request; + } + + public NetworkCredential GetCredential(Uri uri, string authType) + { + return new NetworkCredential(username, password); + } + } +} \ No newline at end of file diff --git a/CalCli/Connections/GoogleConnection.cs b/CalCli/Connections/GoogleConnection.cs new file mode 100644 index 0000000..6c877b0 --- /dev/null +++ b/CalCli/Connections/GoogleConnection.cs @@ -0,0 +1,21 @@ +using System.Net; +using CalCli.API; + +namespace CalCli.Connections +{ + public class GoogleConnection : IConnection + { + private string token; + + public GoogleConnection(string token) + { + this.token = token; + } + + public WebRequest Authorize(WebRequest request) + { + request.Headers.Add(HttpRequestHeader.Authorization, "Bearer "+token); + return request; + } + } +} diff --git a/CalCli/Connections/GoogleOAuthFormResponse.cs b/CalCli/Connections/GoogleOAuthFormResponse.cs new file mode 100644 index 0000000..1886648 --- /dev/null +++ b/CalCli/Connections/GoogleOAuthFormResponse.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CalCli.Connections +{ + public class GoogleOAuthFormResponse + { + public DialogResult DialogResult { get; set; } + public string Token { get; set; } + public string RefreshToken { get; set; } + public int ExpiresIn { get; set; } + } +} diff --git a/CalCli/Properties/AssemblyInfo.cs b/CalCli/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7b5f4b6 --- /dev/null +++ b/CalCli/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CalCli")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CalCli")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("dbefed7e-dc69-48c0-9ac3-428b2168a17a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/CalCli/UI/GoogleOAuthForm.Designer.cs b/CalCli/UI/GoogleOAuthForm.Designer.cs new file mode 100644 index 0000000..686174d --- /dev/null +++ b/CalCli/UI/GoogleOAuthForm.Designer.cs @@ -0,0 +1,74 @@ +namespace CalCli.UI +{ + partial class GoogleOAuthForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.webBrowser1 = new System.Windows.Forms.WebBrowser(); + this.authWebBrowser = new System.Windows.Forms.WebBrowser(); + this.SuspendLayout(); + // + // webBrowser1 + // + this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; + this.webBrowser1.Location = new System.Drawing.Point(0, 0); + this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20); + this.webBrowser1.Name = "webBrowser1"; + this.webBrowser1.Size = new System.Drawing.Size(872, 499); + this.webBrowser1.TabIndex = 0; + // + // authWebBrowser + // + this.authWebBrowser.Dock = System.Windows.Forms.DockStyle.Fill; + this.authWebBrowser.Location = new System.Drawing.Point(0, 0); + this.authWebBrowser.MinimumSize = new System.Drawing.Size(20, 20); + this.authWebBrowser.Name = "authWebBrowser"; + this.authWebBrowser.Size = new System.Drawing.Size(872, 499); + this.authWebBrowser.TabIndex = 1; + this.authWebBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.authWebBrowser_DocumentCompleted); + // + // GoogleOAuthForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(872, 499); + this.Controls.Add(this.authWebBrowser); + this.Controls.Add(this.webBrowser1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Name = "GoogleOAuthForm"; + this.Text = "Google Authentication"; + this.Load += new System.EventHandler(this.GoogleOAuthForm_Load); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.WebBrowser webBrowser1; + private System.Windows.Forms.WebBrowser authWebBrowser; + } +} \ No newline at end of file diff --git a/CalCli/UI/GoogleOAuthForm.cs b/CalCli/UI/GoogleOAuthForm.cs new file mode 100644 index 0000000..5146d66 --- /dev/null +++ b/CalCli/UI/GoogleOAuthForm.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Net; +using System.IO; +using Newtonsoft.Json.Linq; +using CalCli.Connections; + +namespace CalCli.UI +{ + public partial class GoogleOAuthForm : Form + { + public GoogleOAuthFormResponse Result { get; set; } + + public GoogleOAuthForm() + { + InitializeComponent(); + } + + private void GoogleOAuthForm_Load(object sender, EventArgs e) + { + authWebBrowser.Navigate("https://accounts.google.com/o/oauth2/auth?response_type=code&redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto&" + + "client_id=562771573604-thtg508t2k88730qveaalj8fuq43iuki.apps.googleusercontent.com&" + + "scope=https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.readonly"); + } + + private void authWebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) + { + if (authWebBrowser.DocumentTitle.Contains("code=")) + { + getToken(extractCode(authWebBrowser.DocumentTitle)); + } + } + + private void getToken(object code) + { + WebRequest request = HttpWebRequest.Create("https://accounts.google.com/o/oauth2/token"); + + string postData = "code="+code+"&" + + "client_id=562771573604-thtg508t2k88730qveaalj8fuq43iuki.apps.googleusercontent.com&" + + "client_secret=LpgRRdGGqrHDr7KIG-FA604x&" + + "redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto&" + + "grant_type=authorization_code"; + + var data = Encoding.ASCII.GetBytes(postData); + + request.Method = "POST"; + request.ContentType = "application/x-www-form-urlencoded"; + request.ContentLength = data.Length; + + using (var stream = request.GetRequestStream()) + { + stream.Write(data, 0, data.Length); + } + + string response = new StreamReader(request.GetResponse().GetResponseStream()).ReadToEnd(); + + Result = new GoogleOAuthFormResponse() + { + DialogResult = DialogResult.OK, + Token = extractToken(response), + RefreshToken = extractRefreshToken(response), + ExpiresIn = extractExpiresIn(response) + }; + Close(); + } + + private int extractExpiresIn(string response) + { + return Convert.ToInt32(extractJsonParameter("expires_in", response)); + } + + private string extractRefreshToken(string response) + { + return extractJsonParameter("refresh_token", response); + } + + private string extractToken(string response) + { + return extractJsonParameter("access_token", response); + } + + private string extractJsonParameter(string key, string json) + { + JObject o = JObject.Parse(json); + return o.GetValue(key).ToString() ; + } + + private object extractCode(string documentTitle) + { + return documentTitle.Substring(documentTitle.IndexOf("code=") + 5); + } + } +} diff --git a/CalCli/UI/GoogleOAuthForm.resx b/CalCli/UI/GoogleOAuthForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/CalCli/UI/GoogleOAuthForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/CalCli/packages.config b/CalCli/packages.config new file mode 100644 index 0000000..583acbd --- /dev/null +++ b/CalCli/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/CalDav.Client/CalDav.Client.csproj b/CalDav.Client/CalDav.Client.csproj index 5b3b531..ca94863 100644 --- a/CalDav.Client/CalDav.Client.csproj +++ b/CalDav.Client/CalDav.Client.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,10 +9,11 @@ Properties CalDav.Client CalDav.Client - v4.5 + v4.8 512 ..\ true + true @@ -47,6 +48,10 @@ + + {2c258fae-97ed-4916-b5a3-4723700d675d} + CalCli.API + {01a4c4cf-5ad1-4324-a391-dc922c84be1c} CalDav diff --git a/CalDav.Client/Calendar.cs b/CalDav.Client/Calendar.cs index 99d95db..e13dd7f 100644 --- a/CalDav.Client/Calendar.cs +++ b/CalDav.Client/Calendar.cs @@ -3,16 +3,31 @@ using System.Linq; using System.Net; using System.Xml.Linq; +using CalCli.API; namespace CalDav.Client { - public class Calendar { + public class Calendar : ICalendar { public Uri Url { get; set; } public NetworkCredential Credentials { get; set; } public string Name { get; set; } public string Description { get; set; } - - public void Initialize() { - var result = Common.Request(Url, "PROPFIND", CalDav.Common.xDav.Element("propfind", + public Common common { get; set; } + + public Calendar(Common common) + { + this.common = common; + } + + public Calendar(Common common, Uri Url) + { + this.Url = Url; + this.common = common; + Initialize(); + } + + + public void Initialize() { + var result = common.Request(Url, "PROPFIND", CalDav.Common.xDav.Element("propfind", CalDav.Common.xDav.Element("allprop")), Credentials, new Dictionary { { "Depth", 0 } }); @@ -31,7 +46,7 @@ public void Initialize() { } public CalendarCollection Search(CalDav.CalendarQuery query) { - var result = Common.Request(Url, "REPORT", (XElement)query, Credentials, new Dictionary { + var result = common.Request(Url, "REPORT", (XElement)query, Credentials, new Dictionary { { "Depth", 1 } }); var xdoc = XDocument.Parse(result.Item2); @@ -45,12 +60,17 @@ public CalendarCollection Search(CalDav.CalendarQuery query) { } public void Save(Event e) { - if (string.IsNullOrEmpty(e.UID)) e.UID = Guid.NewGuid().ToString(); + bool update = !string.IsNullOrEmpty(e.UID); + + if (string.IsNullOrEmpty(e.UID)) e.UID = Guid.NewGuid().ToString(); e.LastModified = DateTime.UtcNow; - var result = Common.Request(new Uri(Url, e.UID + ".ics"), "PUT", (req, str) => { - req.Headers[System.Net.HttpRequestHeader.IfNoneMatch] = "*"; - req.ContentType = "text/calendar"; + var result = common.Request(new Uri(Url,e.UID + ".ics"), "PUT", (req, str) => { + if (!update) + { + req.Headers[System.Net.HttpRequestHeader.IfNoneMatch] = "*"; + } + req.ContentType = "text/calendar"; var calendar = new CalDav.Calendar(); e.Sequence = (e.Sequence ?? 0) + 1; calendar.Events.Add(e); @@ -63,9 +83,83 @@ public void Save(Event e) { GetObject(e.UID); } - - public CalendarCollection GetAll() { - var result = Common.Request(Url, "PROPFIND", CalDav.Common.xCalDav.Element("calendar-multiget", + public void Delete(Event e) + { + bool update = !string.IsNullOrEmpty(e.UID); + + if (string.IsNullOrEmpty(e.UID)) e.UID = Guid.NewGuid().ToString(); + e.LastModified = DateTime.UtcNow; + + var result = common.Request(new Uri(Url, e.UID + ".ics"), "DELETE", (req, str) => { + if (!update) + { + req.Headers[System.Net.HttpRequestHeader.IfNoneMatch] = "*"; + } + req.ContentType = "text/calendar"; + var calendar = new CalDav.Calendar(); + e.Sequence = (e.Sequence ?? 0) + 1; + calendar.Events.Add(e); + Common.Serialize(str, calendar); + + }, Credentials); + if (result.Item1 != System.Net.HttpStatusCode.Created && result.Item1 != HttpStatusCode.NoContent) + throw new Exception("Unable to save event: " + result.Item1); + e.Url = new Uri(Url, result.Item3[System.Net.HttpResponseHeader.Location]); + + GetObject(e.UID); + } + public void Save(ToDo e) + { + bool update = !string.IsNullOrEmpty(e.UID); + + if (string.IsNullOrEmpty(e.UID)) e.UID = Guid.NewGuid().ToString(); + e.LastModified = DateTime.UtcNow; + + var result = common.Request(new Uri(Url, e.UID + ".ics"), "PUT", (req, str) => { + if (!update) + { + req.Headers[System.Net.HttpRequestHeader.IfNoneMatch] = "*"; + } + req.ContentType = "text/calendar"; + var calendar = new CalDav.Calendar(); + e.Sequence = (e.Sequence ?? 0) + 1; + calendar.ToDos.Add(e); + Common.Serialize(str, calendar); + + }, Credentials); + if (result.Item1 != System.Net.HttpStatusCode.Created && result.Item1 != HttpStatusCode.NoContent) + throw new Exception("Unable to save event: " + result.Item1); + // e.Url = new Uri(Url, result.Item3[System.Net.HttpResponseHeader.Location]); + + GetObject(e.UID); + } + public void Delete(ToDo e) + { + bool update = !string.IsNullOrEmpty(e.UID); + + if (string.IsNullOrEmpty(e.UID)) e.UID = Guid.NewGuid().ToString(); + e.LastModified = DateTime.UtcNow; + + var result = common.Request(new Uri(Url, e.UID + ".ics"), "DELETE", (req, str) => { + if (!update) + { + req.Headers[System.Net.HttpRequestHeader.IfNoneMatch] = "*"; + } + req.ContentType = "text/calendar"; + var calendar = new CalDav.Calendar(); + e.Sequence = (e.Sequence ?? 0) + 1; + calendar.ToDos.Add(e); + Common.Serialize(str, calendar); + + }, Credentials); + if (result.Item1 != System.Net.HttpStatusCode.Created && result.Item1 != HttpStatusCode.NoContent) + throw new Exception("Unable to save event: " + result.Item1); + // e.Url = new Uri(Url, result.Item3[System.Net.HttpResponseHeader.Location]); + + GetObject(e.UID); + } + public CalendarCollection GetAll() { + var result = common.Request(Url, "REPORT", CalDav.Common.xCalDav.Element("calendar-multiget", CalDav.Common.xDav.Element("prop", CalDav.Common.xDav.Element("getetag"), CalDav.Common.xCalDav.Element("calendar-data") @@ -79,7 +173,7 @@ public CalendarCollection GetAll() { } public CalendarCollection GetObject(string uid) { - var result = Common.Request(Url, "REPORT", CalDav.Common.xCalDav.Element("calendar-multiget", + var result = common.Request(Url, "REPORT", CalDav.Common.xCalDav.Element("calendar-multiget", CalDav.Common.xDav.Element("prop", CalDav.Common.xDav.Element("getetag"), CalDav.Common.xCalDav.Element("calendar-data") @@ -91,5 +185,48 @@ public CalendarCollection GetObject(string uid) { return null; } - } + + public void Save(IEvent e) + { + Event ev = (Event)e; + Save(ev); + } + public void Delete(IEvent e) + { + Event ev = (Event)e; + Delete(ev); + } + + public void Save(IToDo t) + { + ToDo todo = (ToDo)t; + Save(todo); + } + public void Delete(IToDo t) + { + ToDo todo = (ToDo)t; + Delete(todo); + } + + public IToDo createToDo() + { + CalDav.ToDo todo = new CalDav.ToDo(); + return todo; + } + + public ITrigger createTrigger() + { + return new Trigger(); + } + + public IAlarm createAlarm() + { + return new Alarm(); + } + + public IEvent createEvent() + { + return new CalDav.Event(); + } + } } diff --git a/CalDav.Client/Common.cs b/CalDav.Client/Common.cs index f2af237..53261a7 100644 --- a/CalDav.Client/Common.cs +++ b/CalDav.Client/Common.cs @@ -1,23 +1,30 @@ using System; using System.Net; using System.Xml.Linq; +using CalCli.API; namespace CalDav.Client { - internal static class Common { + public class Common { + private IConnection connection; - public static Tuple Request(Uri url, string method, XDocument content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { + public Common(IConnection connection) + { + this.connection = connection; + } + + public Tuple Request(Uri url, string method, XDocument content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { return Request(url, method, content.Root, credentials, headers); } - public static Tuple Request(Uri url, string method, XElement content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { + public Tuple Request(Uri url, string method, XElement content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { return Request(url, method, (req, str) => { req.ContentType = "text/xml"; - var xml = content.ToString(); - using (var wrtr = new System.IO.StreamWriter(str)) + var xml = content.ToString(); + using (var wrtr = new System.IO.StreamWriter(str)) wrtr.Write(xml); }, credentials, headers); } - public static Tuple Request(Uri url, string method, string contentType, string content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { + public Tuple Request(Uri url, string method, string contentType, string content, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { return Request(url, method, (req, str) => { req.ContentType = contentType; using (var wrtr = new System.IO.StreamWriter(str)) @@ -25,8 +32,9 @@ internal static class Common { }, credentials, headers); } - public static Tuple Request(Uri url, string method = "GET", Action content = null, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { + public Tuple Request(Uri url, string method = "GET", Action content = null, NetworkCredential credentials = null, System.Collections.Generic.Dictionary headers = null) { var req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url); + req = (System.Net.HttpWebRequest)connection.Authorize(req); req.Method = method.ToUpper(); //Dear .NET, please don't try to do things for me. kthxbai @@ -40,13 +48,13 @@ internal static class Common { else req.Headers[header.Key] = value; } - if (credentials != null) { - //req.Credentials = credentials; - var b64 = credentials.UserName + ":" + credentials.Password; - b64 = System.Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(b64)); - req.Headers[HttpRequestHeader.Authorization] = "Basic " + b64; - } - + //if (credentials != null) { + // //req.Credentials = credentials; + // var b64 = credentials.UserName + ":" + credentials.Password; + // b64 = System.Convert.ToBase64String(System.Text.Encoding.Default.GetBytes(b64)); + // req.Headers[HttpRequestHeader.Authorization] = "Basic " + b64; + //} + connection.Authorize(req); using (var stream = req.GetRequestStream()) { if (content != null) { content(req, stream); @@ -60,7 +68,7 @@ internal static class Common { } } - private static System.Net.HttpWebResponse GetResponse(System.Net.HttpWebRequest req) { + private System.Net.HttpWebResponse GetResponse(System.Net.HttpWebRequest req) { try { return (System.Net.HttpWebResponse)req.GetResponse(); } catch (System.Net.WebException wex) { @@ -75,6 +83,21 @@ public static void Serialize(System.IO.Stream stream, Event e, System.Text.Encod } public static void Serialize(System.IO.Stream stream, CalDav.Calendar ical, System.Text.Encoding encoding = null) { + //System.IO.StreamWriter sr = new System.IO.StreamWriter(stream); + //sr.WriteLine("BEGIN: VCALENDAR"); + //sr.WriteLine("VERSION:2.0"); + //sr.WriteLine("PRODID: CalCli"); + //sr.WriteLine("BEGIN:VEVENT"); + //var enumer = ical.Events.GetEnumerator(); + //enumer.MoveNext(); + //sr.WriteLine("UID:"+enumer.Current.UID); + //sr.WriteLine("DTSTAMP:20060712T182145Z"); + //sr.WriteLine("DTSTART:20060714T170000Z"); + //sr.WriteLine("DTEND:20060715T040000Z"); + //sr.WriteLine("SUMMARY:Bastille Day Party"); + //sr.WriteLine("END:VEVENT"); + //sr.WriteLine("END:VCALENDAR"); + //return var serializer = new CalDav.Serializer(); serializer.Serialize(stream, ical, encoding); } diff --git a/CalDav.Client/Server.cs b/CalDav.Client/Server.cs index 7e89355..7b2541e 100644 --- a/CalDav.Client/Server.cs +++ b/CalDav.Client/Server.cs @@ -2,25 +2,74 @@ using System.Collections.Generic; using System.Linq; using System.Xml.Linq; +using CalDav.Client; +using CalCli.API; namespace CalDav.Client { - public class Server { + public class Server : IServer { + private Common Common; + private IConnection connection; public Uri Url { get; set; } public System.Net.NetworkCredential Credentials { get; set; } - public Server(string url, string username = null, string password = null) - : this(new Uri(url), username, password) { } + public Server(string url, IConnection connection, string username = null, string password = null) + : this(new Uri(url), connection, username, password) { } - private HashSet _Options; + private HashSet _Options; + // private string v; + // private IConnection connection; - public Server(Uri url, string username = null, string password = null) { - Url = url; + public Server(Uri url, IConnection connection, string username = null, string password = null) { + this.connection = connection; + Common = new Common(connection); + Url = url; if (username != null && password != null) { Credentials = new System.Net.NetworkCredential(username, password); } _Options = GetOptions(); + completeUrl(); } - public HashSet Options { + private void completeUrl() + { + var xcollectionset = CalDav.Common.xDav.GetName("current-user-principal"); + var result = Common.Request(Url, "propfind", new XDocument( + new XElement(CalDav.Common.xDav.GetName("propfind"), + new XElement(CalDav.Common.xDav.GetName("prop"), + new XElement(xcollectionset) + ) + + ) + ), Credentials, new System.Collections.Generic.Dictionary { { "Depth", 0 } }); + + var xdoc = XDocument.Parse(result.Item2); + Uri userprincipal = Url; + foreach(XNode node in xdoc.Descendants(xcollectionset)) + { + foreach (XElement href in xdoc.Descendants(CalDav.Common.xDav.GetName("href"))) + { + if (href.Parent == node) + { + userprincipal = new Uri(Url, href.Value); + } + } + } + // get homeset + xcollectionset = CalDav.Common.xCalDav.GetName("calendar-home-set"); + result = Common.Request(userprincipal, "propfind", new XDocument( + new XElement(CalDav.Common.xDav.GetName("propfind"), + new XElement(CalDav.Common.xDav.GetName("prop"), + new XElement(xcollectionset) + ) + + ) + ), Credentials, new System.Collections.Generic.Dictionary { { "Depth", 0 } }); + + xdoc = XDocument.Parse(result.Item2); + var hrefs = xdoc.Descendants(xcollectionset).SelectMany(x => x.Descendants(CalDav.Common.xDav.GetName("href"))); + Url = new Uri(Url, hrefs.First().Value); + } + + public HashSet Options { get { if (_Options == null) lock (this) @@ -30,7 +79,21 @@ public HashSet Options { } } - private HashSet GetOptions() { + public IConnection Connection + { + get + { + return connection; + } + + set + { + connection = value; + Common = new Common(connection); + } + } + + private HashSet GetOptions() { var result = Common.Request(Url, "options", credentials: Credentials); if (result.Item3["WWW-Authenticate"] != null) throw new Exception("Authentication is required"); @@ -49,26 +112,50 @@ public void CreateCalendar(string name) { } public Calendar[] GetCalendars() { - var xcollectionset = CalDav.Common.xCalDav.GetName("calendar-collection-set"); - var result = Common.Request(Url, "propfind", new XDocument( - new XElement(CalDav.Common.xDav.GetName("options"), - new XElement(xcollectionset) - ) - ), Credentials, new System.Collections.Generic.Dictionary { { "Depth", 0 } }); - - if (string.IsNullOrEmpty(result.Item2)) + var xcollectionset = CalDav.Common.xCalDav.GetName("calendar-home-set"); + var result = Common.Request(Url, "propfind", new XDocument( + new XElement(CalDav.Common.xDav.GetName("propfind"), + new XElement(CalDav.Common.xDav.GetName("allprop")//, + //new XElement(xcollectionset) + ) + + ) + ), Credentials, new System.Collections.Generic.Dictionary { { "Depth", 1 } }); + + if (string.IsNullOrEmpty(result.Item2)) return new[]{ - new Calendar { Url = Url, Credentials = Credentials } + new Calendar(Common) { Url = Url, Credentials = Credentials } }; var xdoc = XDocument.Parse(result.Item2); - var hrefs = xdoc.Descendants(xcollectionset).SelectMany(x => x.Descendants(CalDav.Common.xDav.GetName("href"))); - return hrefs.Select(x => new Calendar { Url = new Uri(Url, x.Value), Credentials = Credentials }).ToArray(); + var responses = xdoc.Descendants(CalDav.Common.xDav.GetName("response")); + List calendars = new List(); + // var hrefs = xdoc.Descendants(CalDav.Common.xDav.GetName("href")); + foreach(XElement response in responses) + { + if(response.Descendants(CalDav.Common.xCalDav.GetName("calendar")).Count() > 0) + { + string href = response.Descendants(CalDav.Common.xDav.GetName("href")).First().Value; + calendars.Add(new Calendar(Common, new Uri(Url, href)) { Credentials = Credentials }); + } + } + return calendars.ToArray(); } public bool Supports(string option) { return Options.Contains(option); } - } + + ICalendar[] IServer.GetCalendars() + { + return GetCalendars(); + } + + public void CreateCalendar(ICalendar calendar) + { + Calendar cal = (Calendar)calendar; + CreateCalendar(cal.Name); + } + } } diff --git a/CalDav.Server/CalDav.Server.csproj b/CalDav.Server/CalDav.Server.csproj index 76140e4..bab9108 100644 --- a/CalDav.Server/CalDav.Server.csproj +++ b/CalDav.Server/CalDav.Server.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,7 +9,7 @@ Properties CalDav.Server CalDav.Server - v4.0 + v4.8 512 ..\ true @@ -23,6 +23,7 @@ DEBUG;TRACE prompt 4 + false pdbonly @@ -31,12 +32,33 @@ TRACE prompt 4 + false + + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + - + + ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll + + + ..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll + + + ..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll + @@ -49,6 +71,10 @@ + + {2c258fae-97ed-4916-b5a3-4723700d675d} + CalCli.API + {01a4c4cf-5ad1-4324-a391-dc922c84be1c} CalDav @@ -58,6 +84,7 @@ Designer + diff --git a/CalDav.Server/Controllers/CalDavController.cs b/CalDav.Server/Controllers/CalDavController.cs index 7481558..cf04704 100644 --- a/CalDav.Server/Controllers/CalDavController.cs +++ b/CalDav.Server/Controllers/CalDavController.cs @@ -6,6 +6,8 @@ using System.Web.Mvc; using System.Web.Routing; using System.Xml.Linq; +using CalDavController = CalDav.Server.Controllers.CalDavController; + //http://greenbytes.de/tech/webdav/draft-dusseault-caldav-05.html //http://wwcsd.net/principals/__uids__/wiki-ilovemysmartboard/ diff --git a/CalDav.Server/Properties/AssemblyInfo.cs b/CalDav.Server/Properties/AssemblyInfo.cs index e58bb7b..75b1bfd 100644 --- a/CalDav.Server/Properties/AssemblyInfo.cs +++ b/CalDav.Server/Properties/AssemblyInfo.cs @@ -32,4 +32,5 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.0.1.0")] -[assembly: AssemblyFileVersion("0.0.1-beta3")] +//[assembly: AssemblyFileVersion("0.0.1-beta3")] +[assembly: AssemblyFileVersion("0.0.1")] diff --git a/CalDav.Server/packages.config b/CalDav.Server/packages.config new file mode 100644 index 0000000..f5288df --- /dev/null +++ b/CalDav.Server/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CalDav.sln b/CalDav.sln index 2cf0eb5..89639cb 100644 --- a/CalDav.sln +++ b/CalDav.sln @@ -1,6 +1,20 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31729.503 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{9A2D1E8A-0F23-4431-8FAD-113F12F2AD96}" + ProjectSection(SolutionItems) = preProject + .nuget\NuGet.Config = .nuget\NuGet.Config + .nuget\NuGet.exe = .nuget\NuGet.exe + .nuget\NuGet.targets = .nuget\NuGet.targets + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0374EF10-4265-4EEC-8608-94D0561FBF7F}" + ProjectSection(SolutionItems) = preProject + Create-Package.ps1 = Create-Package.ps1 + EndProjectSection +EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "Console\Console.csproj", "{EE946C60-392B-4A4F-B0A5-9D9A32C283DD}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{FABD2E1F-315B-4DCB-8DDA-FDE9263F99E1}" @@ -9,23 +23,21 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalDav", "CalDav\CalDav.csp EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalDav.Client", "CalDav.Client\CalDav.Client.csproj", "{1B9B42A0-A34B-4BF6-A5D5-21C46ED0D9B3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{9A2D1E8A-0F23-4431-8FAD-113F12F2AD96}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.WPF", "Demo.WPF\Demo.WPF.csproj", "{69BD41BC-3945-4C33-8A07-A0BD6DD9B160}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalDav.Server", "CalDav.Server\CalDav.Server.csproj", "{471EA68F-FB1F-4DF8-AAC1-31022C7316AB}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.MVC", "Demo.MVC\Demo.MVC.csproj", "{9164611E-4CAF-4FE1-B707-397CC1D515C0}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0374EF10-4265-4EEC-8608-94D0561FBF7F}" - ProjectSection(SolutionItems) = preProject - Create-Package.ps1 = Create-Package.ps1 - EndProjectSection +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalCli", "CalCli\CalCli.csproj", "{DBEFED7E-DC69-48C0-9AC3-428B2168A17A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Demo.CalCli", "Demo.CalCli\Demo.CalCli.csproj", "{4ED47A68-871A-4069-8B20-1D3D7AD163E6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalCli.API", "CalCli.API\CalCli.API.csproj", "{2C258FAE-97ED-4916-B5A3-4723700D675D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OutlookClient", "OutlookClient\OutlookClient.csproj", "{01AF789A-F9CE-47F7-A66C-D3BAE82AECC3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CalCli.Util", "CalCli.Util\CalCli.Util.csproj", "{00B20F5C-EE2C-4A3D-9BB6-EA426A02C985}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -61,8 +73,31 @@ Global {9164611E-4CAF-4FE1-B707-397CC1D515C0}.Debug|Any CPU.Build.0 = Debug|Any CPU {9164611E-4CAF-4FE1-B707-397CC1D515C0}.Release|Any CPU.ActiveCfg = Release|Any CPU {9164611E-4CAF-4FE1-B707-397CC1D515C0}.Release|Any CPU.Build.0 = Release|Any CPU + {DBEFED7E-DC69-48C0-9AC3-428B2168A17A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DBEFED7E-DC69-48C0-9AC3-428B2168A17A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DBEFED7E-DC69-48C0-9AC3-428B2168A17A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DBEFED7E-DC69-48C0-9AC3-428B2168A17A}.Release|Any CPU.Build.0 = Release|Any CPU + {4ED47A68-871A-4069-8B20-1D3D7AD163E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4ED47A68-871A-4069-8B20-1D3D7AD163E6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4ED47A68-871A-4069-8B20-1D3D7AD163E6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4ED47A68-871A-4069-8B20-1D3D7AD163E6}.Release|Any CPU.Build.0 = Release|Any CPU + {2C258FAE-97ED-4916-B5A3-4723700D675D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2C258FAE-97ED-4916-B5A3-4723700D675D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C258FAE-97ED-4916-B5A3-4723700D675D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2C258FAE-97ED-4916-B5A3-4723700D675D}.Release|Any CPU.Build.0 = Release|Any CPU + {01AF789A-F9CE-47F7-A66C-D3BAE82AECC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {01AF789A-F9CE-47F7-A66C-D3BAE82AECC3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {01AF789A-F9CE-47F7-A66C-D3BAE82AECC3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {01AF789A-F9CE-47F7-A66C-D3BAE82AECC3}.Release|Any CPU.Build.0 = Release|Any CPU + {00B20F5C-EE2C-4A3D-9BB6-EA426A02C985}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00B20F5C-EE2C-4A3D-9BB6-EA426A02C985}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00B20F5C-EE2C-4A3D-9BB6-EA426A02C985}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00B20F5C-EE2C-4A3D-9BB6-EA426A02C985}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {BC555101-0410-4588-8E6F-9CCA0D48DD4C} + EndGlobalSection EndGlobal diff --git a/CalDav/Alarm.cs b/CalDav/Alarm.cs index bc3b6cd..3f5f32b 100644 --- a/CalDav/Alarm.cs +++ b/CalDav/Alarm.cs @@ -1,22 +1,62 @@ - +using System; +using CalCli.API; namespace CalDav { - public class Alarm : ISerializeToICAL { - public string Action { get; set; } + public class Alarm : ISerializeToICAL, IAlarm { + public AlarmActions Action { get; set; } public string Description { get; set; } - public Trigger Trigger { get; set; } + public Trigger CalDavTrigger { get; set; } + + public ITrigger Trigger + { + get + { + return CalDavTrigger; + } + } + + ITrigger IAlarm.Trigger + { + get + { + return CalDavTrigger; + } + + set + { + CalDavTrigger = (CalDav.Trigger)value; + } + } public void Deserialize(System.IO.TextReader rdr, Serializer serializer) { string name, value; var parameters = new System.Collections.Specialized.NameValueCollection(); while (rdr.Property(out name, out value, parameters) && !string.IsNullOrEmpty(name)) { switch (name) { - case "ACTION": Action = value; break; + case "ACTION": Action = getAlarmActions(value); break; case "DESCRIPTION": Description = value; break; - case "TRIGGER": Trigger = serializer.GetService(); Trigger.Deserialize(value, parameters); break; + case "TRIGGER": CalDavTrigger = serializer.GetService(); CalDavTrigger.Deserialize(value, parameters); break; + case "END": return; } } } + private AlarmActions getAlarmActions(string value) + { + switch(value) + { + case "EMAIL": + return AlarmActions.EMAIL; + case "AUDIO": + return AlarmActions.AUDIO; + case "DISPLAY": + return AlarmActions.DISPLAY; + case "NONE": + return AlarmActions.NONE; + default: + throw new Exception("Action is not valid for alarm."); + } + } + public void Serialize(System.IO.TextWriter wrtr) { wrtr.BeginBlock("VALARM"); wrtr.Property("ACTION", Action); diff --git a/CalDav/CalDav.csproj b/CalDav/CalDav.csproj index daef403..69ea8fa 100644 --- a/CalDav/CalDav.csproj +++ b/CalDav/CalDav.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,7 +9,7 @@ Properties CalDav CalDav - v4.0 + v4.8 512 ..\ true @@ -23,6 +23,7 @@ DEBUG;TRACE prompt 4 + false pdbonly @@ -31,6 +32,7 @@ TRACE prompt 4 + false @@ -61,7 +63,6 @@ - @@ -71,6 +72,12 @@ Designer + + + {2c258fae-97ed-4916-b5a3-4723700d675d} + CalCli.API + + + \ No newline at end of file diff --git a/Demo.CalCli/Main.Designer.cs b/Demo.CalCli/Main.Designer.cs new file mode 100644 index 0000000..f11fdcd --- /dev/null +++ b/Demo.CalCli/Main.Designer.cs @@ -0,0 +1,365 @@ +namespace Demo.CalCli +{ + partial class Main + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.authButton = new System.Windows.Forms.Button(); + this.createEventButton = new System.Windows.Forms.Button(); + this.eventStartPicker = new System.Windows.Forms.DateTimePicker(); + this.eventEndPicker = new System.Windows.Forms.DateTimePicker(); + this.eventSummaryTextBox = new System.Windows.Forms.TextBox(); + this.eventDescriptionTextBox = new System.Windows.Forms.TextBox(); + this.summaryLabel = new System.Windows.Forms.Label(); + this.descriptionLabel = new System.Windows.Forms.Label(); + this.startLabel = new System.Windows.Forms.Label(); + this.eventGroupBox = new System.Windows.Forms.GroupBox(); + this.button1 = new System.Windows.Forms.Button(); + this.connectionGroupBox = new System.Windows.Forms.GroupBox(); + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.calidLabel = new System.Windows.Forms.Label(); + this.pswdLabel = new System.Windows.Forms.Label(); + this.passwordTextBox = new System.Windows.Forms.TextBox(); + this.usernameLabel = new System.Windows.Forms.Label(); + this.usernameTextBox = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.urlCombo = new System.Windows.Forms.ComboBox(); + this.checkList = new System.Windows.Forms.CheckedListBox(); + this.groupBox1 = new System.Windows.Forms.GroupBox(); + this.button2 = new System.Windows.Forms.Button(); + this.comboBox2 = new System.Windows.Forms.ComboBox(); + this.button3 = new System.Windows.Forms.Button(); + this.eventGroupBox.SuspendLayout(); + this.connectionGroupBox.SuspendLayout(); + this.groupBox1.SuspendLayout(); + this.SuspendLayout(); + // + // authButton + // + this.authButton.Location = new System.Drawing.Point(64, 134); + this.authButton.Name = "authButton"; + this.authButton.Size = new System.Drawing.Size(104, 23); + this.authButton.TabIndex = 0; + this.authButton.Text = "Connect"; + this.authButton.UseVisualStyleBackColor = true; + this.authButton.Click += new System.EventHandler(this.testButton_Click); + // + // createEventButton + // + this.createEventButton.Location = new System.Drawing.Point(82, 134); + this.createEventButton.Name = "createEventButton"; + this.createEventButton.Size = new System.Drawing.Size(102, 23); + this.createEventButton.TabIndex = 1; + this.createEventButton.Text = "Create Event"; + this.createEventButton.UseVisualStyleBackColor = true; + this.createEventButton.Click += new System.EventHandler(this.createEventButton_Click); + // + // eventStartPicker + // + this.eventStartPicker.Format = System.Windows.Forms.DateTimePickerFormat.Time; + this.eventStartPicker.Location = new System.Drawing.Point(82, 23); + this.eventStartPicker.Name = "eventStartPicker"; + this.eventStartPicker.Size = new System.Drawing.Size(102, 20); + this.eventStartPicker.TabIndex = 2; + // + // eventEndPicker + // + this.eventEndPicker.Format = System.Windows.Forms.DateTimePickerFormat.Time; + this.eventEndPicker.Location = new System.Drawing.Point(190, 23); + this.eventEndPicker.Name = "eventEndPicker"; + this.eventEndPicker.Size = new System.Drawing.Size(102, 20); + this.eventEndPicker.TabIndex = 3; + // + // eventSummaryTextBox + // + this.eventSummaryTextBox.Location = new System.Drawing.Point(82, 52); + this.eventSummaryTextBox.Name = "eventSummaryTextBox"; + this.eventSummaryTextBox.Size = new System.Drawing.Size(210, 20); + this.eventSummaryTextBox.TabIndex = 4; + // + // eventDescriptionTextBox + // + this.eventDescriptionTextBox.Location = new System.Drawing.Point(82, 78); + this.eventDescriptionTextBox.Multiline = true; + this.eventDescriptionTextBox.Name = "eventDescriptionTextBox"; + this.eventDescriptionTextBox.Size = new System.Drawing.Size(210, 50); + this.eventDescriptionTextBox.TabIndex = 5; + // + // summaryLabel + // + this.summaryLabel.AutoSize = true; + this.summaryLabel.Location = new System.Drawing.Point(28, 55); + this.summaryLabel.Name = "summaryLabel"; + this.summaryLabel.Size = new System.Drawing.Size(50, 13); + this.summaryLabel.TabIndex = 6; + this.summaryLabel.Text = "Summary"; + // + // descriptionLabel + // + this.descriptionLabel.AutoSize = true; + this.descriptionLabel.Location = new System.Drawing.Point(18, 81); + this.descriptionLabel.Name = "descriptionLabel"; + this.descriptionLabel.Size = new System.Drawing.Size(60, 13); + this.descriptionLabel.TabIndex = 7; + this.descriptionLabel.Text = "Description"; + // + // startLabel + // + this.startLabel.AutoSize = true; + this.startLabel.Location = new System.Drawing.Point(44, 27); + this.startLabel.Name = "startLabel"; + this.startLabel.Size = new System.Drawing.Size(30, 13); + this.startLabel.TabIndex = 8; + this.startLabel.Text = "Time"; + // + // eventGroupBox + // + this.eventGroupBox.Controls.Add(this.button1); + this.eventGroupBox.Controls.Add(this.eventDescriptionTextBox); + this.eventGroupBox.Controls.Add(this.createEventButton); + this.eventGroupBox.Controls.Add(this.startLabel); + this.eventGroupBox.Controls.Add(this.eventStartPicker); + this.eventGroupBox.Controls.Add(this.descriptionLabel); + this.eventGroupBox.Controls.Add(this.eventEndPicker); + this.eventGroupBox.Controls.Add(this.summaryLabel); + this.eventGroupBox.Controls.Add(this.eventSummaryTextBox); + this.eventGroupBox.Location = new System.Drawing.Point(270, 185); + this.eventGroupBox.Name = "eventGroupBox"; + this.eventGroupBox.Size = new System.Drawing.Size(301, 167); + this.eventGroupBox.TabIndex = 10; + this.eventGroupBox.TabStop = false; + this.eventGroupBox.Text = "Event"; + // + // button1 + // + this.button1.Location = new System.Drawing.Point(190, 134); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(102, 23); + this.button1.TabIndex = 9; + this.button1.Text = "Create ToDo"; + this.button1.UseVisualStyleBackColor = true; + this.button1.Click += new System.EventHandler(this.button1_Click_1); + // + // connectionGroupBox + // + this.connectionGroupBox.Controls.Add(this.button3); + this.connectionGroupBox.Controls.Add(this.comboBox2); + this.connectionGroupBox.Controls.Add(this.comboBox1); + this.connectionGroupBox.Controls.Add(this.calidLabel); + this.connectionGroupBox.Controls.Add(this.pswdLabel); + this.connectionGroupBox.Controls.Add(this.passwordTextBox); + this.connectionGroupBox.Controls.Add(this.authButton); + this.connectionGroupBox.Controls.Add(this.usernameLabel); + this.connectionGroupBox.Controls.Add(this.usernameTextBox); + this.connectionGroupBox.Controls.Add(this.label1); + this.connectionGroupBox.Controls.Add(this.urlCombo); + this.connectionGroupBox.Location = new System.Drawing.Point(12, 12); + this.connectionGroupBox.Name = "connectionGroupBox"; + this.connectionGroupBox.Size = new System.Drawing.Size(559, 167); + this.connectionGroupBox.TabIndex = 11; + this.connectionGroupBox.TabStop = false; + this.connectionGroupBox.Text = "Connection"; + // + // comboBox1 + // + this.comboBox1.FormattingEnabled = true; + this.comboBox1.Location = new System.Drawing.Point(64, 55); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(486, 21); + this.comboBox1.TabIndex = 22; + // + // calidLabel + // + this.calidLabel.AutoSize = true; + this.calidLabel.Location = new System.Drawing.Point(27, 59); + this.calidLabel.Name = "calidLabel"; + this.calidLabel.Size = new System.Drawing.Size(31, 13); + this.calidLabel.TabIndex = 19; + this.calidLabel.Text = "CalId"; + // + // pswdLabel + // + this.pswdLabel.AutoSize = true; + this.pswdLabel.Location = new System.Drawing.Point(6, 111); + this.pswdLabel.Name = "pswdLabel"; + this.pswdLabel.Size = new System.Drawing.Size(53, 13); + this.pswdLabel.TabIndex = 17; + this.pswdLabel.Text = "Password"; + // + // passwordTextBox + // + this.passwordTextBox.Location = new System.Drawing.Point(64, 108); + this.passwordTextBox.Name = "passwordTextBox"; + this.passwordTextBox.Size = new System.Drawing.Size(486, 20); + this.passwordTextBox.TabIndex = 16; + this.passwordTextBox.Text = "Aliasgarikh20"; + this.passwordTextBox.UseSystemPasswordChar = true; + // + // usernameLabel + // + this.usernameLabel.AutoSize = true; + this.usernameLabel.Location = new System.Drawing.Point(6, 85); + this.usernameLabel.Name = "usernameLabel"; + this.usernameLabel.Size = new System.Drawing.Size(55, 13); + this.usernameLabel.TabIndex = 15; + this.usernameLabel.Text = "Username"; + // + // usernameTextBox + // + this.usernameTextBox.Location = new System.Drawing.Point(64, 82); + this.usernameTextBox.Name = "usernameTextBox"; + this.usernameTextBox.Size = new System.Drawing.Size(486, 20); + this.usernameTextBox.TabIndex = 14; + this.usernameTextBox.Text = "aliasgarikh@icloud.com"; + this.usernameTextBox.TextChanged += new System.EventHandler(this.usernameTextBox_TextChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(38, 33); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(20, 13); + this.label1.TabIndex = 13; + this.label1.Text = "Url"; + // + // urlCombo + // + this.urlCombo.FormattingEnabled = true; + this.urlCombo.Items.AddRange(new object[] { + "https://caldav.icloud.com/", + "https://apidata.googleusercontent.com/caldav/v2/", + "https://caldav.calendar.yahoo.com/dav/", + "Outlook"}); + this.urlCombo.Location = new System.Drawing.Point(64, 29); + this.urlCombo.Name = "urlCombo"; + this.urlCombo.Size = new System.Drawing.Size(486, 21); + this.urlCombo.TabIndex = 12; + this.urlCombo.Text = "https://caldav.icloud.com/"; + // + // checkList + // + this.checkList.FormattingEnabled = true; + this.checkList.Location = new System.Drawing.Point(9, 34); + this.checkList.Name = "checkList"; + this.checkList.Size = new System.Drawing.Size(237, 94); + this.checkList.TabIndex = 12; + // + // groupBox1 + // + this.groupBox1.Controls.Add(this.button2); + this.groupBox1.Controls.Add(this.checkList); + this.groupBox1.Location = new System.Drawing.Point(12, 185); + this.groupBox1.Name = "groupBox1"; + this.groupBox1.Size = new System.Drawing.Size(252, 167); + this.groupBox1.TabIndex = 13; + this.groupBox1.TabStop = false; + this.groupBox1.Text = "ToDos"; + // + // button2 + // + this.button2.Location = new System.Drawing.Point(9, 134); + this.button2.Name = "button2"; + this.button2.Size = new System.Drawing.Size(102, 23); + this.button2.TabIndex = 10; + this.button2.Text = "Update"; + this.button2.UseVisualStyleBackColor = true; + this.button2.Click += new System.EventHandler(this.button2_Click); + // + // comboBox2 + // + this.comboBox2.FormattingEnabled = true; + this.comboBox2.Items.AddRange(new object[] { + "Google", + "iCloud", + "Yahoo", + "Outlook"}); + this.comboBox2.Location = new System.Drawing.Point(367, 135); + this.comboBox2.Name = "comboBox2"; + this.comboBox2.Size = new System.Drawing.Size(82, 21); + this.comboBox2.TabIndex = 23; + this.comboBox2.Text = "Google"; + // + // button3 + // + this.button3.Location = new System.Drawing.Point(448, 134); + this.button3.Name = "button3"; + this.button3.Size = new System.Drawing.Size(102, 23); + this.button3.TabIndex = 24; + this.button3.Text = "Auto Config"; + this.button3.UseVisualStyleBackColor = true; + this.button3.Click += new System.EventHandler(this.button3_Click); + // + // Main + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(580, 362); + this.Controls.Add(this.groupBox1); + this.Controls.Add(this.connectionGroupBox); + this.Controls.Add(this.eventGroupBox); + this.Name = "Main"; + this.Text = "CalCli Demo"; + this.Load += new System.EventHandler(this.Main_Load); + this.eventGroupBox.ResumeLayout(false); + this.eventGroupBox.PerformLayout(); + this.connectionGroupBox.ResumeLayout(false); + this.connectionGroupBox.PerformLayout(); + this.groupBox1.ResumeLayout(false); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Button authButton; + private System.Windows.Forms.Button createEventButton; + private System.Windows.Forms.DateTimePicker eventStartPicker; + private System.Windows.Forms.DateTimePicker eventEndPicker; + private System.Windows.Forms.TextBox eventSummaryTextBox; + private System.Windows.Forms.TextBox eventDescriptionTextBox; + private System.Windows.Forms.Label summaryLabel; + private System.Windows.Forms.Label descriptionLabel; + private System.Windows.Forms.Label startLabel; + private System.Windows.Forms.GroupBox eventGroupBox; + private System.Windows.Forms.GroupBox connectionGroupBox; + private System.Windows.Forms.Label pswdLabel; + private System.Windows.Forms.TextBox passwordTextBox; + private System.Windows.Forms.Label usernameLabel; + private System.Windows.Forms.TextBox usernameTextBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox urlCombo; + private System.Windows.Forms.Label calidLabel; + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.CheckedListBox checkList; + private System.Windows.Forms.GroupBox groupBox1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button3; + private System.Windows.Forms.ComboBox comboBox2; + } +} + diff --git a/Demo.CalCli/Main.cs b/Demo.CalCli/Main.cs new file mode 100644 index 0000000..a0a8feb --- /dev/null +++ b/Demo.CalCli/Main.cs @@ -0,0 +1,236 @@ +using System; +using System.Windows.Forms; +using CalCli.UI; +using CalCli.Connections; +using System.IO; +using CalCli.API; +using CalCli; +using Outlook = Microsoft.Office.Interop.Outlook; +using System.Collections.Generic; +using CalCli.Util; + +namespace Demo.CalCli +{ + public partial class Main : Form + { + IConnection connection; + + ICalendar[] calendars; + + List todos; + + IServer server; + + public Main() + { + InitializeComponent(); + + todos = new List(); + } + + private void testButton_Click(object sender, EventArgs e) + { + if (urlCombo.Text.Contains("google")) + { + if (File.Exists("token")) + { + StreamReader sr = new StreamReader("token"); + connection = new GoogleConnection(sr.ReadLine()); + sr.Close(); + } + else + { + refreshGoogleToken(); + } + server = null; + } + else if (urlCombo.Text.Contains("Outlook")) + { + connection = new BasicConnection(null, null); + server = new OutlookClient.OutlookServer(); + } + else + { + connection = new BasicConnection(usernameTextBox.Text, passwordTextBox.Text); + server = null; + } + if(server == null) + { + try + { + server = new CalDav.Client.Server(urlCombo.Text, connection, usernameTextBox.Text, passwordTextBox.Text); + + } + catch (Exception ex) + { + if (ex.Message == "Authentication is required") + { + refreshGoogleToken(); + server = new CalDav.Client.Server(urlCombo.Text, connection, usernameTextBox.Text, passwordTextBox.Text); + + } + } + } + + try { + calendars = server.GetCalendars(); + }catch(NullReferenceException ex) + { + MessageBox.Show("Could not login."); + return; + } + comboBox1.Items.Clear(); + foreach(ICalendar calendar in calendars) + { + comboBox1.Items.Add(calendar.Name); + } + if(comboBox1.Items.Count > 0) + { + comboBox1.Text = (string)comboBox1.Items[0]; + } + } + + private void refreshGoogleToken() + { + GoogleOAuthForm form = new GoogleOAuthForm(); + form.ShowDialog(); + connection = new GoogleConnection(form.Result.Token); + StreamWriter sw = new StreamWriter("token"); + sw.WriteLine(form.Result.Token); + sw.Close(); + } + + private void createEventButton_Click(object sender, EventArgs e) + { + List < IAlarm > alarms = new List(); + IAlarm alarm = calendars[comboBox1.SelectedIndex].createAlarm(); + ITrigger trigger = calendars[comboBox1.SelectedIndex].createTrigger(); + alarm.Trigger = trigger; + //trigger.DateTime = eventStartPicker.Value; + trigger.Duration = new TimeSpan(); + trigger.Duration = trigger.Duration.Value.Add(new TimeSpan(0, -5, 0)); + trigger.Related = Relateds.Start; + alarm.Action = AlarmActions.DISPLAY; + alarms.Add(alarm); + IEvent ev = calendars[comboBox1.SelectedIndex].createEvent(); + + ev.Description = eventDescriptionTextBox.Text; + ev.Summary = eventSummaryTextBox.Text; + ev.Start = eventStartPicker.Value; + ev.End = eventEndPicker.Value; + ev.Alarms = alarms; + calendars[comboBox1.SelectedIndex].Save(ev); + } + + private void button1_Click(object sender, EventArgs e) + { + Outlook.Application olApp = new Outlook.Application(); + Outlook.NameSpace mapiNS = olApp.GetNamespace("MAPI"); + + string profile = ""; + mapiNS.Logon(profile, null, null, null); + + Outlook.AppointmentItem apt = olApp.CreateItem(Outlook.OlItemType.olAppointmentItem); + apt.Start = DateTime.Now.AddHours(-3); + apt.End = apt.Start.AddHours(1); + apt.Subject = "Please synch in advance."; + apt.Save(); + apt.Send(); + } + + private void Main_Load(object sender, EventArgs e) + { + + } + + private void usernameTextBox_TextChanged(object sender, EventArgs e) + { + + } + + private void button1_Click_1(object sender, EventArgs e) + { + IToDo todo = calendars[comboBox1.SelectedIndex].createToDo(); + todo.Summary = eventSummaryTextBox.Text; + todo.Start = eventStartPicker.Value; + todo.Due = eventStartPicker.Value; + try + { + calendars[comboBox1.SelectedIndex].Save(todo); + todos.Add(todo); + checkList.Items.Add(todo.Summary); + }catch(Exception ex) + { + MessageBox.Show("Calendar doesn't support todos."); + } + } + + private void button2_Click(object sender, EventArgs e) + { + for(int i = 0; i < checkList.Items.Count; i++) + { + if(checkList.GetItemChecked(i) != (todos[i].Completed != null)) + { + if (checkList.GetItemChecked(i)) + { + todos[i].Completed = DateTime.UtcNow; + todos[i].Status = Statuses.COMPLETED; + } + else + { + todos[i].Completed = null; + } + calendars[comboBox1.SelectedIndex].Save(todos[i]); + } + } + } + + private void button3_Click(object sender, EventArgs e) + { + try { + server = AutoConfiguration.GetCalendarServer(calendarTypeFromText(comboBox2.Text), usernameTextBox.Text, passwordTextBox.Text); + } + catch(Exception ex) + { + if (ex.Message == "Authentication is required") + MessageBox.Show("Could not login."); + else { + MessageBox.Show("Could not login."); + return; + } + + } + try + { + calendars = server.GetCalendars(); + } + catch (NullReferenceException ex) + { + MessageBox.Show("Could not login."); + return; + } + comboBox1.Items.Clear(); + foreach (ICalendar calendar in calendars) + { + comboBox1.Items.Add(calendar.Name); + } + if (comboBox1.Items.Count > 0) + { + comboBox1.Text = (string)comboBox1.Items[0]; + } + } + + private CalendarTypes calendarTypeFromText(string text) + { + if (text == "Google") + return CalendarTypes.Google; + if (text == "iCloud") + return CalendarTypes.iCloud; + if (text == "Yahoo") + return CalendarTypes.Yahoo; + if (text == "Outlook") + return CalendarTypes.Outlook; + return CalendarTypes.Google; + } + } +} diff --git a/Demo.CalCli/Main.resx b/Demo.CalCli/Main.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/Demo.CalCli/Main.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo.CalCli/Program.cs b/Demo.CalCli/Program.cs new file mode 100644 index 0000000..d6f61b1 --- /dev/null +++ b/Demo.CalCli/Program.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Demo.CalCli +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Main()); + } + } +} diff --git a/Demo.CalCli/Properties/AssemblyInfo.cs b/Demo.CalCli/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..826ecff --- /dev/null +++ b/Demo.CalCli/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Demo.CalCli")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Demo.CalCli")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("4ed47a68-871a-4069-8b20-1d3d7ad163e6")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Demo.CalCli/Properties/Resources.Designer.cs b/Demo.CalCli/Properties/Resources.Designer.cs new file mode 100644 index 0000000..d33b530 --- /dev/null +++ b/Demo.CalCli/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Demo.CalCli.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Demo.CalCli.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Demo.CalCli/Properties/Resources.resx b/Demo.CalCli/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/Demo.CalCli/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Demo.CalCli/Properties/Settings.Designer.cs b/Demo.CalCli/Properties/Settings.Designer.cs new file mode 100644 index 0000000..26bb228 --- /dev/null +++ b/Demo.CalCli/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Demo.CalCli.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/Demo.CalCli/Properties/Settings.settings b/Demo.CalCli/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/Demo.CalCli/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Demo.CalCli/packages.config b/Demo.CalCli/packages.config new file mode 100644 index 0000000..e146e3c --- /dev/null +++ b/Demo.CalCli/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Demo.MVC/Content/themes/base/accordion.css b/Demo.MVC/Content/themes/base/accordion.css new file mode 100644 index 0000000..13e5752 --- /dev/null +++ b/Demo.MVC/Content/themes/base/accordion.css @@ -0,0 +1,36 @@ +/*! + * jQuery UI Accordion 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/accordion/#theming + */ +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin: 2px 0 0 0; + padding: .5em .5em .5em .7em; + min-height: 0; /* support: IE7 */ + font-size: 100%; +} +.ui-accordion .ui-accordion-icons { + padding-left: 2.2em; +} +.ui-accordion .ui-accordion-icons .ui-accordion-icons { + padding-left: 2.2em; +} +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { + position: absolute; + left: .5em; + top: 50%; + margin-top: -8px; +} +.ui-accordion .ui-accordion-content { + padding: 1em 2.2em; + border-top: 0; + overflow: auto; +} diff --git a/Demo.MVC/Content/themes/base/all.css b/Demo.MVC/Content/themes/base/all.css new file mode 100644 index 0000000..0bab991 --- /dev/null +++ b/Demo.MVC/Content/themes/base/all.css @@ -0,0 +1,12 @@ +/*! + * jQuery UI CSS Framework 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/theming/ + */ +@import "base.css"; +@import "theme.css"; diff --git a/Demo.MVC/Content/themes/base/autocomplete.css b/Demo.MVC/Content/themes/base/autocomplete.css new file mode 100644 index 0000000..c21c54f --- /dev/null +++ b/Demo.MVC/Content/themes/base/autocomplete.css @@ -0,0 +1,16 @@ +/*! + * jQuery UI Autocomplete 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/autocomplete/#theming + */ +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: default; +} diff --git a/Demo.MVC/Content/themes/base/base.css b/Demo.MVC/Content/themes/base/base.css new file mode 100644 index 0000000..7f53172 --- /dev/null +++ b/Demo.MVC/Content/themes/base/base.css @@ -0,0 +1,28 @@ +/*! + * jQuery UI CSS Framework 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/theming/ + */ +@import url("core.css"); + +@import url("accordion.css"); +@import url("autocomplete.css"); +@import url("button.css"); +@import url("datepicker.css"); +@import url("dialog.css"); +@import url("draggable.css"); +@import url("menu.css"); +@import url("progressbar.css"); +@import url("resizable.css"); +@import url("selectable.css"); +@import url("selectmenu.css"); +@import url("sortable.css"); +@import url("slider.css"); +@import url("spinner.css"); +@import url("tabs.css"); +@import url("tooltip.css"); diff --git a/Demo.MVC/Content/themes/base/button.css b/Demo.MVC/Content/themes/base/button.css new file mode 100644 index 0000000..7f11bdd --- /dev/null +++ b/Demo.MVC/Content/themes/base/button.css @@ -0,0 +1,114 @@ +/*! + * jQuery UI Button 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/button/#theming + */ +.ui-button { + display: inline-block; + position: relative; + padding: 0; + line-height: normal; + margin-right: .1em; + cursor: pointer; + vertical-align: middle; + text-align: center; + overflow: visible; /* removes extra width in IE */ +} +.ui-button, +.ui-button:link, +.ui-button:visited, +.ui-button:hover, +.ui-button:active { + text-decoration: none; +} +/* to make room for the icon, a width needs to be set here */ +.ui-button-icon-only { + width: 2.2em; +} +/* button elements seem to need a little more width */ +button.ui-button-icon-only { + width: 2.4em; +} +.ui-button-icons-only { + width: 3.4em; +} +button.ui-button-icons-only { + width: 3.7em; +} + +/* button text element */ +.ui-button .ui-button-text { + display: block; + line-height: normal; +} +.ui-button-text-only .ui-button-text { + padding: .4em 1em; +} +.ui-button-icon-only .ui-button-text, +.ui-button-icons-only .ui-button-text { + padding: .4em; + text-indent: -9999999px; +} +.ui-button-text-icon-primary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: .4em 1em .4em 2.1em; +} +.ui-button-text-icon-secondary .ui-button-text, +.ui-button-text-icons .ui-button-text { + padding: .4em 2.1em .4em 1em; +} +.ui-button-text-icons .ui-button-text { + padding-left: 2.1em; + padding-right: 2.1em; +} +/* no icon support for input elements, provide padding by default */ +input.ui-button { + padding: .4em 1em; +} + +/* button icon element(s) */ +.ui-button-icon-only .ui-icon, +.ui-button-text-icon-primary .ui-icon, +.ui-button-text-icon-secondary .ui-icon, +.ui-button-text-icons .ui-icon, +.ui-button-icons-only .ui-icon { + position: absolute; + top: 50%; + margin-top: -8px; +} +.ui-button-icon-only .ui-icon { + left: 50%; + margin-left: -8px; +} +.ui-button-text-icon-primary .ui-button-icon-primary, +.ui-button-text-icons .ui-button-icon-primary, +.ui-button-icons-only .ui-button-icon-primary { + left: .5em; +} +.ui-button-text-icon-secondary .ui-button-icon-secondary, +.ui-button-text-icons .ui-button-icon-secondary, +.ui-button-icons-only .ui-button-icon-secondary { + right: .5em; +} + +/* button sets */ +.ui-buttonset { + margin-right: 7px; +} +.ui-buttonset .ui-button { + margin-left: 0; + margin-right: -.3em; +} + +/* workarounds */ +/* reset extra padding in Firefox, see h5bp.com/l */ +input.ui-button::-moz-focus-inner, +button.ui-button::-moz-focus-inner { + border: 0; + padding: 0; +} diff --git a/Demo.MVC/Content/themes/base/core.css b/Demo.MVC/Content/themes/base/core.css new file mode 100644 index 0000000..154f1f8 --- /dev/null +++ b/Demo.MVC/Content/themes/base/core.css @@ -0,0 +1,93 @@ +/*! + * jQuery UI CSS Framework 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/theming/ + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-clearfix { + min-height: 0; /* support: IE7 */ +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:Alpha(Opacity=0); /* support: IE8 */ +} + +.ui-front { + z-index: 100; +} + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; +} + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; +} + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} diff --git a/Demo.MVC/Content/themes/base/datepicker.css b/Demo.MVC/Content/themes/base/datepicker.css new file mode 100644 index 0000000..ea559d8 --- /dev/null +++ b/Demo.MVC/Content/themes/base/datepicker.css @@ -0,0 +1,175 @@ +/*! + * jQuery UI Datepicker 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/datepicker/#theming + */ +.ui-datepicker { + width: 17em; + padding: .2em .2em 0; + display: none; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: .2em 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 2px; + width: 1.8em; + height: 1.8em; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 1px; +} +.ui-datepicker .ui-datepicker-prev { + left: 2px; +} +.ui-datepicker .ui-datepicker-next { + right: 2px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 1px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 1px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin: 1px 0; +} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 45%; +} +.ui-datepicker table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em; +} +.ui-datepicker th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible; +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + width: 100%; + font-size: 0; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} diff --git a/Demo.MVC/Content/themes/base/dialog.css b/Demo.MVC/Content/themes/base/dialog.css new file mode 100644 index 0000000..66b90cc --- /dev/null +++ b/Demo.MVC/Content/themes/base/dialog.css @@ -0,0 +1,70 @@ +/*! + * jQuery UI Dialog 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/dialog/#theming + */ +.ui-dialog { + overflow: hidden; + position: absolute; + top: 0; + left: 0; + padding: .2em; + outline: 0; +} +.ui-dialog .ui-dialog-titlebar { + padding: .4em 1em; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: .1em 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 20px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: .5em 1em; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + margin-top: .5em; + padding: .3em 1em .5em .4em; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: .5em .4em .5em 0; + cursor: pointer; +} +.ui-dialog .ui-resizable-se { + width: 12px; + height: 12px; + right: -5px; + bottom: -5px; + background-position: 16px 16px; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} diff --git a/Demo.MVC/Content/themes/base/draggable.css b/Demo.MVC/Content/themes/base/draggable.css new file mode 100644 index 0000000..df01f29 --- /dev/null +++ b/Demo.MVC/Content/themes/base/draggable.css @@ -0,0 +1,12 @@ +/*! + * jQuery UI Draggable 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ +.ui-draggable-handle { + -ms-touch-action: none; + touch-action: none; +} diff --git a/Demo.MVC/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png b/Demo.MVC/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000..5b5dab2 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png b/Demo.MVC/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png new file mode 100644 index 0000000..ac8b229 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-bg_flat_75_ffffff_40x100.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png b/Demo.MVC/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000..ad3d634 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-bg_glass_55_fbf9ee_1x400.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png b/Demo.MVC/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png new file mode 100644 index 0000000..42ccba2 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-bg_glass_65_ffffff_1x400.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png b/Demo.MVC/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png new file mode 100644 index 0000000..5a46b47 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-bg_glass_75_dadada_1x400.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png b/Demo.MVC/Content/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 0000000..86c2baa Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png b/Demo.MVC/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 0000000..4443fdc Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/Demo.MVC/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png new file mode 100644 index 0000000..7c9fa6c Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_222222_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_222222_256x240.png new file mode 100644 index 0000000..ee039dc Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_222222_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_2e83ff_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000..45e8928 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_2e83ff_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_444444_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_444444_256x240.png new file mode 100644 index 0000000..348243b Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_444444_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_454545_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_454545_256x240.png new file mode 100644 index 0000000..7ec70d1 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_454545_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_555555_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_555555_256x240.png new file mode 100644 index 0000000..949749b Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_555555_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_777620_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_777620_256x240.png new file mode 100644 index 0000000..350c783 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_777620_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_777777_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_777777_256x240.png new file mode 100644 index 0000000..f8b5cc4 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_777777_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_888888_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000..5ba708c Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_888888_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_cc0000_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_cc0000_256x240.png new file mode 100644 index 0000000..a046ee5 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_cc0000_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_cd0a0a_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000..7930a55 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_cd0a0a_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/images/ui-icons_ffffff_256x240.png b/Demo.MVC/Content/themes/base/images/ui-icons_ffffff_256x240.png new file mode 100644 index 0000000..ea57ef0 Binary files /dev/null and b/Demo.MVC/Content/themes/base/images/ui-icons_ffffff_256x240.png differ diff --git a/Demo.MVC/Content/themes/base/jquery-ui.css b/Demo.MVC/Content/themes/base/jquery-ui.css new file mode 100644 index 0000000..ffdcb23 --- /dev/null +++ b/Demo.MVC/Content/themes/base/jquery-ui.css @@ -0,0 +1,1312 @@ +/*! jQuery UI - v1.12.0 - 2016-07-08 +* http://jqueryui.com +* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { + display: none; +} +.ui-helper-hidden-accessible { + border: 0; + clip: rect(0 0 0 0); + height: 1px; + margin: -1px; + overflow: hidden; + padding: 0; + position: absolute; + width: 1px; +} +.ui-helper-reset { + margin: 0; + padding: 0; + border: 0; + outline: 0; + line-height: 1.3; + text-decoration: none; + font-size: 100%; + list-style: none; +} +.ui-helper-clearfix:before, +.ui-helper-clearfix:after { + content: ""; + display: table; + border-collapse: collapse; +} +.ui-helper-clearfix:after { + clear: both; +} +.ui-helper-zfix { + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0; + filter:Alpha(Opacity=0); /* support: IE8 */ +} + +.ui-front { + z-index: 100; +} + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { + cursor: default !important; + pointer-events: none; +} + + +/* Icons +----------------------------------*/ +.ui-icon { + display: inline-block; + vertical-align: middle; + margin-top: -.25em; + position: relative; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; +} + +.ui-widget-icon-block { + left: 50%; + margin-left: -8px; + display: block; +} + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} +.ui-accordion .ui-accordion-header { + display: block; + cursor: pointer; + position: relative; + margin: 2px 0 0 0; + padding: .5em .5em .5em .7em; + font-size: 100%; +} +.ui-accordion .ui-accordion-content { + padding: 1em 2.2em; + border-top: 0; + overflow: auto; +} +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: default; +} +.ui-menu { + list-style: none; + padding: 0; + margin: 0; + display: block; + outline: 0; +} +.ui-menu .ui-menu { + position: absolute; +} +.ui-menu .ui-menu-item { + margin: 0; + cursor: pointer; + /* support: IE10, see #8844 */ + list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); +} +.ui-menu .ui-menu-item-wrapper { + position: relative; + padding: 3px 1em 3px .4em; +} +.ui-menu .ui-menu-divider { + margin: 5px 0; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0; +} +.ui-menu .ui-state-focus, +.ui-menu .ui-state-active { + margin: -1px; +} + +/* icon support */ +.ui-menu-icons { + position: relative; +} +.ui-menu-icons .ui-menu-item-wrapper { + padding-left: 2em; +} + +/* left-aligned */ +.ui-menu .ui-icon { + position: absolute; + top: 0; + bottom: 0; + left: .2em; + margin: auto 0; +} + +/* right-aligned */ +.ui-menu .ui-menu-icon { + left: auto; + right: 0; +} +.ui-button { + padding: .4em 1em; + display: inline-block; + position: relative; + line-height: normal; + margin-right: .1em; + cursor: pointer; + vertical-align: middle; + text-align: center; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + + /* Support: IE <= 11 */ + overflow: visible; +} + +.ui-button, +.ui-button:link, +.ui-button:visited, +.ui-button:hover, +.ui-button:active { + text-decoration: none; +} + +/* to make room for the icon, a width needs to be set here */ +.ui-button-icon-only { + width: 2em; + box-sizing: border-box; + text-indent: -9999px; + white-space: nowrap; +} + +/* no icon support for input elements */ +input.ui-button.ui-button-icon-only { + text-indent: 0; +} + +/* button icon element(s) */ +.ui-button-icon-only .ui-icon { + position: absolute; + top: 50%; + left: 50%; + margin-top: -8px; + margin-left: -8px; +} + +.ui-button.ui-icon-notext .ui-icon { + padding: 0; + width: 2.1em; + height: 2.1em; + text-indent: -9999px; + white-space: nowrap; + +} + +input.ui-button.ui-icon-notext .ui-icon { + width: auto; + height: auto; + text-indent: 0; + white-space: normal; + padding: .4em 1em; +} + +/* workarounds */ +/* Support: Firefox 5 - 40 */ +input.ui-button::-moz-focus-inner, +button.ui-button::-moz-focus-inner { + border: 0; + padding: 0; +} +.ui-controlgroup { + vertical-align: middle; + display: inline-block; +} +.ui-controlgroup > .ui-controlgroup-item { + float: left; + margin-left: 0; + margin-right: 0; +} +.ui-controlgroup > .ui-controlgroup-item:focus, +.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus { + z-index: 9999; +} +.ui-controlgroup-vertical > .ui-controlgroup-item { + display: block; + float: none; + width: 100%; + margin-top: 0; + margin-bottom: 0; + text-align: left; +} +.ui-controlgroup-vertical .ui-controlgroup-item { + box-sizing: border-box; +} +.ui-controlgroup .ui-controlgroup-label { + padding: .4em 1em; +} +.ui-controlgroup .ui-controlgroup-label span { + font-size: 80%; +} +.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item { + border-left: none; +} +.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item { + border-top: none; +} +.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content { + border-right: none; +} +.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content { + border-bottom: none; +} + +/* Spinner specific style fixes */ +.ui-controlgroup-vertical .ui-spinner-input { + + /* Support: IE8 only, Android < 4.4 only */ + width: 75%; + width: calc( 100% - 2.4em ); +} +.ui-controlgroup-vertical .ui-spinner .ui-spinner-up { + border-top-style: solid; +} + +.ui-checkboxradio-label .ui-icon-background { + box-shadow: inset 1px 1px 1px #ccc; + border-radius: .12em; + border: none; +} +.ui-checkboxradio-radio-label .ui-icon-background { + width: 16px; + height: 16px; + border-radius: 1em; + overflow: visible; + border: none; +} +.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon, +.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon { + background-image: none; + width: 8px; + height: 8px; + border-width: 4px; + border-style: solid; +} +.ui-checkboxradio-disabled { + pointer-events: none; +} +.ui-datepicker { + width: 17em; + padding: .2em .2em 0; + display: none; +} +.ui-datepicker .ui-datepicker-header { + position: relative; + padding: .2em 0; +} +.ui-datepicker .ui-datepicker-prev, +.ui-datepicker .ui-datepicker-next { + position: absolute; + top: 2px; + width: 1.8em; + height: 1.8em; +} +.ui-datepicker .ui-datepicker-prev-hover, +.ui-datepicker .ui-datepicker-next-hover { + top: 1px; +} +.ui-datepicker .ui-datepicker-prev { + left: 2px; +} +.ui-datepicker .ui-datepicker-next { + right: 2px; +} +.ui-datepicker .ui-datepicker-prev-hover { + left: 1px; +} +.ui-datepicker .ui-datepicker-next-hover { + right: 1px; +} +.ui-datepicker .ui-datepicker-prev span, +.ui-datepicker .ui-datepicker-next span { + display: block; + position: absolute; + left: 50%; + margin-left: -8px; + top: 50%; + margin-top: -8px; +} +.ui-datepicker .ui-datepicker-title { + margin: 0 2.3em; + line-height: 1.8em; + text-align: center; +} +.ui-datepicker .ui-datepicker-title select { + font-size: 1em; + margin: 1px 0; +} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { + width: 45%; +} +.ui-datepicker table { + width: 100%; + font-size: .9em; + border-collapse: collapse; + margin: 0 0 .4em; +} +.ui-datepicker th { + padding: .7em .3em; + text-align: center; + font-weight: bold; + border: 0; +} +.ui-datepicker td { + border: 0; + padding: 1px; +} +.ui-datepicker td span, +.ui-datepicker td a { + display: block; + padding: .2em; + text-align: right; + text-decoration: none; +} +.ui-datepicker .ui-datepicker-buttonpane { + background-image: none; + margin: .7em 0 0 0; + padding: 0 .2em; + border-left: 0; + border-right: 0; + border-bottom: 0; +} +.ui-datepicker .ui-datepicker-buttonpane button { + float: right; + margin: .5em .2em .4em; + cursor: pointer; + padding: .2em .6em .3em .6em; + width: auto; + overflow: visible; +} +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { + float: left; +} + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { + width: auto; +} +.ui-datepicker-multi .ui-datepicker-group { + float: left; +} +.ui-datepicker-multi .ui-datepicker-group table { + width: 95%; + margin: 0 auto .4em; +} +.ui-datepicker-multi-2 .ui-datepicker-group { + width: 50%; +} +.ui-datepicker-multi-3 .ui-datepicker-group { + width: 33.3%; +} +.ui-datepicker-multi-4 .ui-datepicker-group { + width: 25%; +} +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { + border-left-width: 0; +} +.ui-datepicker-multi .ui-datepicker-buttonpane { + clear: left; +} +.ui-datepicker-row-break { + clear: both; + width: 100%; + font-size: 0; +} + +/* RTL support */ +.ui-datepicker-rtl { + direction: rtl; +} +.ui-datepicker-rtl .ui-datepicker-prev { + right: 2px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next { + left: 2px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-prev:hover { + right: 1px; + left: auto; +} +.ui-datepicker-rtl .ui-datepicker-next:hover { + left: 1px; + right: auto; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane { + clear: right; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button { + float: left; +} +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, +.ui-datepicker-rtl .ui-datepicker-group { + float: right; +} +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { + border-right-width: 0; + border-left-width: 1px; +} + +/* Icons */ +.ui-datepicker .ui-icon { + display: block; + text-indent: -99999px; + overflow: hidden; + background-repeat: no-repeat; + left: .5em; + top: .3em; +} +.ui-dialog { + position: absolute; + top: 0; + left: 0; + padding: .2em; + outline: 0; +} +.ui-dialog .ui-dialog-titlebar { + padding: .4em 1em; + position: relative; +} +.ui-dialog .ui-dialog-title { + float: left; + margin: .1em 0; + white-space: nowrap; + width: 90%; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-dialog .ui-dialog-titlebar-close { + position: absolute; + right: .3em; + top: 50%; + width: 20px; + margin: -10px 0 0 0; + padding: 1px; + height: 20px; +} +.ui-dialog .ui-dialog-content { + position: relative; + border: 0; + padding: .5em 1em; + background: none; + overflow: auto; +} +.ui-dialog .ui-dialog-buttonpane { + text-align: left; + border-width: 1px 0 0 0; + background-image: none; + margin-top: .5em; + padding: .3em 1em .5em .4em; +} +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { + float: right; +} +.ui-dialog .ui-dialog-buttonpane button { + margin: .5em .4em .5em 0; + cursor: pointer; +} +.ui-dialog .ui-resizable-n { + height: 2px; + top: 0; +} +.ui-dialog .ui-resizable-e { + width: 2px; + right: 0; +} +.ui-dialog .ui-resizable-s { + height: 2px; + bottom: 0; +} +.ui-dialog .ui-resizable-w { + width: 2px; + left: 0; +} +.ui-dialog .ui-resizable-se, +.ui-dialog .ui-resizable-sw, +.ui-dialog .ui-resizable-ne, +.ui-dialog .ui-resizable-nw { + width: 7px; + height: 7px; +} +.ui-dialog .ui-resizable-se { + right: 0; + bottom: 0; +} +.ui-dialog .ui-resizable-sw { + left: 0; + bottom: 0; +} +.ui-dialog .ui-resizable-ne { + right: 0; + top: 0; +} +.ui-dialog .ui-resizable-nw { + left: 0; + top: 0; +} +.ui-draggable .ui-dialog-titlebar { + cursor: move; +} +.ui-draggable-handle { + -ms-touch-action: none; + touch-action: none; +} +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; + -ms-touch-action: none; + touch-action: none; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} +.ui-progressbar { + height: 2em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw=="); + height: 100%; + filter: alpha(opacity=25); /* support: IE8 */ + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} +.ui-selectable { + -ms-touch-action: none; + touch-action: none; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} +.ui-selectmenu-menu { + padding: 0; + margin: 0; + position: absolute; + top: 0; + left: 0; + display: none; +} +.ui-selectmenu-menu .ui-menu { + overflow: auto; + overflow-x: hidden; + padding-bottom: 1px; +} +.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { + font-size: 1em; + font-weight: bold; + line-height: 1.5; + padding: 2px 0.4em; + margin: 0.5em 0 0 0; + height: auto; + border: 0; +} +.ui-selectmenu-open { + display: block; +} +.ui-selectmenu-text { + display: block; + margin-right: 20px; + overflow: hidden; + text-overflow: ellipsis; +} +.ui-selectmenu-button.ui-button { + text-align: left; + white-space: nowrap; + width: 14em; +} +.ui-selectmenu-icon.ui-icon { + float: right; + margin-top: 0; +} +.ui-slider { + position: relative; + text-align: left; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 1.2em; + height: 1.2em; + cursor: default; + -ms-touch-action: none; + touch-action: none; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0; +} + +/* support: IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: .8em; +} +.ui-slider-horizontal .ui-slider-handle { + top: -.3em; + margin-left: -.6em; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: .8em; + height: 100px; +} +.ui-slider-vertical .ui-slider-handle { + left: -.3em; + margin-left: 0; + margin-bottom: -.6em; +} +.ui-slider-vertical .ui-slider-range { + left: 0; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} +.ui-sortable-handle { + -ms-touch-action: none; + touch-action: none; +} +.ui-spinner { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; +} +.ui-spinner-input { + border: none; + background: none; + color: inherit; + padding: .222em 0; + margin: .2em 0; + vertical-align: middle; + margin-left: .4em; + margin-right: 2em; +} +.ui-spinner-button { + width: 1.6em; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to override default borders */ +.ui-spinner a.ui-spinner-button { + border-top-style: none; + border-bottom-style: none; + border-right-style: none; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ + padding: .2em; +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px .2em 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav .ui-tabs-anchor { + float: left; + padding: .5em 1em; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { + cursor: text; +} +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em 1.4em; + background: none; +} +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px; +} +body .ui-tooltip { + border-width: 2px; +} +/* Component containers +----------------------------------*/ +.ui-widget { + font-family: Arial,Helvetica,sans-serif; + font-size: 1em; +} +.ui-widget .ui-widget { + font-size: 1em; +} +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-family: Arial,Helvetica,sans-serif; + font-size: 1em; +} +.ui-widget.ui-widget-content { + border: 1px solid #c5c5c5; +} +.ui-widget-content { + border: 1px solid #dddddd; + background: #ffffff; + color: #333333; +} +.ui-widget-content a { + color: #333333; +} +.ui-widget-header { + border: 1px solid #dddddd; + background: #e9e9e9; + color: #333333; + font-weight: bold; +} +.ui-widget-header a { + color: #333333; +} + +/* Interaction states +----------------------------------*/ +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default, +.ui-button, + +/* We use html here because we need a greater specificity to make sure disabled +works properly when clicked or hovered */ +html .ui-button.ui-state-disabled:hover, +html .ui-button.ui-state-disabled:active { + border: 1px solid #c5c5c5; + background: #f6f6f6; + font-weight: normal; + color: #454545; +} +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited, +a.ui-button, +a:link.ui-button, +a:visited.ui-button, +.ui-button { + color: #454545; + text-decoration: none; +} +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus, +.ui-button:hover, +.ui-button:focus { + border: 1px solid #cccccc; + background: #ededed; + font-weight: normal; + color: #2b2b2b; +} +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited, +.ui-state-focus a, +.ui-state-focus a:hover, +.ui-state-focus a:link, +.ui-state-focus a:visited, +a.ui-button:hover, +a.ui-button:focus { + color: #2b2b2b; + text-decoration: none; +} + +.ui-visual-focus { + box-shadow: 0 0 3px 1px rgb(94, 158, 214); +} +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +a.ui-button:active, +.ui-button:active, +.ui-button.ui-state-active:hover { + border: 1px solid #003eff; + background: #007fff; + font-weight: normal; + color: #ffffff; +} +.ui-icon-background, +.ui-state-active .ui-icon-background { + border: #003eff; + background-color: #ffffff; +} +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + color: #ffffff; + text-decoration: none; +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #dad55e; + background: #fffa90; + color: #777620; +} +.ui-state-checked { + border: 1px solid #dad55e; + background: #fffa90; +} +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a { + color: #777620; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #f1a899; + background: #fddfdf; + color: #5f3f3f; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a { + color: #5f3f3f; +} +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #5f3f3f; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .7; + filter:Alpha(Opacity=70); /* support: IE8 */ + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .35; + filter:Alpha(Opacity=35); /* support: IE8 */ + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */ +} + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + width: 16px; + height: 16px; +} +.ui-icon, +.ui-widget-content .ui-icon { + background-image: url("images/ui-icons_444444_256x240.png"); +} +.ui-widget-header .ui-icon { + background-image: url("images/ui-icons_444444_256x240.png"); +} +.ui-button .ui-icon { + background-image: url("images/ui-icons_777777_256x240.png"); +} +.ui-state-hover .ui-icon, +.ui-state-focus .ui-icon, +.ui-button:hover .ui-icon, +.ui-button:focus .ui-icon, +.ui-state-default .ui-icon { + background-image: url("images/ui-icons_555555_256x240.png"); +} +.ui-state-active .ui-icon, +.ui-button:active .ui-icon { + background-image: url("images/ui-icons_ffffff_256x240.png"); +} +.ui-state-highlight .ui-icon, +.ui-button .ui-state-highlight.ui-icon { + background-image: url("images/ui-icons_777620_256x240.png"); +} +.ui-state-error .ui-icon, +.ui-state-error-text .ui-icon { + background-image: url("images/ui-icons_cc0000_256x240.png"); +} + +/* positioning */ +.ui-icon-blank { background-position: 16px 16px; } +.ui-icon-caret-1-n { background-position: 0 0; } +.ui-icon-caret-1-ne { background-position: -16px 0; } +.ui-icon-caret-1-e { background-position: -32px 0; } +.ui-icon-caret-1-se { background-position: -48px 0; } +.ui-icon-caret-1-s { background-position: -65px 0; } +.ui-icon-caret-1-sw { background-position: -80px 0; } +.ui-icon-caret-1-w { background-position: -96px 0; } +.ui-icon-caret-1-nw { background-position: -112px 0; } +.ui-icon-caret-2-n-s { background-position: -128px 0; } +.ui-icon-caret-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -65px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -65px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 1px -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl { + border-top-left-radius: 3px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr { + border-top-right-radius: 3px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl { + border-bottom-left-radius: 3px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br { + border-bottom-right-radius: 3px; +} + +/* Overlays */ +.ui-widget-overlay { + background: #aaaaaa; + opacity: .3; + filter: Alpha(Opacity=30); /* support: IE8 */ +} +.ui-widget-shadow { + -webkit-box-shadow: 0px 0px 5px #666666; + box-shadow: 0px 0px 5px #666666; +} diff --git a/Demo.MVC/Content/themes/base/jquery-ui.min.css b/Demo.MVC/Content/themes/base/jquery-ui.min.css new file mode 100644 index 0000000..1f47347 --- /dev/null +++ b/Demo.MVC/Content/themes/base/jquery-ui.min.css @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.12.0 - 2016-07-08 +* http://jqueryui.com +* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;font-size:100%}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-button{padding:.4em 1em;display:inline-block;position:relative;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2em;box-sizing:border-box;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-button-icon-only{text-indent:0}.ui-button-icon-only .ui-icon{position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}.ui-button.ui-icon-notext .ui-icon{padding:0;width:2.1em;height:2.1em;text-indent:-9999px;white-space:nowrap}input.ui-button.ui-icon-notext .ui-icon{width:auto;height:auto;text-indent:0;white-space:normal;padding:.4em 1em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-controlgroup{vertical-align:middle;display:inline-block}.ui-controlgroup > .ui-controlgroup-item{float:left;margin-left:0;margin-right:0}.ui-controlgroup > .ui-controlgroup-item:focus,.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus{z-index:9999}.ui-controlgroup-vertical > .ui-controlgroup-item{display:block;float:none;width:100%;margin-top:0;margin-bottom:0;text-align:left}.ui-controlgroup-vertical .ui-controlgroup-item{box-sizing:border-box}.ui-controlgroup .ui-controlgroup-label{padding:.4em 1em}.ui-controlgroup .ui-controlgroup-label span{font-size:80%}.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item{border-left:none}.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item{border-top:none}.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content{border-right:none}.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content{border-bottom:none}.ui-controlgroup-vertical .ui-spinner-input{width:75%;width:calc( 100% - 2.4em )}.ui-controlgroup-vertical .ui-spinner .ui-spinner-up{border-top-style:solid}.ui-checkboxradio-label .ui-icon-background{box-shadow:inset 1px 1px 1px #ccc;border-radius:.12em;border:none}.ui-checkboxradio-radio-label .ui-icon-background{width:16px;height:16px;border-radius:1em;overflow:visible;border:none}.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon{background-image:none;width:8px;height:8px;border-width:4px;border-style:solid}.ui-checkboxradio-disabled{pointer-events:none}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em}.ui-dialog{position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-n{height:2px;top:0}.ui-dialog .ui-resizable-e{width:2px;right:0}.ui-dialog .ui-resizable-s{height:2px;bottom:0}.ui-dialog .ui-resizable-w{width:2px;left:0}.ui-dialog .ui-resizable-se,.ui-dialog .ui-resizable-sw,.ui-dialog .ui-resizable-ne,.ui-dialog .ui-resizable-nw{width:7px;height:7px}.ui-dialog .ui-resizable-se{right:0;bottom:0}.ui-dialog .ui-resizable-sw{left:0;bottom:0}.ui-dialog .ui-resizable-ne{right:0;top:0}.ui-dialog .ui-resizable-nw{left:0;top:0}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-text{display:block;margin-right:20px;overflow:hidden;text-overflow:ellipsis}.ui-selectmenu-button.ui-button{text-align:left;white-space:nowrap;width:14em}.ui-selectmenu-icon.ui-icon{float:right;margin-top:0}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:.222em 0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:2em}.ui-spinner-button{width:1.6em;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top-style:none;border-bottom-style:none;border-right-style:none}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Arial,Helvetica,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#333}.ui-widget-content a{color:#333}.ui-widget-header{border:1px solid #ddd;background:#e9e9e9;color:#333;font-weight:bold}.ui-widget-header a{color:#333}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #003eff;background:#007fff;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#003eff;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #dad55e;background:#fffa90;color:#777620}.ui-state-checked{border:1px solid #dad55e;background:#fffa90}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#777620}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_444444_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon,.ui-state-default .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_777620_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} \ No newline at end of file diff --git a/Demo.MVC/Content/themes/base/menu.css b/Demo.MVC/Content/themes/base/menu.css new file mode 100644 index 0000000..221fc51 --- /dev/null +++ b/Demo.MVC/Content/themes/base/menu.css @@ -0,0 +1,63 @@ +/*! + * jQuery UI Menu 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/menu/#theming + */ +.ui-menu { + list-style: none; + padding: 0; + margin: 0; + display: block; + outline: none; +} +.ui-menu .ui-menu { + position: absolute; +} +.ui-menu .ui-menu-item { + position: relative; + margin: 0; + padding: 3px 1em 3px .4em; + cursor: pointer; + min-height: 0; /* support: IE7 */ + /* support: IE10, see #8844 */ + list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"); +} +.ui-menu .ui-menu-divider { + margin: 5px 0; + height: 0; + font-size: 0; + line-height: 0; + border-width: 1px 0 0 0; +} +.ui-menu .ui-state-focus, +.ui-menu .ui-state-active { + margin: -1px; +} + +/* icon support */ +.ui-menu-icons { + position: relative; +} +.ui-menu-icons .ui-menu-item { + padding-left: 2em; +} + +/* left-aligned */ +.ui-menu .ui-icon { + position: absolute; + top: 0; + bottom: 0; + left: .2em; + margin: auto 0; +} + +/* right-aligned */ +.ui-menu .ui-menu-icon { + left: auto; + right: 0; +} diff --git a/Demo.MVC/Content/themes/base/progressbar.css b/Demo.MVC/Content/themes/base/progressbar.css new file mode 100644 index 0000000..5e43600 --- /dev/null +++ b/Demo.MVC/Content/themes/base/progressbar.css @@ -0,0 +1,28 @@ +/*! + * jQuery UI Progressbar 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/progressbar/#theming + */ +.ui-progressbar { + height: 2em; + text-align: left; + overflow: hidden; +} +.ui-progressbar .ui-progressbar-value { + margin: -1px; + height: 100%; +} +.ui-progressbar .ui-progressbar-overlay { + background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw=="); + height: 100%; + filter: alpha(opacity=25); /* support: IE8 */ + opacity: 0.25; +} +.ui-progressbar-indeterminate .ui-progressbar-value { + background-image: none; +} diff --git a/Demo.MVC/Content/themes/base/resizable.css b/Demo.MVC/Content/themes/base/resizable.css new file mode 100644 index 0000000..23d9a07 --- /dev/null +++ b/Demo.MVC/Content/themes/base/resizable.css @@ -0,0 +1,78 @@ +/*! + * jQuery UI Resizable 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ +.ui-resizable { + position: relative; +} +.ui-resizable-handle { + position: absolute; + font-size: 0.1px; + display: block; + -ms-touch-action: none; + touch-action: none; +} +.ui-resizable-disabled .ui-resizable-handle, +.ui-resizable-autohide .ui-resizable-handle { + display: none; +} +.ui-resizable-n { + cursor: n-resize; + height: 7px; + width: 100%; + top: -5px; + left: 0; +} +.ui-resizable-s { + cursor: s-resize; + height: 7px; + width: 100%; + bottom: -5px; + left: 0; +} +.ui-resizable-e { + cursor: e-resize; + width: 7px; + right: -5px; + top: 0; + height: 100%; +} +.ui-resizable-w { + cursor: w-resize; + width: 7px; + left: -5px; + top: 0; + height: 100%; +} +.ui-resizable-se { + cursor: se-resize; + width: 12px; + height: 12px; + right: 1px; + bottom: 1px; +} +.ui-resizable-sw { + cursor: sw-resize; + width: 9px; + height: 9px; + left: -5px; + bottom: -5px; +} +.ui-resizable-nw { + cursor: nw-resize; + width: 9px; + height: 9px; + left: -5px; + top: -5px; +} +.ui-resizable-ne { + cursor: ne-resize; + width: 9px; + height: 9px; + right: -5px; + top: -5px; +} diff --git a/Demo.MVC/Content/themes/base/selectable.css b/Demo.MVC/Content/themes/base/selectable.css new file mode 100644 index 0000000..482597c --- /dev/null +++ b/Demo.MVC/Content/themes/base/selectable.css @@ -0,0 +1,17 @@ +/*! + * jQuery UI Selectable 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ +.ui-selectable { + -ms-touch-action: none; + touch-action: none; +} +.ui-selectable-helper { + position: absolute; + z-index: 100; + border: 1px dotted black; +} diff --git a/Demo.MVC/Content/themes/base/selectmenu.css b/Demo.MVC/Content/themes/base/selectmenu.css new file mode 100644 index 0000000..2417b6b --- /dev/null +++ b/Demo.MVC/Content/themes/base/selectmenu.css @@ -0,0 +1,59 @@ +/*! + * jQuery UI Selectmenu 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/selectmenu/#theming + */ +.ui-selectmenu-menu { + padding: 0; + margin: 0; + position: absolute; + top: 0; + left: 0; + display: none; +} +.ui-selectmenu-menu .ui-menu { + overflow: auto; + /* Support: IE7 */ + overflow-x: hidden; + padding-bottom: 1px; +} +.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup { + font-size: 1em; + font-weight: bold; + line-height: 1.5; + padding: 2px 0.4em; + margin: 0.5em 0 0 0; + height: auto; + border: 0; +} +.ui-selectmenu-open { + display: block; +} +.ui-selectmenu-button { + display: inline-block; + overflow: hidden; + position: relative; + text-decoration: none; + cursor: pointer; +} +.ui-selectmenu-button span.ui-icon { + right: 0.5em; + left: auto; + margin-top: -8px; + position: absolute; + top: 50%; +} +.ui-selectmenu-button span.ui-selectmenu-text { + text-align: left; + padding: 0.4em 2.1em 0.4em 1em; + display: block; + line-height: 1.4; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} diff --git a/Demo.MVC/Content/themes/base/slider.css b/Demo.MVC/Content/themes/base/slider.css new file mode 100644 index 0000000..7c4f01a --- /dev/null +++ b/Demo.MVC/Content/themes/base/slider.css @@ -0,0 +1,75 @@ +/*! + * jQuery UI Slider 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/slider/#theming + */ +.ui-slider { + position: relative; + text-align: left; +} +.ui-slider .ui-slider-handle { + position: absolute; + z-index: 2; + width: 1.2em; + height: 1.2em; + cursor: default; + -ms-touch-action: none; + touch-action: none; +} +.ui-slider .ui-slider-range { + position: absolute; + z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0; +} + +/* support: IE8 - See #6727 */ +.ui-slider.ui-state-disabled .ui-slider-handle, +.ui-slider.ui-state-disabled .ui-slider-range { + filter: inherit; +} + +.ui-slider-horizontal { + height: .8em; +} +.ui-slider-horizontal .ui-slider-handle { + top: -.3em; + margin-left: -.6em; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} + +.ui-slider-vertical { + width: .8em; + height: 100px; +} +.ui-slider-vertical .ui-slider-handle { + left: -.3em; + margin-left: 0; + margin-bottom: -.6em; +} +.ui-slider-vertical .ui-slider-range { + left: 0; + width: 100%; +} +.ui-slider-vertical .ui-slider-range-min { + bottom: 0; +} +.ui-slider-vertical .ui-slider-range-max { + top: 0; +} diff --git a/Demo.MVC/Content/themes/base/sortable.css b/Demo.MVC/Content/themes/base/sortable.css new file mode 100644 index 0000000..1c27bad --- /dev/null +++ b/Demo.MVC/Content/themes/base/sortable.css @@ -0,0 +1,12 @@ +/*! + * jQuery UI Sortable 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + */ +.ui-sortable-handle { + -ms-touch-action: none; + touch-action: none; +} diff --git a/Demo.MVC/Content/themes/base/spinner.css b/Demo.MVC/Content/themes/base/spinner.css new file mode 100644 index 0000000..9a9b78b --- /dev/null +++ b/Demo.MVC/Content/themes/base/spinner.css @@ -0,0 +1,65 @@ +/*! + * jQuery UI Spinner 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/spinner/#theming + */ +.ui-spinner { + position: relative; + display: inline-block; + overflow: hidden; + padding: 0; + vertical-align: middle; +} +.ui-spinner-input { + border: none; + background: none; + color: inherit; + padding: 0; + margin: .2em 0; + vertical-align: middle; + margin-left: .4em; + margin-right: 22px; +} +.ui-spinner-button { + width: 16px; + height: 50%; + font-size: .5em; + padding: 0; + margin: 0; + text-align: center; + position: absolute; + cursor: default; + display: block; + overflow: hidden; + right: 0; +} +/* more specificity required here to override default borders */ +.ui-spinner a.ui-spinner-button { + border-top: none; + border-bottom: none; + border-right: none; +} +/* vertically center icon */ +.ui-spinner .ui-icon { + position: absolute; + margin-top: -8px; + top: 50%; + left: 0; +} +.ui-spinner-up { + top: 0; +} +.ui-spinner-down { + bottom: 0; +} + +/* TR overrides */ +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position: -65px -16px; +} diff --git a/Demo.MVC/Content/themes/base/tabs.css b/Demo.MVC/Content/themes/base/tabs.css new file mode 100644 index 0000000..c92a1b8 --- /dev/null +++ b/Demo.MVC/Content/themes/base/tabs.css @@ -0,0 +1,51 @@ +/*! + * jQuery UI Tabs 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/tabs/#theming + */ +.ui-tabs { + position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ + padding: .2em; +} +.ui-tabs .ui-tabs-nav { + margin: 0; + padding: .2em .2em 0; +} +.ui-tabs .ui-tabs-nav li { + list-style: none; + float: left; + position: relative; + top: 0; + margin: 1px .2em 0 0; + border-bottom-width: 0; + padding: 0; + white-space: nowrap; +} +.ui-tabs .ui-tabs-nav .ui-tabs-anchor { + float: left; + padding: .5em 1em; + text-decoration: none; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active { + margin-bottom: -1px; + padding-bottom: 1px; +} +.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor, +.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor { + cursor: text; +} +.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor { + cursor: pointer; +} +.ui-tabs .ui-tabs-panel { + display: block; + border-width: 0; + padding: 1em 1.4em; + background: none; +} diff --git a/Demo.MVC/Content/themes/base/theme.css b/Demo.MVC/Content/themes/base/theme.css new file mode 100644 index 0000000..da972f5 --- /dev/null +++ b/Demo.MVC/Content/themes/base/theme.css @@ -0,0 +1,444 @@ +/*! + * jQuery UI CSS Framework 1.12.0 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/category/theming/ + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Arial%2CHelvetica%2Csans-serif&fsDefault=1em&fwDefault=normal&cornerRadius=3px&bgColorHeader=e9e9e9&bgTextureHeader=flat&borderColorHeader=dddddd&fcHeader=333333&iconColorHeader=444444&bgColorContent=ffffff&bgTextureContent=flat&borderColorContent=dddddd&fcContent=333333&iconColorContent=444444&bgColorDefault=f6f6f6&bgTextureDefault=flat&borderColorDefault=c5c5c5&fcDefault=454545&iconColorDefault=777777&bgColorHover=ededed&bgTextureHover=flat&borderColorHover=cccccc&fcHover=2b2b2b&iconColorHover=555555&bgColorActive=007fff&bgTextureActive=flat&borderColorActive=003eff&fcActive=ffffff&iconColorActive=ffffff&bgColorHighlight=fffa90&bgTextureHighlight=flat&borderColorHighlight=dad55e&fcHighlight=777620&iconColorHighlight=777620&bgColorError=fddfdf&bgTextureError=flat&borderColorError=f1a899&fcError=5f3f3f&iconColorError=cc0000&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=666666&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=5px&offsetTopShadow=0px&offsetLeftShadow=0px&cornerRadiusShadow=8px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { + font-family: Arial,Helvetica,sans-serif; + font-size: 1em; +} +.ui-widget .ui-widget { + font-size: 1em; +} +.ui-widget input, +.ui-widget select, +.ui-widget textarea, +.ui-widget button { + font-family: Arial,Helvetica,sans-serif; + font-size: 1em; +} +.ui-widget.ui-widget-content { + border: 1px solid #c5c5c5; +} +.ui-widget-content { + border: 1px solid #dddddd; + background: #ffffff; + color: #333333; +} +.ui-widget-content a { + color: #333333; +} +.ui-widget-header { + border: 1px solid #dddddd; + background: #e9e9e9; + color: #333333; + font-weight: bold; +} +.ui-widget-header a { + color: #333333; +} + +/* Interaction states +----------------------------------*/ +.ui-state-default, +.ui-widget-content .ui-state-default, +.ui-widget-header .ui-state-default, +.ui-button, + +/* We use html here because we need a greater specificity to make sure disabled +works properly when clicked or hovered */ +html .ui-button.ui-state-disabled:hover, +html .ui-button.ui-state-disabled:active { + border: 1px solid #c5c5c5; + background: #f6f6f6; + font-weight: normal; + color: #454545; +} +.ui-state-default a, +.ui-state-default a:link, +.ui-state-default a:visited, +a.ui-button, +a:link.ui-button, +a:visited.ui-button, +.ui-button { + color: #454545; + text-decoration: none; +} +.ui-state-hover, +.ui-widget-content .ui-state-hover, +.ui-widget-header .ui-state-hover, +.ui-state-focus, +.ui-widget-content .ui-state-focus, +.ui-widget-header .ui-state-focus, +.ui-button:hover, +.ui-button:focus { + border: 1px solid #cccccc; + background: #ededed; + font-weight: normal; + color: #2b2b2b; +} +.ui-state-hover a, +.ui-state-hover a:hover, +.ui-state-hover a:link, +.ui-state-hover a:visited, +.ui-state-focus a, +.ui-state-focus a:hover, +.ui-state-focus a:link, +.ui-state-focus a:visited, +a.ui-button:hover, +a.ui-button:focus { + color: #2b2b2b; + text-decoration: none; +} + +.ui-visual-focus { + box-shadow: 0 0 3px 1px rgb(94, 158, 214); +} +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +a.ui-button:active, +.ui-button:active, +.ui-button.ui-state-active:hover { + border: 1px solid #003eff; + background: #007fff; + font-weight: normal; + color: #ffffff; +} +.ui-icon-background, +.ui-state-active .ui-icon-background { + border: #003eff; + background-color: #ffffff; +} +.ui-state-active a, +.ui-state-active a:link, +.ui-state-active a:visited { + color: #ffffff; + text-decoration: none; +} + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, +.ui-widget-content .ui-state-highlight, +.ui-widget-header .ui-state-highlight { + border: 1px solid #dad55e; + background: #fffa90; + color: #777620; +} +.ui-state-checked { + border: 1px solid #dad55e; + background: #fffa90; +} +.ui-state-highlight a, +.ui-widget-content .ui-state-highlight a, +.ui-widget-header .ui-state-highlight a { + color: #777620; +} +.ui-state-error, +.ui-widget-content .ui-state-error, +.ui-widget-header .ui-state-error { + border: 1px solid #f1a899; + background: #fddfdf; + color: #5f3f3f; +} +.ui-state-error a, +.ui-widget-content .ui-state-error a, +.ui-widget-header .ui-state-error a { + color: #5f3f3f; +} +.ui-state-error-text, +.ui-widget-content .ui-state-error-text, +.ui-widget-header .ui-state-error-text { + color: #5f3f3f; +} +.ui-priority-primary, +.ui-widget-content .ui-priority-primary, +.ui-widget-header .ui-priority-primary { + font-weight: bold; +} +.ui-priority-secondary, +.ui-widget-content .ui-priority-secondary, +.ui-widget-header .ui-priority-secondary { + opacity: .7; + filter:Alpha(Opacity=70); /* support: IE8 */ + font-weight: normal; +} +.ui-state-disabled, +.ui-widget-content .ui-state-disabled, +.ui-widget-header .ui-state-disabled { + opacity: .35; + filter:Alpha(Opacity=35); /* support: IE8 */ + background-image: none; +} +.ui-state-disabled .ui-icon { + filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */ +} + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { + width: 16px; + height: 16px; +} +.ui-icon, +.ui-widget-content .ui-icon { + background-image: url("images/ui-icons_444444_256x240.png"); +} +.ui-widget-header .ui-icon { + background-image: url("images/ui-icons_444444_256x240.png"); +} +.ui-button .ui-icon { + background-image: url("images/ui-icons_777777_256x240.png"); +} +.ui-state-hover .ui-icon, +.ui-state-focus .ui-icon, +.ui-button:hover .ui-icon, +.ui-button:focus .ui-icon, +.ui-state-default .ui-icon { + background-image: url("images/ui-icons_555555_256x240.png"); +} +.ui-state-active .ui-icon, +.ui-button:active .ui-icon { + background-image: url("images/ui-icons_ffffff_256x240.png"); +} +.ui-state-highlight .ui-icon, +.ui-button .ui-state-highlight.ui-icon { + background-image: url("images/ui-icons_777620_256x240.png"); +} +.ui-state-error .ui-icon, +.ui-state-error-text .ui-icon { + background-image: url("images/ui-icons_cc0000_256x240.png"); +} + +/* positioning */ +.ui-icon-blank { background-position: 16px 16px; } +.ui-icon-caret-1-n { background-position: 0 0; } +.ui-icon-caret-1-ne { background-position: -16px 0; } +.ui-icon-caret-1-e { background-position: -32px 0; } +.ui-icon-caret-1-se { background-position: -48px 0; } +.ui-icon-caret-1-s { background-position: -65px 0; } +.ui-icon-caret-1-sw { background-position: -80px 0; } +.ui-icon-caret-1-w { background-position: -96px 0; } +.ui-icon-caret-1-nw { background-position: -112px 0; } +.ui-icon-caret-2-n-s { background-position: -128px 0; } +.ui-icon-caret-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -65px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -65px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 1px -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, +.ui-corner-top, +.ui-corner-left, +.ui-corner-tl { + border-top-left-radius: 3px; +} +.ui-corner-all, +.ui-corner-top, +.ui-corner-right, +.ui-corner-tr { + border-top-right-radius: 3px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-left, +.ui-corner-bl { + border-bottom-left-radius: 3px; +} +.ui-corner-all, +.ui-corner-bottom, +.ui-corner-right, +.ui-corner-br { + border-bottom-right-radius: 3px; +} + +/* Overlays */ +.ui-widget-overlay { + background: #aaaaaa; + opacity: .3; + filter: Alpha(Opacity=30); /* support: IE8 */ +} +.ui-widget-shadow { + -webkit-box-shadow: 0px 0px 5px #666666; + box-shadow: 0px 0px 5px #666666; +} diff --git a/Demo.MVC/Content/themes/base/tooltip.css b/Demo.MVC/Content/themes/base/tooltip.css new file mode 100644 index 0000000..6eb8b91 --- /dev/null +++ b/Demo.MVC/Content/themes/base/tooltip.css @@ -0,0 +1,21 @@ +/*! + * jQuery UI Tooltip 1.11.4 + * http://jqueryui.com + * + * Copyright jQuery Foundation and other contributors + * Released under the MIT license. + * http://jquery.org/license + * + * http://api.jqueryui.com/tooltip/#theming + */ +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +body .ui-tooltip { + border-width: 2px; +} diff --git a/Demo.MVC/Controllers/HomeController.cs b/Demo.MVC/Controllers/HomeController.cs new file mode 100644 index 0000000..80ae87d --- /dev/null +++ b/Demo.MVC/Controllers/HomeController.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.Mvc; + +namespace Demo.MVC.Controllers +{ + public class HomeController : Controller + { + // GET: Home + public ActionResult Index() + { + return View(); + } + } +} \ No newline at end of file diff --git a/Demo.MVC/Demo.MVC.csproj b/Demo.MVC/Demo.MVC.csproj index 4c28463..ab6d103 100644 --- a/Demo.MVC/Demo.MVC.csproj +++ b/Demo.MVC/Demo.MVC.csproj @@ -1,5 +1,6 @@  - + + Debug @@ -8,12 +9,12 @@ 2.0 {9164611E-4CAF-4FE1-B707-397CC1D515C0} - {E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} Library Properties Demo.MVC Demo.MVC - v4.0 + v4.8 false true @@ -23,6 +24,16 @@ ..\ true + true + + + + + 4.0 + + + + true @@ -32,6 +43,7 @@ DEBUG;TRACE prompt 4 + false pdbonly @@ -40,8 +52,15 @@ TRACE prompt 4 + false + + ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll + + + ..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.SqlServer.dll + @@ -52,51 +71,43 @@ - - - - - - - - ..\packages\EntityFramework.5.0.0\lib\net45\EntityFramework.dll - - - True - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll - - True - ..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.Helpers.dll + + ..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll - - True - ..\packages\Microsoft.AspNet.Mvc.3.0.20105.1\lib\net40\System.Web.Mvc.dll + + ..\packages\Microsoft.AspNet.Providers.Core.2.0.0\lib\net40\System.Web.Providers.dll - - ..\packages\Microsoft.AspNet.Providers.Core.1.1\lib\net40\System.Web.Providers.dll + + ..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll - - True - ..\packages\Microsoft.AspNet.Razor.1.0.20105.408\lib\net40\System.Web.Razor.dll + + + ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll - - True - ..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.dll + + ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll - - True - ..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.Deployment.dll + + ..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll - + + + + + True - ..\packages\Microsoft.AspNet.WebPages.1.0.20105.408\lib\net40\System.Web.WebPages.Razor.dll + ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + Global.asax @@ -105,7 +116,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Web.config @@ -117,16 +180,19 @@ + - - + + {2c258fae-97ed-4916-b5a3-4723700d675d} + CalCli.API + {471ea68f-fb1f-4df8-aac1-31022c7316ab} CalDav.Server @@ -136,6 +202,12 @@ CalDav + + + + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) @@ -152,9 +224,9 @@ True True - 0 + 49970 / - http://localhost:59780/ + http://localhost:49970/ False False @@ -165,6 +237,14 @@ + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + - - - - - - + + + + + + + diff --git a/Demo.MVC/Web.config b/Demo.MVC/Web.config index fa06dd1..7c35679 100644 --- a/Demo.MVC/Web.config +++ b/Demo.MVC/Web.config @@ -1,4 +1,4 @@ - + -
+
- - - + + + + + - + - + - - - - - - + + + + + + - + - + - + - + + - + - - - - - - - - - - - - - + + + + - + \ No newline at end of file diff --git a/Demo.MVC/packages.config b/Demo.MVC/packages.config index bb29542..b776f6b 100644 --- a/Demo.MVC/packages.config +++ b/Demo.MVC/packages.config @@ -1,14 +1,14 @@  - - - - - - - - - + + + + + + + + + - + \ No newline at end of file diff --git a/Demo.WPF/App.config b/Demo.WPF/App.config index 8e15646..4bfa005 100644 --- a/Demo.WPF/App.config +++ b/Demo.WPF/App.config @@ -1,6 +1,6 @@ - + - + - \ No newline at end of file + diff --git a/Demo.WPF/Demo.WPF.csproj b/Demo.WPF/Demo.WPF.csproj index 4690144..156bfdf 100644 --- a/Demo.WPF/Demo.WPF.csproj +++ b/Demo.WPF/Demo.WPF.csproj @@ -1,5 +1,5 @@  - + Debug @@ -9,10 +9,11 @@ Properties CalDav.WPF CalDav.WPF - v4.5 + v4.8 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 + AnyCPU diff --git a/Demo.WPF/MainWindow.xaml.cs b/Demo.WPF/MainWindow.xaml.cs index 29fdea6..7833b0c 100644 --- a/Demo.WPF/MainWindow.xaml.cs +++ b/Demo.WPF/MainWindow.xaml.cs @@ -17,64 +17,65 @@ public MainWindow() { CalDav.Client.Calendar _Calendar; void MainWindow_Loaded(object sender, RoutedEventArgs e) { - _Server = new CalDav.Client.Server("https://www.google.com/calendar/dav/andy.edinborough@gmail.com/events/", "andy.edinborough@gmail.com", "Gboey6Emo!"); - _Calendar = _Server.GetCalendars().FirstOrDefault(); + // CalCli.API.IConnection c = + //_Server = new CalDav.Client.Server("https://www.google.com/calendar/dav/andy.edinborough@gmail.com/events/", c, "andy.edinborough@gmail.com", "Gboey6Emo!"); + //_Calendar = _Server.GetCalendars().FirstOrDefault(); - this.AsyncUI(_Calendar.Initialize, () => lblCalendarName.Content = _Calendar.Name); - LoadEvents(); + //this.AsyncUI(_Calendar.Initialize, () => lblCalendarName.Content = _Calendar.Name); + //LoadEvents(); } void LoadEvents() { - this.AsyncUI(() => { - var now = DateTime.UtcNow; - var from = new DateTime(now.Year, now.Month, 1); - var to = from.AddMonths(1); - return _Calendar.Search(CalDav.CalendarQuery.SearchEvents(from, to)); - }, results => { - lbEvents.Items.Clear(); - var events = results.SelectMany(x => x.Events); - lbEvents.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; - foreach (var evnt in events) { - var grid = new Grid(); - grid.Margin = new Thickness(0); - grid.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; - grid.ColumnDefinitions.Add(new ColumnDefinition { }); - grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(90) }); - grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(90) }); + //this.AsyncUI(() => { + // var now = DateTime.UtcNow; + // var from = new DateTime(now.Year, now.Month, 1); + // var to = from.AddMonths(1); + // //return _Calendar.Search(CalDav.CalendarQuery.SearchEvents(from, to)); + //}, results => { + // lbEvents.Items.Clear(); + // var events = results.SelectMany(x => x.Events); + // lbEvents.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; + // foreach (var evnt in events) { + // var grid = new Grid(); + // grid.Margin = new Thickness(0); + // grid.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; + // grid.ColumnDefinitions.Add(new ColumnDefinition { }); + // grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(90) }); + // grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(90) }); - var lbl = new Label { Content = evnt.Start.Value.ToShortDateString() + " " + evnt.Summary }; - grid.Children.Add(lbl); - Grid.SetColumn(lbl, 0); + // var lbl = new Label { Content = evnt.Start.Value.ToShortDateString() + " " + evnt.Summary }; + // grid.Children.Add(lbl); + // Grid.SetColumn(lbl, 0); - var btn = new Button { - Content = "Tomorrow" - }; - btn.Click += (sender, ee) => { - evnt.Start = DateTime.UtcNow.AddDays(1).Date; - btn.IsEnabled = false; - this.AsyncUI(() => _Calendar.Save(evnt), LoadEvents); - }; - btn.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; - btn.Margin = new Thickness(0); - grid.Children.Add(btn); - Grid.SetColumn(btn, 1); + // var btn = new Button { + // Content = "Tomorrow" + // }; + // btn.Click += (sender, ee) => { + // evnt.Start = DateTime.UtcNow.AddDays(1).Date; + // btn.IsEnabled = false; + // this.AsyncUI(() => _Calendar.Save(evnt), LoadEvents); + // }; + // btn.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; + // btn.Margin = new Thickness(0); + // grid.Children.Add(btn); + // Grid.SetColumn(btn, 1); - var btn2 = new Button { - Content = "Next Week" - }; - btn2.Click += (sender, ee) => { - evnt.Start = DateTime.UtcNow.AddDays(7).Date; - btn2.IsEnabled = false; - this.AsyncUI(() => _Calendar.Save(evnt), LoadEvents); - }; - btn2.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; - btn2.Margin = new Thickness(0); - grid.Children.Add(btn2); - Grid.SetColumn(btn2, 2); + // var btn2 = new Button { + // Content = "Next Week" + // }; + // btn2.Click += (sender, ee) => { + // evnt.Start = DateTime.UtcNow.AddDays(7).Date; + // btn2.IsEnabled = false; + // this.AsyncUI(() => _Calendar.Save(evnt), LoadEvents); + // }; + // btn2.HorizontalAlignment = System.Windows.HorizontalAlignment.Right; + // btn2.Margin = new Thickness(0); + // grid.Children.Add(btn2); + // Grid.SetColumn(btn2, 2); - lbEvents.Items.Add(grid); - } - }); + // lbEvents.Items.Add(grid); + // } + //}); } } } diff --git a/Demo.WPF/Properties/Resources.Designer.cs b/Demo.WPF/Properties/Resources.Designer.cs index 7e330c6..e491474 100644 --- a/Demo.WPF/Properties/Resources.Designer.cs +++ b/Demo.WPF/Properties/Resources.Designer.cs @@ -1,62 +1,63 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.17929 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Demo.WPF.Properties { - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if ((resourceMan == null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Demo.WPF.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } +namespace CalDav.WPF.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("CalDav.WPF.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } } diff --git a/Demo.WPF/Properties/Settings.Designer.cs b/Demo.WPF/Properties/Settings.Designer.cs index 41e5749..ec997b9 100644 --- a/Demo.WPF/Properties/Settings.Designer.cs +++ b/Demo.WPF/Properties/Settings.Designer.cs @@ -1,26 +1,26 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.17929 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ -namespace Demo.WPF.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } +namespace CalDav.WPF.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } } diff --git a/OutlookClient/OutlookAlarm.cs b/OutlookClient/OutlookAlarm.cs new file mode 100644 index 0000000..dfbbba7 --- /dev/null +++ b/OutlookClient/OutlookAlarm.cs @@ -0,0 +1,63 @@ +using System; +using CalCli.API; +using Outlook = Microsoft.Office.Interop.Outlook; +using CalDav; +namespace OutlookClient { + public class OutlookAlarm : IAlarm + { + public OutlookAlarm(Outlook.Application application) + { + this.application = application; + } + + Outlook.Reminder reminder; + public AlarmActions Action + { + get + { + return AlarmActions.DISPLAY; + } + + set + { + if(value != AlarmActions.DISPLAY) + throw new Exception("Outlook supports display type only."); + } + } + + public string Description + { + get + { + return reminder.Caption; + } + + set + { + throw new Exception("Description cannot be set for Outlook alarm."); + } + } + + private Trigger trigger; + private Outlook.Application application; + + public ITrigger Trigger + { + get + { + if (trigger == null) + return new Trigger() + { + DateTime = reminder.OriginalReminderDate + }; + else + return trigger; + } + + set + { + trigger = (Trigger)value; + } + } + } +} diff --git a/OutlookClient/OutlookCalendar.cs b/OutlookClient/OutlookCalendar.cs new file mode 100644 index 0000000..b57c9bb --- /dev/null +++ b/OutlookClient/OutlookCalendar.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Xml.Linq; +using CalCli.API; +using Outlook = Microsoft.Office.Interop.Outlook; +using OutlookClient; +using System.Runtime.InteropServices; + +namespace OutlookClient { + public class OutlookCalendar : ICalendar + { + private Outlook.Application application; + public OutlookCalendar(Outlook.Application app) + { + this.application = app; + } + public string Description + { + get + { + return "Outlook calendar."; + } + + set + { + throw new Exception("Description for outlook calendar is readonly. "); + } + } + + public string Name + { + get + { + return "Outlook calendar."; + } + + set + { + throw new Exception("Name for outlook calendar is readonly. "); + } + } + + public IAlarm createAlarm() + { + return new OutlookAlarm(application); + } + + public IEvent createEvent() + { + return new OutlookEvent(application); + } + + public IToDo createToDo() + { + return new OutlookToDo(application); + } + + public ITrigger createTrigger() + { + return new CalDav.Trigger(); + } + + public void Save(IToDo t) + { + Outlook.TaskItem item = ((OutlookToDo)t).TaskItem; + item.Assign(); + item.Save(); + sync(); + } + + public void Save(IEvent e) + { + Outlook.AppointmentItem item = ((OutlookEvent)e).Appointment; + item.Save(); + sync(); + } + + private void sync() + { + + Outlook.NameSpace ns = application.GetNamespace("MAPI"); + ns.SendAndReceive(false); + if (ns != null) Marshal.ReleaseComObject(ns); + } + } +} diff --git a/OutlookClient/OutlookClient.csproj b/OutlookClient/OutlookClient.csproj new file mode 100644 index 0000000..f05a7b2 --- /dev/null +++ b/OutlookClient/OutlookClient.csproj @@ -0,0 +1,101 @@ + + + + + Debug + AnyCPU + {01AF789A-F9CE-47F7-A66C-D3BAE82AECC3} + Library + Properties + OutlookClient + OutlookClient + v4.8 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + ..\packages\Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.4.0.209160138-alpha\lib\net45\Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.dll + True + + + ..\packages\Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.4.0.209160138-alpha\lib\net45\Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory.Platform.dll + True + + + ..\packages\Microsoft.Office.Interop.Outlook.15.0.4797.1003\lib\net20\Microsoft.Office.Interop.Outlook.dll + True + + + + + + + + + + + + + + + + + + + + + + + + {2c258fae-97ed-4916-b5a3-4723700d675d} + CalCli.API + + + {01a4c4cf-5ad1-4324-a391-dc922c84be1c} + CalDav + + + + + + + + + {00020430-0000-0000-C000-000000000046} + 2 + 0 + 0 + primary + False + True + + + + + \ No newline at end of file diff --git a/OutlookClient/OutlookConnection.cs b/OutlookClient/OutlookConnection.cs new file mode 100644 index 0000000..126c065 --- /dev/null +++ b/OutlookClient/OutlookConnection.cs @@ -0,0 +1,14 @@ +using System.Net; +using CalCli.API; +//using Microsoft.Experimental.IdentityModel.Clients.ActiveDirectory; + +namespace CalCli.Connections +{ + public class OutlookConnection : IConnection + { + public WebRequest Authorize(WebRequest request) + { + return request; + } + } +} diff --git a/OutlookClient/OutlookEvent.cs b/OutlookClient/OutlookEvent.cs new file mode 100644 index 0000000..f2772cc --- /dev/null +++ b/OutlookClient/OutlookEvent.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using CalCli.API; +using CalDav; +using Outlook = Microsoft.Office.Interop.Outlook; + +namespace OutlookClient { + public class OutlookEvent : IEvent + { + public Outlook.AppointmentItem Appointment { get { return appointment; } } + Outlook.Application application; + Outlook.AppointmentItem appointment; + public OutlookEvent(Outlook.Application app) + { + application = app; + appointment = app.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olAppointmentItem); + } + public ICollection Alarms + { + get + { + return new List { + new OutlookAlarm(application) + { + Action = AlarmActions.DISPLAY, + Trigger = new Trigger() + { + DateTime = appointment.Start.AddMinutes(-appointment.ReminderMinutesBeforeStart) + } + + } + }; + } + + set + { + if (Alarms.Count > 1) + throw new Exception("Outlook doesn't support multiple alarms."); + else + { + if (Alarms.Count == 0) + appointment.ReminderSet = false; + else + { + appointment.ReminderSet = true; + if(value.First().Trigger.DateTime != null) + { + value.First().Trigger.Duration = value.First().Trigger.DateTime - appointment.Start; + } + appointment.ReminderMinutesBeforeStart = 1;// (int)value.First().Trigger.Duration.Value.TotalMinutes; + } + } + } + } + + public ICollection Categories + { + get + { + return new List { appointment.Categories }; + } + + set + { + appointment.Categories = ""; + foreach (string category in value) + { + appointment.Categories += value + ";"; + } + + } + } + + public DateTime? Created + { + get + { + return appointment.CreationTime; + } + + set + { + throw new Exception("Creation time is read only using outlook. It is automatically set. "); + } + } + + public string Description + { + get + { + return appointment.Body; + } + + set + { + appointment.Body = value; + } + } + + public DateTime? End + { + get + { + return appointment.End; + } + + set + { + if (value == null) + throw new Exception("End cannot be null."); + appointment.End = (DateTime)value; + } + } + + public DateTime? Start + { + get + { + return appointment.Start; + } + + set + { + if(value == null) + throw new Exception("Start cannot be null."); + appointment.Start = (DateTime)value; + + } + } + + public string Summary + { + get + { + return appointment.Subject; + } + + set + { + appointment.Subject = value; + } + } + + public string UID + { + get; set; + } + + public Uri Url + { + get + { + throw new Exception("Url doesn't make sence for outlook calendar."); + } + + set + { + throw new Exception("Url doesn't make sence for outlook calendar."); + } + } + } +} diff --git a/OutlookClient/OutlookServer.cs b/OutlookClient/OutlookServer.cs new file mode 100644 index 0000000..6885282 --- /dev/null +++ b/OutlookClient/OutlookServer.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; +using CalCli.API; +using Outlook = Microsoft.Office.Interop.Outlook; + +namespace OutlookClient { + public class OutlookServer : IServer + { + Outlook.Application application = new Outlook.Application(); + public IConnection Connection + { + get + { + return null; + } + + set + { + + } + } + + public Uri Url + { + get + { + return null; + } + + set + { + + } + } + + public void CreateCalendar(ICalendar calendar) + { + throw new Exception("Outlook doesn't support creating calendars."); + } + + public ICalendar[] GetCalendars() + { + return new ICalendar[] { new OutlookCalendar(application) }; + } + } +} diff --git a/OutlookClient/OutlookToDo.cs b/OutlookClient/OutlookToDo.cs new file mode 100644 index 0000000..4fbe74c --- /dev/null +++ b/OutlookClient/OutlookToDo.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using CalCli.API; +using Outlook = Microsoft.Office.Interop.Outlook; + +namespace OutlookClient { + public class OutlookToDo : IToDo{ + Outlook.TaskItem taskItem; + + public ICollection Categories + { + get + { + return new List { taskItem.Categories }; + } + + set + { + taskItem.Categories = ""; + foreach (string category in value) + { + taskItem.Categories += value + ";"; + } + + } + } + + public DateTime? Completed + { + get + { + return taskItem.DateCompleted; + } + + set + { + if(value == null) + throw new Exception("Completion date cannot be null."); + taskItem.DateCompleted = (DateTime)value; + } + } + + public DateTime? Due + { + get + { + return taskItem.DueDate; + } + + set + { + + if (value == null) + throw new Exception("Due cannot be null."); + taskItem.DueDate = (DateTime)value; + } + } + + public int? Priority + { + get + { + throw new Exception("Not supported for outlook."); + } + + set + { + throw new Exception("Not supported for outlook."); + } + } + + public int? Sequence + { + get + { + return (int)(taskItem.DueDate - taskItem.StartDate).TotalSeconds; + } + + set + { + if(taskItem.DueDate != null && taskItem.StartDate != null) + { + throw new Exception("Dates are already set."); + } + + } + } + + + public DateTime? Start + { + get + { + return taskItem.StartDate; + } + + set + { + if (value == null) + throw new Exception("Start cannot be null."); + taskItem.StartDate = (DateTime)value; + + } + } + + public Statuses? Status + { + get + { + if (taskItem.Complete) + return Statuses.COMPLETED; + else + return Statuses.NEEDS_ACTION; + } + + set + { + taskItem.Complete = value == Statuses.COMPLETED; + } + } + + public string Summary + { + get + { + return taskItem.Subject; + } + + set + { + taskItem.Subject = value; + } + } + + public string UID + { + get; set; + } + public Outlook.TaskItem TaskItem + { + get + { + return taskItem; + } + } + + public OutlookToDo(Outlook.Application app) { + taskItem = app.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olTaskItem); + } + } +} diff --git a/OutlookClient/Properties/AssemblyInfo.cs b/OutlookClient/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..cf045c2 --- /dev/null +++ b/OutlookClient/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("OutlookClient")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OutlookClient")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("01af789a-f9ce-47f7-a66c-d3bae82aecc3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/OutlookClient/packages.config b/OutlookClient/packages.config new file mode 100644 index 0000000..2c7ff9d --- /dev/null +++ b/OutlookClient/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f093b01 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# CalDav +CalDav server and client libraries. It supports Google, iCloud, Yahoo and Outlook calendars. + +# Installation + +It is hosted on [NuGet gallery](https://www.nuget.org/packages/CalCli/) and can be installed as is described there. + +# Development + +Any pull requests whould be appreciated. diff --git a/Tests/IRLTests.cs b/Tests/IRLTests.cs index 98539fa..4c13af6 100644 --- a/Tests/IRLTests.cs +++ b/Tests/IRLTests.cs @@ -10,7 +10,7 @@ public class IRLTests { public void ParseFeed() { var calendar = new CalDav.Calendar(); var serializer = new Serializer(); - var req = System.Net.HttpWebRequest.Create("http://www.nasa.gov/templateimages/redesign/calendar/iCal/nasa_calendar.ics"); + var req = System.Net.HttpWebRequest.Create("https://canada-holidays.ca/ics"); using (var res = req.GetResponse()) using (var str = res.GetResponseStream()) using (var rdr = new System.IO.StreamReader(str)) @@ -24,13 +24,13 @@ public void ParseICal() { //http://blogs.nologin.es/rickyepoderi/index.php?/archives/14-Introducing-CalDAV-Part-I.html //http://blogs.nologin.es/rickyepoderi/index.php?/archives/15-Introducing-CalDAV-Part-II.html - var server = new CalDav.Client.Server("https://www.google.com/calendar/dav/andy.edinborough@gmail.com/events/", "andy.edinborough@gmail.com", "Gboey6Emo!"); - var calendars = server.GetCalendars(); - calendars.ShouldNotBeEmpty(); + //var server = new CalDav.Client.Server("https://www.google.com/calendar/dav/andy.edinborough@gmail.com/events/", "andy.edinborough@gmail.com", "Gboey6Emo!"); + //var calendars = server.GetCalendars(); + //calendars.ShouldNotBeEmpty(); - var calendar = calendars[0]; - var events = calendar.Search(CalendarQuery.SearchEvents(new DateTime(2012, 8, 1), new DateTime(2012, 8, 31))).ToArray(); - events.Length.ShouldBeGreaterThan(0); + //var calendar = calendars[0]; + //var events = calendar.Search(CalendarQuery.SearchEvents(new DateTime(2012, 8, 1), new DateTime(2012, 8, 31))).ToArray(); + //events.Length.ShouldBeGreaterThan(0); } } diff --git a/Tests/ParsingBasic.cs b/Tests/ParsingBasic.cs index 10acca5..6ba28c1 100644 --- a/Tests/ParsingBasic.cs +++ b/Tests/ParsingBasic.cs @@ -1,4 +1,5 @@ -using CalDav; +using CalCli.API; +using CalDav; using Microsoft.VisualStudio.TestTools.UnitTesting; using Shouldly; using System; @@ -65,7 +66,7 @@ public void Trigger() { text = "TRIGGER;RELATED=END:-P1W3DT2H3M45S"; trigger = Deserialize(text); - trigger.Related.ShouldBe(CalDav.Trigger.Relateds.End); + trigger.Related.ShouldBe(Relateds.End); trigger.Duration.ShouldBe(-(new TimeSpan(1 * 7 + 3, 2, 3, 45, 0))); text2 = Serialize("TRIGGER", trigger); text2.ShouldBe(text); diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 0c1ddd8..9683fc7 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -8,7 +8,7 @@ Properties Tests Tests - v4.5 + v4.8 512 {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 10.0 @@ -18,6 +18,7 @@ UnitTest ..\ true + true @@ -63,6 +64,10 @@ + + {2c258fae-97ed-4916-b5a3-4723700d675d} + CalCli.API + {1b9b42a0-a34b-4bf6-a5d5-21c46ed0d9b3} CalDav.Client diff --git a/Tests/app.config b/Tests/app.config index 56f696d..8e3607f 100644 --- a/Tests/app.config +++ b/Tests/app.config @@ -1,11 +1,11 @@ - + - - + + - \ No newline at end of file + diff --git a/UpgradeLog.htm b/UpgradeLog.htm new file mode 100644 index 0000000..728ea2b Binary files /dev/null and b/UpgradeLog.htm differ