());
25 | }
26 | foreach (var user in _connectedUsers[groupName])
27 | {
28 | await Clients.Client(Context.ConnectionId).SendAsync("UserConnected", user);
29 | }
30 | if (!_connectedUsers[groupName].Contains(userId))
31 | {
32 | _connectedUsers[groupName].Add(Context.GetHttpContext().Request.Query["UserId"]);
33 | }
34 | await Groups.AddToGroupAsync(Context.ConnectionId, Context.GetHttpContext().Request.Query["RecordId"]);
35 |
36 | await Clients.GroupExcept(groupName, Context.ConnectionId).SendAsync("UserConnected", Context.GetHttpContext().Request.Query["UserId"][0]);
37 | }
38 |
39 | public override async Task OnDisconnectedAsync(System.Exception exception)
40 | {
41 | _connectedUsers[Context.GetHttpContext().Request.Query["RecordId"]].Remove(Context.GetHttpContext().Request.Query["UserId"]);
42 | await Groups.RemoveFromGroupAsync(Context.ConnectionId, Context.GetHttpContext().Request.Query["RecordId"]);
43 | await Clients.Group(Context.GetHttpContext().Request.Query["RecordId"]).SendAsync("UserDisconnected", Context.GetHttpContext().Request.Query["UserId"][0]);
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/About.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model AboutModel
3 | @{
4 | ViewData["Title"] = "About";
5 | }
6 | @ViewData["Title"]
7 | @Model.Message
8 |
9 | Use this area to provide additional information.
10 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/About.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc.RazorPages;
6 |
7 | namespace SignalRPresence.Pages
8 | {
9 | public class AboutModel : PageModel
10 | {
11 | public string Message { get; set; }
12 |
13 | public void OnGet()
14 | {
15 | Message = "Your application description page.";
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Contact.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model ContactModel
3 | @{
4 | ViewData["Title"] = "Contact";
5 | }
6 | @ViewData["Title"]
7 | @Model.Message
8 |
9 |
10 | One Microsoft Way
11 | Redmond, WA 98052-6399
12 | P:
13 | 425.555.0100
14 |
15 |
16 |
17 | Support: Support@example.com
18 | Marketing: Marketing@example.com
19 |
20 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Contact.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc.RazorPages;
6 |
7 | namespace SignalRPresence.Pages
8 | {
9 | public class ContactModel : PageModel
10 | {
11 | public string Message { get; set; }
12 |
13 | public void OnGet()
14 | {
15 | Message = "Your contact page.";
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Error.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model ErrorModel
3 | @{
4 | ViewData["Title"] = "Error";
5 | }
6 |
7 | Error.
8 | An error occurred while processing your request.
9 |
10 | @if (Model.ShowRequestId)
11 | {
12 |
13 | Request ID: @Model.RequestId
14 |
15 | }
16 |
17 | Development Mode
18 |
19 | Swapping to Development environment will display more detailed information about the error that occurred.
20 |
21 |
22 | Development environment should not be enabled in deployed applications , as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development , and restarting the application.
23 |
24 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Error.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Diagnostics;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 | using Microsoft.AspNetCore.Mvc;
7 | using Microsoft.AspNetCore.Mvc.RazorPages;
8 |
9 | namespace SignalRPresence.Pages
10 | {
11 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
12 | public class ErrorModel : PageModel
13 | {
14 | public string RequestId { get; set; }
15 |
16 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
17 |
18 | public void OnGet()
19 | {
20 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Index.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 |
25 |
26 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Index.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Microsoft.AspNetCore.Mvc.RazorPages;
7 |
8 | namespace SignalRPresence.Pages
9 | {
10 | public class IndexModel : PageModel
11 | {
12 | public void OnGet()
13 | {
14 |
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Privacy.cshtml:
--------------------------------------------------------------------------------
1 | @page
2 | @model PrivacyModel
3 | @{
4 | ViewData["Title"] = "Privacy Policy";
5 | }
6 | @ViewData["Title"]
7 |
8 | Use this page to detail your site's privacy policy.
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Privacy.cshtml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Mvc;
6 | using Microsoft.AspNetCore.Mvc.RazorPages;
7 |
8 | namespace SignalRPresence.Pages
9 | {
10 | public class PrivacyModel : PageModel
11 | {
12 | public void OnGet()
13 | {
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Shared/_CookieConsentPartial.cshtml:
--------------------------------------------------------------------------------
1 | @using Microsoft.AspNetCore.Http.Features
2 |
3 | @{
4 | var consentFeature = Context.Features.Get();
5 | var showBanner = !consentFeature?.CanTrack ?? false;
6 | var cookieString = consentFeature?.CreateConsentCookie();
7 | }
8 |
9 | @if (showBanner)
10 | {
11 |
12 |
13 |
22 |
23 |
24 | Use this space to summarize your privacy and cookie use policy.
25 |
26 |
30 |
31 |
32 |
33 |
41 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Shared/_Layout.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | @ViewData["Title"] - SignalRPresence
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
39 |
40 |
41 |
42 |
43 |
44 | @RenderBody()
45 |
46 |
47 | © 2019 - SignalRPresence
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
69 |
70 |
71 |
72 | @RenderSection("Scripts", required: false)
73 |
74 |
75 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/Shared/_ValidationScriptsPartial.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using SignalRPresence
2 | @namespace SignalRPresence.Pages
3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
4 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Pages/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Net;
6 | using System.Threading.Tasks;
7 | using Microsoft.AspNetCore;
8 | using Microsoft.AspNetCore.Hosting;
9 | using Microsoft.Extensions.Configuration;
10 | using Microsoft.Extensions.Logging;
11 |
12 | namespace SignalRPresence
13 | {
14 | public class Program
15 | {
16 | public static void Main(string[] args)
17 | {
18 | CreateWebHostBuilder(args).Build().Run();
19 | }
20 |
21 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
22 | WebHost.CreateDefaultBuilder(args)
23 | .UseKestrel(options =>
24 | {
25 | options.Listen(IPAddress.Loopback, 5080);
26 | })
27 | .UseStartup();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:20791",
7 | "sslPort": 44330
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "SignalRPresence": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "applicationUrl": "https://localhost:5001;http://localhost:5000",
22 | "environmentVariables": {
23 | "ASPNETCORE_ENVIRONMENT": "Development"
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/SignalRPresence.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp2.1
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Microsoft.AspNetCore.Builder;
6 | using Microsoft.AspNetCore.Hosting;
7 | using Microsoft.AspNetCore.Http;
8 | using Microsoft.AspNetCore.HttpsPolicy;
9 | using Microsoft.AspNetCore.Mvc;
10 | using Microsoft.Extensions.Configuration;
11 | using Microsoft.Extensions.DependencyInjection;
12 | using SignalRChat.Hubs;
13 |
14 | namespace SignalRPresence
15 | {
16 | public class Startup
17 | {
18 | public Startup(IConfiguration configuration)
19 | {
20 | Configuration = configuration;
21 | }
22 |
23 | public IConfiguration Configuration { get; }
24 |
25 | // This method gets called by the runtime. Use this method to add services to the container.
26 | public void ConfigureServices(IServiceCollection services)
27 | {
28 | services.Configure(options =>
29 | {
30 | // This lambda determines whether user consent for non-essential cookies is needed for a given request.
31 | options.CheckConsentNeeded = context => true;
32 | options.MinimumSameSitePolicy = SameSiteMode.None;
33 | });
34 |
35 |
36 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
37 |
38 | services.AddSignalR();
39 | }
40 |
41 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
42 | public void Configure(IApplicationBuilder app, IHostingEnvironment env)
43 | {
44 | if (env.IsDevelopment())
45 | {
46 | app.UseDeveloperExceptionPage();
47 | app.UseCors(builder =>
48 | {
49 | builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials();
50 | });
51 | }
52 | else
53 | {
54 | app.UseExceptionHandler("/Error");
55 | app.UseHsts();
56 | }
57 |
58 | app.UseHttpsRedirection();
59 | app.UseStaticFiles();
60 | app.UseCookiePolicy();
61 | app.UseSignalR(routes =>
62 | {
63 | routes.MapHub("/d365Hub");
64 | });
65 | app.UseMvc();
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Debug",
5 | "System": "Information",
6 | "Microsoft": "Information"
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Warning"
5 | }
6 | },
7 | "AllowedHosts": "*"
8 | }
9 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/libman.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.0",
3 | "defaultProvider": "unpkg",
4 | "libraries": [
5 | {
6 | "library": "@aspnet/signalr@1.1.4",
7 | "destination": "wwwroot/lib/signalr",
8 | "files": [
9 | "dist/browser/signalr.js",
10 | "dist/browser/signalr.min.js"
11 | ]
12 | }
13 | ]
14 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/css/site.css:
--------------------------------------------------------------------------------
1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
2 | for details on configuring this project to bundle and minify static web assets. */
3 | body {
4 | padding-top: 50px;
5 | padding-bottom: 20px;
6 | }
7 |
8 | /* Wrapping element */
9 | /* Set some basic padding to keep content from hitting the edges */
10 | .body-content {
11 | padding-left: 15px;
12 | padding-right: 15px;
13 | }
14 |
15 | /* Carousel */
16 | .carousel-caption p {
17 | font-size: 20px;
18 | line-height: 1.4;
19 | }
20 |
21 | /* Make .svg files in the carousel display properly in older browsers */
22 | .carousel-inner .item img[src$=".svg"] {
23 | width: 100%;
24 | }
25 |
26 | /* QR code generator */
27 | #qrCode {
28 | margin: 15px;
29 | }
30 |
31 | /* Hide/rearrange for smaller screens */
32 | @media screen and (max-width: 767px) {
33 | /* Hide captions */
34 | .carousel-caption {
35 | display: none;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/css/site.min.css:
--------------------------------------------------------------------------------
1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}#qrCode{margin:15px}@media screen and (max-width:767px){.carousel-caption{display:none}}
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenLBartle/PCF-Components/fd21a6e41ba6f2907f182393d99c30092fb0a645/SignalRPresence/Server/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/images/banner1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/images/banner2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/images/banner3.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/js/chat.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | function makeid(length) {
4 | var result = '';
5 | var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
6 | var charactersLength = characters.length;
7 | for ( var i = 0; i < length; i++ ) {
8 | result += characters.charAt(Math.floor(Math.random() * charactersLength));
9 | }
10 | return result;
11 | }
12 |
13 | var connection = new signalR.HubConnectionBuilder().withUrl("/d365Hub/?UserId=Ben" + makeid(5) + "&RecordId=1").build();
14 |
15 | //Disable send button until connection is established
16 | document.getElementById("sendButton").disabled = true;
17 |
18 | connection.on("ReceiveMessage", function (user, message) {
19 | var msg = message.replace(/&/g, "&").replace(//g, ">");
20 | var encodedMsg = user + " says " + msg;
21 | var li = document.createElement("li");
22 | li.textContent = encodedMsg;
23 | document.getElementById("messagesList").appendChild(li);
24 | });
25 |
26 | connection.on("UserConnected", function (user) {
27 | var encodedMsg = user + " connected";
28 | var li = document.createElement("li");
29 | li.textContent = encodedMsg;
30 | document.getElementById("messagesList").appendChild(li);
31 | });
32 |
33 | connection.on("UserDisconnected", function (user) {
34 | var encodedMsg = user + " disconnected";
35 | var li = document.createElement("li");
36 | li.textContent = encodedMsg;
37 | document.getElementById("messagesList").appendChild(li);
38 | });
39 |
40 | connection.start().then(function(){
41 | document.getElementById("sendButton").disabled = false;
42 | }).catch(function (err) {
43 | return console.error(err.toString());
44 | });
45 |
46 | document.getElementById("sendButton").addEventListener("click", function (event) {
47 | var user = document.getElementById("userInput").value;
48 | var message = document.getElementById("messageInput").value;
49 | connection.invoke("SendMessage", user, message).catch(function (err) {
50 | return console.error(err.toString());
51 | });
52 | event.preventDefault();
53 | });
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/js/site.js:
--------------------------------------------------------------------------------
1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
2 | // for details on configuring this project to bundle and minify static web assets.
3 |
4 | // Write your Javascript code.
5 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/js/site.min.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenLBartle/PCF-Components/fd21a6e41ba6f2907f182393d99c30092fb0a645/SignalRPresence/Server/wwwroot/js/site.min.js
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/bootstrap/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap",
3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
4 | "keywords": [
5 | "css",
6 | "js",
7 | "less",
8 | "mobile-first",
9 | "responsive",
10 | "front-end",
11 | "framework",
12 | "web"
13 | ],
14 | "homepage": "http://getbootstrap.com",
15 | "license": "MIT",
16 | "moduleType": "globals",
17 | "main": [
18 | "less/bootstrap.less",
19 | "dist/js/bootstrap.js"
20 | ],
21 | "ignore": [
22 | "/.*",
23 | "_config.yml",
24 | "CNAME",
25 | "composer.json",
26 | "CONTRIBUTING.md",
27 | "docs",
28 | "js/tests",
29 | "test-infra"
30 | ],
31 | "dependencies": {
32 | "jquery": "1.9.1 - 3"
33 | },
34 | "version": "3.3.7",
35 | "_release": "3.3.7",
36 | "_resolution": {
37 | "type": "version",
38 | "tag": "v3.3.7",
39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
40 | },
41 | "_source": "https://github.com/twbs/bootstrap.git",
42 | "_target": "v3.3.7",
43 | "_originalSource": "bootstrap",
44 | "_direct": true
45 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/bootstrap/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2011-2016 Twitter, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/css/bootstrap-theme.min.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * Bootstrap v3.3.7 (http://getbootstrap.com)
3 | * Copyright 2011-2016 Twitter, Inc.
4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
5 | */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)}
6 | /*# sourceMappingURL=bootstrap-theme.min.css.map */
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenLBartle/PCF-Components/fd21a6e41ba6f2907f182393d99c30092fb0a645/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenLBartle/PCF-Components/fd21a6e41ba6f2907f182393d99c30092fb0a645/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenLBartle/PCF-Components/fd21a6e41ba6f2907f182393d99c30092fb0a645/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenLBartle/PCF-Components/fd21a6e41ba6f2907f182393d99c30092fb0a645/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/bootstrap/dist/js/npm.js:
--------------------------------------------------------------------------------
1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
2 | require('../../js/transition.js')
3 | require('../../js/alert.js')
4 | require('../../js/button.js')
5 | require('../../js/carousel.js')
6 | require('../../js/collapse.js')
7 | require('../../js/dropdown.js')
8 | require('../../js/modal.js')
9 | require('../../js/tooltip.js')
10 | require('../../js/popover.js')
11 | require('../../js/scrollspy.js')
12 | require('../../js/tab.js')
13 | require('../../js/affix.js')
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery-validation-unobtrusive/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-validation-unobtrusive",
3 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive",
4 | "version": "3.2.9",
5 | "_release": "3.2.9",
6 | "_resolution": {
7 | "type": "version",
8 | "tag": "v3.2.9",
9 | "commit": "a91f5401898e125f10771c5f5f0909d8c4c82396"
10 | },
11 | "_source": "https://github.com/aspnet/jquery-validation-unobtrusive.git",
12 | "_target": "^3.2.9",
13 | "_originalSource": "jquery-validation-unobtrusive",
14 | "_direct": true
15 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) .NET Foundation. All rights reserved.
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
4 | these files except in compliance with the License. You may obtain a copy of the
5 | License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software distributed
10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
12 | specific language governing permissions and limitations under the License.
13 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js:
--------------------------------------------------------------------------------
1 | // Unobtrusive validation support library for jQuery and jQuery Validate
2 | // Copyright (C) Microsoft Corporation. All rights reserved.
3 | // @version v3.2.9
4 |
5 | /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
6 | /*global document: false, jQuery: false */
7 |
8 | (function (factory) {
9 | if (typeof define === 'function' && define.amd) {
10 | // AMD. Register as an anonymous module.
11 | define("jquery.validate.unobtrusive", ['jquery.validation'], factory);
12 | } else if (typeof module === 'object' && module.exports) {
13 | // CommonJS-like environments that support module.exports
14 | module.exports = factory(require('jquery-validation'));
15 | } else {
16 | // Browser global
17 | jQuery.validator.unobtrusive = factory(jQuery);
18 | }
19 | }(function ($) {
20 | var $jQval = $.validator,
21 | adapters,
22 | data_validation = "unobtrusiveValidation";
23 |
24 | function setValidationValues(options, ruleName, value) {
25 | options.rules[ruleName] = value;
26 | if (options.message) {
27 | options.messages[ruleName] = options.message;
28 | }
29 | }
30 |
31 | function splitAndTrim(value) {
32 | return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
33 | }
34 |
35 | function escapeAttributeValue(value) {
36 | // As mentioned on http://api.jquery.com/category/selectors/
37 | return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
38 | }
39 |
40 | function getModelPrefix(fieldName) {
41 | return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
42 | }
43 |
44 | function appendModelPrefix(value, prefix) {
45 | if (value.indexOf("*.") === 0) {
46 | value = value.replace("*.", prefix);
47 | }
48 | return value;
49 | }
50 |
51 | function onError(error, inputElement) { // 'this' is the form element
52 | var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
53 | replaceAttrValue = container.attr("data-valmsg-replace"),
54 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
55 |
56 | container.removeClass("field-validation-valid").addClass("field-validation-error");
57 | error.data("unobtrusiveContainer", container);
58 |
59 | if (replace) {
60 | container.empty();
61 | error.removeClass("input-validation-error").appendTo(container);
62 | }
63 | else {
64 | error.hide();
65 | }
66 | }
67 |
68 | function onErrors(event, validator) { // 'this' is the form element
69 | var container = $(this).find("[data-valmsg-summary=true]"),
70 | list = container.find("ul");
71 |
72 | if (list && list.length && validator.errorList.length) {
73 | list.empty();
74 | container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
75 |
76 | $.each(validator.errorList, function () {
77 | $(" ").html(this.message).appendTo(list);
78 | });
79 | }
80 | }
81 |
82 | function onSuccess(error) { // 'this' is the form element
83 | var container = error.data("unobtrusiveContainer");
84 |
85 | if (container) {
86 | var replaceAttrValue = container.attr("data-valmsg-replace"),
87 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
88 |
89 | container.addClass("field-validation-valid").removeClass("field-validation-error");
90 | error.removeData("unobtrusiveContainer");
91 |
92 | if (replace) {
93 | container.empty();
94 | }
95 | }
96 | }
97 |
98 | function onReset(event) { // 'this' is the form element
99 | var $form = $(this),
100 | key = '__jquery_unobtrusive_validation_form_reset';
101 | if ($form.data(key)) {
102 | return;
103 | }
104 | // Set a flag that indicates we're currently resetting the form.
105 | $form.data(key, true);
106 | try {
107 | $form.data("validator").resetForm();
108 | } finally {
109 | $form.removeData(key);
110 | }
111 |
112 | $form.find(".validation-summary-errors")
113 | .addClass("validation-summary-valid")
114 | .removeClass("validation-summary-errors");
115 | $form.find(".field-validation-error")
116 | .addClass("field-validation-valid")
117 | .removeClass("field-validation-error")
118 | .removeData("unobtrusiveContainer")
119 | .find(">*") // If we were using valmsg-replace, get the underlying error
120 | .removeData("unobtrusiveContainer");
121 | }
122 |
123 | function validationInfo(form) {
124 | var $form = $(form),
125 | result = $form.data(data_validation),
126 | onResetProxy = $.proxy(onReset, form),
127 | defaultOptions = $jQval.unobtrusive.options || {},
128 | execInContext = function (name, args) {
129 | var func = defaultOptions[name];
130 | func && $.isFunction(func) && func.apply(form, args);
131 | };
132 |
133 | if (!result) {
134 | result = {
135 | options: { // options structure passed to jQuery Validate's validate() method
136 | errorClass: defaultOptions.errorClass || "input-validation-error",
137 | errorElement: defaultOptions.errorElement || "span",
138 | errorPlacement: function () {
139 | onError.apply(form, arguments);
140 | execInContext("errorPlacement", arguments);
141 | },
142 | invalidHandler: function () {
143 | onErrors.apply(form, arguments);
144 | execInContext("invalidHandler", arguments);
145 | },
146 | messages: {},
147 | rules: {},
148 | success: function () {
149 | onSuccess.apply(form, arguments);
150 | execInContext("success", arguments);
151 | }
152 | },
153 | attachValidation: function () {
154 | $form
155 | .off("reset." + data_validation, onResetProxy)
156 | .on("reset." + data_validation, onResetProxy)
157 | .validate(this.options);
158 | },
159 | validate: function () { // a validation function that is called by unobtrusive Ajax
160 | $form.validate();
161 | return $form.valid();
162 | }
163 | };
164 | $form.data(data_validation, result);
165 | }
166 |
167 | return result;
168 | }
169 |
170 | $jQval.unobtrusive = {
171 | adapters: [],
172 |
173 | parseElement: function (element, skipAttach) {
174 | ///
175 | /// Parses a single HTML element for unobtrusive validation attributes.
176 | ///
177 | /// The HTML element to be parsed.
178 | /// [Optional] true to skip attaching the
179 | /// validation to the form. If parsing just this single element, you should specify true.
180 | /// If parsing several elements, you should specify false, and manually attach the validation
181 | /// to the form when you are finished. The default is false.
182 | var $element = $(element),
183 | form = $element.parents("form")[0],
184 | valInfo, rules, messages;
185 |
186 | if (!form) { // Cannot do client-side validation without a form
187 | return;
188 | }
189 |
190 | valInfo = validationInfo(form);
191 | valInfo.options.rules[element.name] = rules = {};
192 | valInfo.options.messages[element.name] = messages = {};
193 |
194 | $.each(this.adapters, function () {
195 | var prefix = "data-val-" + this.name,
196 | message = $element.attr(prefix),
197 | paramValues = {};
198 |
199 | if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
200 | prefix += "-";
201 |
202 | $.each(this.params, function () {
203 | paramValues[this] = $element.attr(prefix + this);
204 | });
205 |
206 | this.adapt({
207 | element: element,
208 | form: form,
209 | message: message,
210 | params: paramValues,
211 | rules: rules,
212 | messages: messages
213 | });
214 | }
215 | });
216 |
217 | $.extend(rules, { "__dummy__": true });
218 |
219 | if (!skipAttach) {
220 | valInfo.attachValidation();
221 | }
222 | },
223 |
224 | parse: function (selector) {
225 | ///
226 | /// Parses all the HTML elements in the specified selector. It looks for input elements decorated
227 | /// with the [data-val=true] attribute value and enables validation according to the data-val-*
228 | /// attribute values.
229 | ///
230 | /// Any valid jQuery selector.
231 |
232 | // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
233 | // element with data-val=true
234 | var $selector = $(selector),
235 | $forms = $selector.parents()
236 | .addBack()
237 | .filter("form")
238 | .add($selector.find("form"))
239 | .has("[data-val=true]");
240 |
241 | $selector.find("[data-val=true]").each(function () {
242 | $jQval.unobtrusive.parseElement(this, true);
243 | });
244 |
245 | $forms.each(function () {
246 | var info = validationInfo(this);
247 | if (info) {
248 | info.attachValidation();
249 | }
250 | });
251 | }
252 | };
253 |
254 | adapters = $jQval.unobtrusive.adapters;
255 |
256 | adapters.add = function (adapterName, params, fn) {
257 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.
258 | /// The name of the adapter to be added. This matches the name used
259 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
260 | /// [Optional] An array of parameter names (strings) that will
261 | /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
262 | /// mmmm is the parameter name).
263 | /// The function to call, which adapts the values from the HTML
264 | /// attributes into jQuery Validate rules and/or messages.
265 | ///
266 | if (!fn) { // Called with no params, just a function
267 | fn = params;
268 | params = [];
269 | }
270 | this.push({ name: adapterName, params: params, adapt: fn });
271 | return this;
272 | };
273 |
274 | adapters.addBool = function (adapterName, ruleName) {
275 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
276 | /// the jQuery Validate validation rule has no parameter values.
277 | /// The name of the adapter to be added. This matches the name used
278 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
279 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value
280 | /// of adapterName will be used instead.
281 | ///
282 | return this.add(adapterName, function (options) {
283 | setValidationValues(options, ruleName || adapterName, true);
284 | });
285 | };
286 |
287 | adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
288 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
289 | /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
290 | /// one for min-and-max). The HTML parameters are expected to be named -min and -max.
291 | /// The name of the adapter to be added. This matches the name used
292 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
293 | /// The name of the jQuery Validate rule to be used when you only
294 | /// have a minimum value.
295 | /// The name of the jQuery Validate rule to be used when you only
296 | /// have a maximum value.
297 | /// The name of the jQuery Validate rule to be used when you
298 | /// have both a minimum and maximum value.
299 | /// [Optional] The name of the HTML attribute that
300 | /// contains the minimum value. The default is "min".
301 | /// [Optional] The name of the HTML attribute that
302 | /// contains the maximum value. The default is "max".
303 | ///
304 | return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
305 | var min = options.params.min,
306 | max = options.params.max;
307 |
308 | if (min && max) {
309 | setValidationValues(options, minMaxRuleName, [min, max]);
310 | }
311 | else if (min) {
312 | setValidationValues(options, minRuleName, min);
313 | }
314 | else if (max) {
315 | setValidationValues(options, maxRuleName, max);
316 | }
317 | });
318 | };
319 |
320 | adapters.addSingleVal = function (adapterName, attribute, ruleName) {
321 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
322 | /// the jQuery Validate validation rule has a single value.
323 | /// The name of the adapter to be added. This matches the name used
324 | /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).
325 | /// [Optional] The name of the HTML attribute that contains the value.
326 | /// The default is "val".
327 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value
328 | /// of adapterName will be used instead.
329 | ///
330 | return this.add(adapterName, [attribute || "val"], function (options) {
331 | setValidationValues(options, ruleName || adapterName, options.params[attribute]);
332 | });
333 | };
334 |
335 | $jQval.addMethod("__dummy__", function (value, element, params) {
336 | return true;
337 | });
338 |
339 | $jQval.addMethod("regex", function (value, element, params) {
340 | var match;
341 | if (this.optional(element)) {
342 | return true;
343 | }
344 |
345 | match = new RegExp(params).exec(value);
346 | return (match && (match.index === 0) && (match[0].length === value.length));
347 | });
348 |
349 | $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
350 | var match;
351 | if (nonalphamin) {
352 | match = value.match(/\W/g);
353 | match = match && match.length >= nonalphamin;
354 | }
355 | return match;
356 | });
357 |
358 | if ($jQval.methods.extension) {
359 | adapters.addSingleVal("accept", "mimtype");
360 | adapters.addSingleVal("extension", "extension");
361 | } else {
362 | // for backward compatibility, when the 'extension' validation method does not exist, such as with versions
363 | // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
364 | // validating the extension, and ignore mime-type validations as they are not supported.
365 | adapters.addSingleVal("extension", "extension", "accept");
366 | }
367 |
368 | adapters.addSingleVal("regex", "pattern");
369 | adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
370 | adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
371 | adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
372 | adapters.add("equalto", ["other"], function (options) {
373 | var prefix = getModelPrefix(options.element.name),
374 | other = options.params.other,
375 | fullOtherName = appendModelPrefix(other, prefix),
376 | element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
377 |
378 | setValidationValues(options, "equalTo", element);
379 | });
380 | adapters.add("required", function (options) {
381 | // jQuery Validate equates "required" with "mandatory" for checkbox elements
382 | if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
383 | setValidationValues(options, "required", true);
384 | }
385 | });
386 | adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
387 | var value = {
388 | url: options.params.url,
389 | type: options.params.type || "GET",
390 | data: {}
391 | },
392 | prefix = getModelPrefix(options.element.name);
393 |
394 | $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
395 | var paramName = appendModelPrefix(fieldName, prefix);
396 | value.data[paramName] = function () {
397 | var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
398 | // For checkboxes and radio buttons, only pick up values from checked fields.
399 | if (field.is(":checkbox")) {
400 | return field.filter(":checked").val() || field.filter(":hidden").val() || '';
401 | }
402 | else if (field.is(":radio")) {
403 | return field.filter(":checked").val() || '';
404 | }
405 | return field.val();
406 | };
407 | });
408 |
409 | setValidationValues(options, "remote", value);
410 | });
411 | adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
412 | if (options.params.min) {
413 | setValidationValues(options, "minlength", options.params.min);
414 | }
415 | if (options.params.nonalphamin) {
416 | setValidationValues(options, "nonalphamin", options.params.nonalphamin);
417 | }
418 | if (options.params.regex) {
419 | setValidationValues(options, "regex", options.params.regex);
420 | }
421 | });
422 | adapters.add("fileextensions", ["extensions"], function (options) {
423 | setValidationValues(options, "extension", options.params.extensions);
424 | });
425 |
426 | $(function () {
427 | $jQval.unobtrusive.parse(document);
428 | });
429 |
430 | return $jQval.unobtrusive;
431 | }));
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js:
--------------------------------------------------------------------------------
1 | // Unobtrusive validation support library for jQuery and jQuery Validate
2 | // Copyright (C) Microsoft Corporation. All rights reserved.
3 | // @version v3.2.9
4 | !function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery.validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a(" ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive});
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery-validation/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-validation",
3 | "homepage": "https://jqueryvalidation.org/",
4 | "repository": {
5 | "type": "git",
6 | "url": "git://github.com/jquery-validation/jquery-validation.git"
7 | },
8 | "authors": [
9 | "Jörn Zaefferer "
10 | ],
11 | "description": "Form validation made easy",
12 | "main": "dist/jquery.validate.js",
13 | "keywords": [
14 | "forms",
15 | "validation",
16 | "validate"
17 | ],
18 | "license": "MIT",
19 | "ignore": [
20 | "**/.*",
21 | "node_modules",
22 | "bower_components",
23 | "test",
24 | "demo",
25 | "lib"
26 | ],
27 | "dependencies": {
28 | "jquery": ">= 1.7.2"
29 | },
30 | "version": "1.17.0",
31 | "_release": "1.17.0",
32 | "_resolution": {
33 | "type": "version",
34 | "tag": "1.17.0",
35 | "commit": "fc9b12d3bfaa2d0c04605855b896edb2934c0772"
36 | },
37 | "_source": "https://github.com/jzaefferer/jquery-validation.git",
38 | "_target": "^1.17.0",
39 | "_originalSource": "jquery-validation",
40 | "_direct": true
41 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery-validation/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | =====================
3 |
4 | Copyright Jörn Zaefferer
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery-validation/dist/additional-methods.min.js:
--------------------------------------------------------------------------------
1 | /*! jQuery Validation Plugin - v1.17.0 - 7/29/2017
2 | * https://jqueryvalidation.org/
3 | * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */
4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g,h="string"==typeof d?d.replace(/\s/g,""):"image/*",i=this.optional(c);if(i)return i;if("file"===a(c).attr("type")&&(h=h.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g,"\\$&").replace(/,/g,"|").replace(/\/\*/g,"/.*"),c.files&&c.files.length))for(g=new RegExp(".?("+h+")$","i"),e=0;e9?"0":f,g="JABCDEFGHI".substr(f,1).toString(),i.match(/[ABEH]/)?k===f:i.match(/[KPQS]/)?k===g:k===f||k===g},"Please specify a valid CIF number."),a.validator.addMethod("cpfBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f=0;if(b=parseInt(a.substring(9,10),10),c=parseInt(a.substring(10,11),10),d=function(a,b){var c=10*a%11;return 10!==c&&11!==c||(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(e=1;e<=9;e++)f+=parseInt(a.substring(e-1,e),10)*(11-e);if(d(f,b)){for(f=0,e=1;e<=10;e++)f+=parseInt(a.substring(e-1,e),10)*(12-e);return d(f,c)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcard",function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},"Please enter a valid credit card number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:!!(128&d)},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=!!e||c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="",q=5;if(l.length9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("netmask",function(a,b){return this.optional(b)||/^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test(a)},"Please enter a valid netmask."),a.validator.addMethod("nieES",function(a,b){"use strict";if(this.optional(b))return!0;var c,d=new RegExp(/^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi),e="TRWAGMYFPDXBNJZSQVHLCKET",f=a.substr(a.length-1).toUpperCase();return a=a.toString().toUpperCase(),!(a.length>10||a.length<9||!d.test(a))&&(a=a.replace(/^[X]/,"0").replace(/^[Y]/,"1").replace(/^[Z]/,"2"),c=9===a.length?a.substr(0,8):a.substr(0,9),e.charAt(parseInt(c,10)%23)===f)},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a,b){"use strict";return!!this.optional(b)||(a=a.toUpperCase(),!!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):!!/^[KLM]{1}/.test(a)&&a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,1)%23)))},"Please specify a valid NIF number."),a.validator.addMethod("nipPL",function(a){"use strict";if(a=a.replace(/[^0-9]/g,""),10!==a.length)return!1;for(var b=[6,5,7,2,3,4,5,6,7],c=0,d=0;d<9;d++)c+=b[d]*a[d];var e=c%11,f=10===e?0:e;return f===parseInt(a[9],10)},"Please specify a valid NIP number."),a.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return!!this.optional(b)||("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=!e&&"undefined"!=typeof c.caseSensitive&&c.caseSensitive,g=!e&&"undefined"!=typeof c.includeTerritories&&c.includeTerritories,h=!e&&"undefined"!=typeof c.includeMilitary&&c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;b<17;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c ").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!c.settings.submitHandler||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(null!=j&&(!j.form&&j.hasAttribute("contenteditable")&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr.pseudos||a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){!this.form&&this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name"));var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=d),!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);if("function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f){if(j=f.call(b,j),"string"!=typeof j)throw new TypeError("The normalizer should return a string value.");delete g.normalizer}for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+""),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a});
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery",
3 | "main": "dist/jquery.js",
4 | "license": "MIT",
5 | "ignore": [
6 | "package.json"
7 | ],
8 | "keywords": [
9 | "jquery",
10 | "javascript",
11 | "browser",
12 | "library"
13 | ],
14 | "homepage": "https://github.com/jquery/jquery-dist",
15 | "version": "3.3.1",
16 | "_release": "3.3.1",
17 | "_resolution": {
18 | "type": "version",
19 | "tag": "3.3.1",
20 | "commit": "9e8ec3d10fad04748176144f108d7355662ae75e"
21 | },
22 | "_source": "https://github.com/jquery/jquery-dist.git",
23 | "_target": "^3.3.1",
24 | "_originalSource": "jquery",
25 | "_direct": true
26 | }
--------------------------------------------------------------------------------
/SignalRPresence/Server/wwwroot/lib/jquery/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright JS Foundation and other contributors, https://js.foundation/
2 |
3 | This software consists of voluntary contributions made by many
4 | individuals. For exact contribution history, see the revision history
5 | available at https://github.com/jquery/jquery
6 |
7 | The following license applies to all parts of this software except as
8 | documented below:
9 |
10 | ====
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining
13 | a copy of this software and associated documentation files (the
14 | "Software"), to deal in the Software without restriction, including
15 | without limitation the rights to use, copy, modify, merge, publish,
16 | distribute, sublicense, and/or sell copies of the Software, and to
17 | permit persons to whom the Software is furnished to do so, subject to
18 | the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be
21 | included in all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 |
31 | ====
32 |
33 | All files located in the node_modules and external directories are
34 | externally maintained libraries used by this software which have their
35 | own licenses; we recommend you read them, as their terms may differ from
36 | the terms above.
37 |
--------------------------------------------------------------------------------
/SpeechToText.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BenLBartle/PCF-Components/fd21a6e41ba6f2907f182393d99c30092fb0a645/SpeechToText.png
--------------------------------------------------------------------------------
/SpeechToText/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # generated directory
7 | **/generated
8 |
9 | # output directory
10 | /out
--------------------------------------------------------------------------------
/SpeechToText/SpeechToText.pcfproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SpeechToText
7 | 55c2e6cc-2f17-4ac8-8828-89190eac3d8c
8 | $(MSBuildThisFileDirectory)out\controls
9 |
10 |
11 |
12 | PackageReference
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Always
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/SpeechToText/SpeechToText/ControlManifest.Input.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | SingleLine.Text
8 | SingleLine.TextArea
9 | Multiple
10 |
11 |
12 |
13 |
14 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/SpeechToText/SpeechToText/css/SpeechToText.css:
--------------------------------------------------------------------------------
1 | .input-text {
2 | border: 1px solid #ddd;
3 | min-height: 150px;
4 | text-align: left;
5 | width: 100%;
6 | -webkit-box-sizing: border-box;
7 | -moz-box-sizing: border-box;
8 | box-sizing: border-box;
9 | border: 1px solid transparent;
10 | box-sizing: border-box;
11 | color: #000;
12 | font-family: SegoeUI,"Segoe UI";
13 | font-size: 1rem;
14 | font-style: normal;
15 | font-variant-caps: normal;
16 | font-variant-east-asian: normal;
17 | font-variant-ligatures: normal;
18 | font-variant-numeric: normal;
19 | font-weight: 600;
20 | height: 2.5rem;
21 | margin-left: 0;
22 | margin-right: 0;
23 | outline: none;
24 | padding: 0 .5rem;
25 | text-overflow: ellipsis;
26 | width: 100%;
27 | }
28 |
29 | .input-text:hover {
30 | background-color: #fff;
31 | border-color: #666;
32 | font-weight: 400;
33 | }
34 |
35 | .record-button {
36 | margin: 0;
37 | padding: 0;
38 | display: inline-block;
39 | padding: 5px;
40 | -webkit-appearance: button;
41 | background-color: #fff;
42 | border: 1px solid #6e6f77;
43 | border-radius: 2px;
44 | box-sizing: border-box;
45 | cursor: pointer;
46 | display: flex;
47 | font-family: SegoeUI,"Segoe UI";
48 | font-size: 14px;
49 | font-style: normal;
50 | font-variant-caps: normal;
51 | font-variant-east-asian: normal;
52 | font-variant-ligatures: normal;
53 | font-variant-numeric: normal;
54 | font-weight: 400;
55 | margin: 0;
56 | outline: none;
57 | overflow: visible;
58 |
59 | }
60 |
61 | .record-button:hover {
62 |
63 | background-color: #e8eaec;
64 | border-color: #a4a6ac;
65 | }
66 |
67 | .record-div {
68 | float: right;
69 | }
--------------------------------------------------------------------------------
/SpeechToText/SpeechToText/index.ts:
--------------------------------------------------------------------------------
1 | import { IInputs, IOutputs } from "./generated/ManifestTypes";
2 | const two_line_regex = new RegExp('/\n\n/g;');
3 | const one_line_regex = new RegExp('/\n/g;');
4 | const first_char_regex = new RegExp('/\S/;');
5 | export class SpeechToText implements ComponentFramework.StandardControl {
6 |
7 | private _value: string;
8 |
9 | private _activeButtonText: string = "Click here and start talking 🎙️";
10 | private _inactiveButtonText: string = "I'm listening 👂...";
11 |
12 | private _context: ComponentFramework.Context;
13 |
14 | // PCF framework to notify of changes
15 | private _notifyOutputChanged: () => void;
16 |
17 | // Define Standard container element
18 | private _container: HTMLDivElement;
19 |
20 | // Define Input Elements
21 | public _inputText: HTMLTextAreaElement;
22 |
23 | // Define Button Elements
24 | private _speakNowButton: HTMLButtonElement;
25 |
26 | // Define SpeechRegonition Service
27 | private _speechRecognition: SpeechRecognition;
28 |
29 | private _refreshData: EventListenerOrEventListenerObject;
30 |
31 | /**
32 | * Empty constructor.
33 | */
34 | constructor() {
35 |
36 | }
37 |
38 | /**
39 | * Used to initialize the control instance. Controls can kick off remote server calls and other initialization actions here.
40 | * Data-set values are not initialized here, use updateView.
41 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to property names defined in the manifest, as well as utility functions.
42 | * @param notifyOutputChanged A callback method to alert the framework that the control has new outputs ready to be retrieved asynchronously.
43 | * @param state A piece of data that persists in one session for a single user. Can be set at any point in a controls life cycle by calling 'setControlState' in the Mode interface.
44 | * @param container If a control is marked control-type='starndard', it will receive an empty div element within which it can render its content.
45 | */
46 | public init(context: ComponentFramework.Context, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container: HTMLDivElement) {
47 |
48 | // Add control initialization code
49 | this._context = context;
50 | this._container = document.createElement("div");
51 | this._notifyOutputChanged = notifyOutputChanged;
52 | this._refreshData = this.RefreshData.bind(this);
53 |
54 | // Initialise Value
55 |
56 | // Layout Elements
57 | var divStart = document.createElement("div");
58 | divStart.setAttribute("class", "record-div");
59 |
60 | var divText = document.createElement("div");
61 | //divText.setAttribute("class", "input-text");
62 |
63 | // Input Elements
64 | this._inputText = document.createElement("textarea");
65 | this._inputText.setAttribute("class", "input-text");
66 | this._inputText.value = this._value;
67 | this._inputText.addEventListener("input", this._refreshData);
68 | this._speakNowButton = document.createElement("button");
69 | this._speakNowButton.setAttribute("type", "button");
70 | this._speakNowButton.setAttribute("class", "record-button");
71 | this._speakNowButton.innerText = this._activeButtonText;
72 | this._speakNowButton.addEventListener("click", this.StartSpeechRecognition.bind(this));
73 |
74 | // Initialise Speech Recognition
75 | var typ = typeof SpeechRecognition;
76 | this._speechRecognition = typ === "undefined" ? new webkitSpeechRecognition() : new SpeechRecognition();
77 | this._speechRecognition.lang = 'en-US';
78 | this._speechRecognition.continuous = true;
79 | this._speechRecognition.interimResults = true;
80 |
81 | // Setup DOM
82 | divStart.append(this._speakNowButton);
83 | divText.append(this._inputText);
84 | this._container.append(divStart);
85 | this._container.append(divText);
86 |
87 | // Bind to parent container
88 | container.append(this._container);
89 | }
90 |
91 |
92 | public StartSpeechRecognition() {
93 |
94 | let finalTranscript = '';
95 |
96 | this._speechRecognition.onresult = (event) => {
97 | for (var i = event.resultIndex; i < event.results.length; ++i) {
98 | if (event.results[i].isFinal) {
99 | finalTranscript += event.results[i][0].transcript;
100 | }
101 | }
102 | finalTranscript = finalTranscript.replace(two_line_regex, '
').replace(one_line_regex, ' ');;
103 | this._inputText.value = finalTranscript.replace(first_char_regex, m => { return m.toUpperCase(); });
104 | };
105 |
106 | this._speechRecognition.onend = () => {
107 | this.RefreshData();
108 | this.EnableSpeakNowButton();
109 | };
110 |
111 | this._speechRecognition.onerror = (e) => {
112 | if (e.error === 'audio-capture') {
113 | alert('Failed capturing audio i.e. microphone. Please check console-logs for hints to fix this issue.');
114 | console.error('No microphone was found. Ensure that a microphone is installed and that microphone settings are configured correctly. https://support.google.com/chrome/bin/answer.py?hl=en&answer=1407892');
115 | console.error('Original', e.type, e.message.length || e);
116 | return;
117 | }
118 |
119 | console.error(e.type, e.error, e.message);
120 | }
121 |
122 | this._speechRecognition.start();
123 |
124 | this.DisableSpeakNowButton();
125 | }
126 |
127 | private EnableSpeakNowButton() {
128 | this._speakNowButton.disabled = false;
129 | this._speakNowButton.innerText = this._activeButtonText;
130 | }
131 |
132 | private DisableSpeakNowButton() {
133 | this._speakNowButton.disabled = true;
134 | this._speakNowButton.innerText = this._inactiveButtonText;
135 | }
136 |
137 | public RefreshData() {
138 | this._value = (this._inputText.value as any) as string;
139 | this._notifyOutputChanged();
140 | }
141 |
142 | /**
143 | * Called when any value in the property bag has changed. This includes field values, data-sets, global values such as container height and width, offline status, control metadata values such as label, visible, etc.
144 | * @param context The entire property bag available to control via Context Object; It contains values as set up by the customizer mapped to names defined in the manifest, as well as utility functions
145 | */
146 | public updateView(context: ComponentFramework.Context): void {
147 | // Add code to update control view
148 |
149 | if(context.parameters.textProperty != null){
150 | this._value = context.parameters.textProperty.raw;
151 | }
152 |
153 | this._inputText.value = this._value;
154 | }
155 |
156 | /**
157 | * It is called by the framework prior to a control receiving new data.
158 | * @returns an object based on nomenclature defined in manifest, expecting object[s] for property marked as “bound” or “output”
159 | */
160 | public getOutputs(): IOutputs {
161 | return {
162 | textProperty: this._value
163 | };
164 | }
165 |
166 | /**
167 | * Called when the control is to be removed from the DOM tree. Controls should use this call for cleanup.
168 | * i.e. cancelling any pending remote calls, removing listeners, etc.
169 | */
170 | public destroy(): void {
171 | // Add code to cleanup control if necessary
172 | }
173 | }
--------------------------------------------------------------------------------
/SpeechToText/obj/SpeechToText.pcfproj.nuget.cache:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "dgSpecHash": "0e9ONIzRly/S3cPGmtRWJBLcDpbkMgVGlTY8ZbVhs0CCFMUC+RtwTdUy8YsWoeHyOfAkBqU+dgs+Tf44uv24bA==",
4 | "success": true
5 | }
--------------------------------------------------------------------------------
/SpeechToText/obj/SpeechToText.pcfproj.nuget.g.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | True
5 | NuGet
6 | C:\Users\Ben\source\repos\SpeechToText\obj\project.assets.json
7 | $(UserProfile)\.nuget\packages\
8 | C:\Users\Ben\.nuget\packages\
9 | PackageReference
10 | 4.9.3
11 |
12 |
13 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/SpeechToText/obj/SpeechToText.pcfproj.nuget.g.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/SpeechToText/obj/project.assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 3,
3 | "targets": {
4 | ".NETFramework,Version=v4.0": {
5 | "Microsoft.PowerApps.MSBuild.Pcf/0.1.51": {
6 | "type": "package",
7 | "build": {
8 | "build/Microsoft.PowerApps.MSBuild.Pcf.props": {},
9 | "build/Microsoft.PowerApps.MSBuild.Pcf.targets": {}
10 | }
11 | }
12 | },
13 | ".NETFramework,Version=v4.0/win": {
14 | "Microsoft.PowerApps.MSBuild.Pcf/0.1.51": {
15 | "type": "package",
16 | "build": {
17 | "build/Microsoft.PowerApps.MSBuild.Pcf.props": {},
18 | "build/Microsoft.PowerApps.MSBuild.Pcf.targets": {}
19 | }
20 | }
21 | },
22 | ".NETFramework,Version=v4.0/win-x64": {
23 | "Microsoft.PowerApps.MSBuild.Pcf/0.1.51": {
24 | "type": "package",
25 | "build": {
26 | "build/Microsoft.PowerApps.MSBuild.Pcf.props": {},
27 | "build/Microsoft.PowerApps.MSBuild.Pcf.targets": {}
28 | }
29 | }
30 | },
31 | ".NETFramework,Version=v4.0/win-x86": {
32 | "Microsoft.PowerApps.MSBuild.Pcf/0.1.51": {
33 | "type": "package",
34 | "build": {
35 | "build/Microsoft.PowerApps.MSBuild.Pcf.props": {},
36 | "build/Microsoft.PowerApps.MSBuild.Pcf.targets": {}
37 | }
38 | }
39 | }
40 | },
41 | "libraries": {
42 | "Microsoft.PowerApps.MSBuild.Pcf/0.1.51": {
43 | "sha512": "rN4gm0QPECei9g3Vy1AFv8WG6KxiNIoWH2ZDF7mj3bX+o9f3B0AQWd+SnejulN6FfDwqQbn1PNvzmg49ra2epg==",
44 | "type": "package",
45 | "path": "microsoft.powerapps.msbuild.pcf/0.1.51",
46 | "files": [
47 | ".nupkg.metadata",
48 | ".signature.p7s",
49 | "3rdPartyNotice.txt",
50 | "LICENSE.txt",
51 | "build/Microsoft.PowerApps.MSBuild.Pcf.props",
52 | "build/Microsoft.PowerApps.MSBuild.Pcf.targets",
53 | "microsoft.powerapps.msbuild.pcf.0.1.51.nupkg.sha512",
54 | "microsoft.powerapps.msbuild.pcf.nuspec"
55 | ]
56 | }
57 | },
58 | "projectFileDependencyGroups": {
59 | ".NETFramework,Version=v4.0": [
60 | "Microsoft.PowerApps.MSBuild.Pcf >= 0.1.*"
61 | ]
62 | },
63 | "packageFolders": {
64 | "C:\\Users\\Ben\\.nuget\\packages\\": {}
65 | },
66 | "project": {
67 | "version": "1.0.0",
68 | "restore": {
69 | "projectUniqueName": "C:\\Users\\Ben\\source\\repos\\SpeechToText\\SpeechToText.pcfproj",
70 | "projectName": "SpeechToText",
71 | "projectPath": "C:\\Users\\Ben\\source\\repos\\SpeechToText\\SpeechToText.pcfproj",
72 | "packagesPath": "C:\\Users\\Ben\\.nuget\\packages\\",
73 | "outputPath": "C:\\Users\\Ben\\source\\repos\\SpeechToText\\obj\\",
74 | "projectStyle": "PackageReference",
75 | "skipContentFileWrite": true,
76 | "configFilePaths": [
77 | "C:\\Users\\Ben\\AppData\\Roaming\\NuGet\\NuGet.Config",
78 | "C:\\Program Files (x86)\\NuGet\\Config\\Microsoft.VisualStudio.Offline.config"
79 | ],
80 | "originalTargetFrameworks": [
81 | "net40"
82 | ],
83 | "sources": {
84 | "C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\": {},
85 | "https://api.nuget.org/v3/index.json": {}
86 | },
87 | "frameworks": {
88 | "net40": {
89 | "projectReferences": {}
90 | }
91 | }
92 | },
93 | "frameworks": {
94 | "net40": {
95 | "dependencies": {
96 | "Microsoft.PowerApps.MSBuild.Pcf": {
97 | "target": "Package",
98 | "version": "[0.1.*, )"
99 | }
100 | }
101 | }
102 | },
103 | "runtimes": {
104 | "win": {
105 | "#import": []
106 | },
107 | "win-x64": {
108 | "#import": []
109 | },
110 | "win-x86": {
111 | "#import": []
112 | }
113 | }
114 | }
115 | }
--------------------------------------------------------------------------------
/SpeechToText/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pcf-project",
3 | "version": "1.0.0",
4 | "description": "Project containing your PowerApps Component Framework (PCF) control.",
5 | "scripts": {
6 | "build": "pcf-scripts build",
7 | "clean": "pcf-scripts clean",
8 | "rebuild": "pcf-scripts rebuild",
9 | "start": "pcf-scripts start"
10 | },
11 | "dependencies": {
12 | "@types/node": "^10.12.18",
13 | "@types/powerapps-component-framework": "1.1.0"
14 | },
15 | "devDependencies": {
16 | "@types/webspeechapi": "0.0.29",
17 | "pcf-scripts": "~0",
18 | "pcf-start": "~0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/SpeechToText/pcfconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "outDir": "./out/controls"
3 | }
--------------------------------------------------------------------------------
/SpeechToText/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./node_modules/pcf-scripts/tsconfig_base.json",
3 | "compilerOptions": {
4 | "typeRoots": ["node_modules/@types"],
5 | }
6 | }
--------------------------------------------------------------------------------