From f19721912bd6081ab69f5f81a7c688d5a3ee7427 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 12 Feb 2012 01:52:51 -0800 Subject: [PATCH] SignalR added to provide realtime episode status updates. (Series/Details and Downloading only currently) --- NzbDrone.Core/NzbDrone.Core.csproj | 7 + NzbDrone.Core/Providers/DownloadProvider.cs | 7 +- NzbDrone.Core/Providers/SignalRProvider.cs | 31 + NzbDrone.Core/packages.config | 2 + NzbDrone.Web/NzbDrone.Web.csproj | 12 +- .../media/js/jquery.validate.js | 1150 ----------------- NzbDrone.Web/Scripts/NzbDrone/grid.js | 34 +- NzbDrone.Web/Scripts/jquery.signalR.js | 885 +++++++++++++ NzbDrone.Web/Scripts/jquery.signalR.min.js | 1 + NzbDrone.Web/Views/Series/Episode.cshtml | 4 +- .../Views/Shared/_ReferenceLayout.cshtml | 4 +- NzbDrone.Web/packages.config | 4 + .../SignalR.Hosting.AspNet.0.4.0.0.nupkg | Bin 0 -> 22547 bytes .../lib/net40/SignalR.Hosting.AspNet.dll | Bin 0 -> 35328 bytes .../SignalR.Js.0.4.0/SignalR.Js.0.4.0.nupkg | Bin 0 -> 13523 bytes .../content/Scripts/jquery.signalR.js | 885 +++++++++++++ .../content/Scripts/jquery.signalR.min.js | 1 + .../SignalR.Server.0.4.0.0.nupkg | Bin 0 -> 59220 bytes .../lib/net40/SignalR.dll | Bin 0 -> 106496 bytes 19 files changed, 1871 insertions(+), 1156 deletions(-) create mode 100644 NzbDrone.Core/Providers/SignalRProvider.cs delete mode 100644 NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.validate.js create mode 100644 NzbDrone.Web/Scripts/jquery.signalR.js create mode 100644 NzbDrone.Web/Scripts/jquery.signalR.min.js create mode 100644 packages/SignalR.Hosting.AspNet.0.4.0.0/SignalR.Hosting.AspNet.0.4.0.0.nupkg create mode 100644 packages/SignalR.Hosting.AspNet.0.4.0.0/lib/net40/SignalR.Hosting.AspNet.dll create mode 100644 packages/SignalR.Js.0.4.0/SignalR.Js.0.4.0.nupkg create mode 100644 packages/SignalR.Js.0.4.0/content/Scripts/jquery.signalR.js create mode 100644 packages/SignalR.Js.0.4.0/content/Scripts/jquery.signalR.min.js create mode 100644 packages/SignalR.Server.0.4.0.0/SignalR.Server.0.4.0.0.nupkg create mode 100644 packages/SignalR.Server.0.4.0.0/lib/net40/SignalR.dll diff --git a/NzbDrone.Core/NzbDrone.Core.csproj b/NzbDrone.Core/NzbDrone.Core.csproj index a2d5e5ce4..02e4be14d 100644 --- a/NzbDrone.Core/NzbDrone.Core.csproj +++ b/NzbDrone.Core/NzbDrone.Core.csproj @@ -171,6 +171,12 @@ ..\packages\Prowlin 0.9.4163.39219\Prowlin.dll + + ..\packages\SignalR.Server.0.4.0.0\lib\net40\SignalR.dll + + + ..\packages\SignalR.Hosting.AspNet.0.4.0.0\lib\net40\SignalR.Hosting.AspNet.dll + @@ -299,6 +305,7 @@ + diff --git a/NzbDrone.Core/Providers/DownloadProvider.cs b/NzbDrone.Core/Providers/DownloadProvider.cs index 4912b4640..426288867 100644 --- a/NzbDrone.Core/Providers/DownloadProvider.cs +++ b/NzbDrone.Core/Providers/DownloadProvider.cs @@ -17,13 +17,15 @@ namespace NzbDrone.Core.Providers private readonly ExternalNotificationProvider _externalNotificationProvider; private readonly ConfigProvider _configProvider; private readonly BlackholeProvider _blackholeProvider; + private readonly SignalRProvider _signalRProvider; private static readonly Logger logger = LogManager.GetCurrentClassLogger(); [Inject] public DownloadProvider(SabProvider sabProvider, HistoryProvider historyProvider, EpisodeProvider episodeProvider, ExternalNotificationProvider externalNotificationProvider, - ConfigProvider configProvider, BlackholeProvider blackholeProvider) + ConfigProvider configProvider, BlackholeProvider blackholeProvider, + SignalRProvider signalRProvider) { _sabProvider = sabProvider; _historyProvider = historyProvider; @@ -31,6 +33,7 @@ namespace NzbDrone.Core.Providers _externalNotificationProvider = externalNotificationProvider; _configProvider = configProvider; _blackholeProvider = blackholeProvider; + _signalRProvider = signalRProvider; } public DownloadProvider() @@ -63,6 +66,8 @@ namespace NzbDrone.Core.Providers _historyProvider.Add(history); _episodeProvider.MarkEpisodeAsFetched(episode.EpisodeId); + + _signalRProvider.UpdateEpisodeStatus(episode.EpisodeId, EpisodeStatusType.Downloading); } _externalNotificationProvider.OnGrab(downloadTitle); diff --git a/NzbDrone.Core/Providers/SignalRProvider.cs b/NzbDrone.Core/Providers/SignalRProvider.cs new file mode 100644 index 000000000..ee96d33c6 --- /dev/null +++ b/NzbDrone.Core/Providers/SignalRProvider.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NLog; +using NzbDrone.Core.Model; +using SignalR; +using SignalR.Hosting.AspNet; +using SignalR.Hubs; +using SignalR.Infrastructure; + +namespace NzbDrone.Core.Providers +{ + public class SignalRProvider : Hub + { + private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); + + public virtual void UpdateEpisodeStatus(int episodeId, EpisodeStatusType episodeStatus) + { + Logger.Trace("Sending Status update to client. EpisodeId: {0}, Status: {1}", episodeId, episodeStatus); + + GetClients().updatedStatus(episodeId, episodeStatus.ToString()); + } + + private static dynamic GetClients() + { + IConnectionManager connectionManager = AspNetHost.DependencyResolver.Resolve(); + return connectionManager.GetClients(); + } + } +} diff --git a/NzbDrone.Core/packages.config b/NzbDrone.Core/packages.config index 5df46aac9..2039b67b7 100644 --- a/NzbDrone.Core/packages.config +++ b/NzbDrone.Core/packages.config @@ -9,6 +9,8 @@ + + diff --git a/NzbDrone.Web/NzbDrone.Web.csproj b/NzbDrone.Web/NzbDrone.Web.csproj index e1ac8ee66..c87b9fcaf 100644 --- a/NzbDrone.Web/NzbDrone.Web.csproj +++ b/NzbDrone.Web/NzbDrone.Web.csproj @@ -59,6 +59,9 @@ ..\packages\MiniProfiler.1.9\lib\net40\MvcMiniProfiler.dll + + ..\packages\Newtonsoft.Json.4.0.8\lib\net40\Newtonsoft.Json.dll + ..\packages\Ninject.2.2.1.4\lib\net40-Full\Ninject.dll @@ -68,6 +71,12 @@ ..\packages\NLog.2.0.0.2000\lib\net40\NLog.dll + + ..\packages\SignalR.Server.0.4.0.0\lib\net40\SignalR.dll + + + ..\packages\SignalR.Hosting.AspNet.0.4.0.0\lib\net40\SignalR.Hosting.AspNet.dll + @@ -325,13 +334,14 @@ - + + diff --git a/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.validate.js b/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.validate.js deleted file mode 100644 index b2d48c060..000000000 --- a/NzbDrone.Web/Scripts/DataTables-1.9.0/media/js/jquery.validate.js +++ /dev/null @@ -1,1150 +0,0 @@ -/* -* Note: While Microsoft is not the author of this file, Microsoft is -* offering you a license subject to the terms of the Microsoft Software -* License Terms for Microsoft ASP.NET Model View Controller 3. -* Microsoft reserves all other rights. The notices below are provided -* for informational purposes only and are not the license terms under -* which Microsoft distributed this file. -* -* jQuery validation plug-in 1.7 -* -* http://bassistance.de/jquery-plugins/jquery-plugin-validation/ -* http://docs.jquery.com/Plugins/Validation -* -* Copyright (c) 2006 - 2008 Jörn Zaefferer -* -* $Id: jquery.validate.js 6403 2009-06-17 14:27:16Z joern.zaefferer $ -* -*/ - -(function($) { - -$.extend($.fn, { - // http://docs.jquery.com/Plugins/Validation/validate - validate: function( options ) { - - // if nothing is selected, return nothing; can't chain anyway - if (!this.length) { - options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" ); - return; - } - - // check if a validator for this form was already created - var validator = $.data(this[0], 'validator'); - if ( validator ) { - return validator; - } - - validator = new $.validator( options, this[0] ); - $.data(this[0], 'validator', validator); - - if ( validator.settings.onsubmit ) { - - // allow suppresing validation by adding a cancel class to the submit button - this.find("input, button").filter(".cancel").click(function() { - validator.cancelSubmit = true; - }); - - // when a submitHandler is used, capture the submitting button - if (validator.settings.submitHandler) { - this.find("input, button").filter(":submit").click(function() { - validator.submitButton = this; - }); - } - - // validate the form on submit - this.submit( function( event ) { - if ( validator.settings.debug ) - // prevent form submit to be able to see console output - event.preventDefault(); - - function handle() { - if ( validator.settings.submitHandler ) { - if (validator.submitButton) { - // insert a hidden input as a replacement for the missing submit button - var hidden = $("").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm); - } - validator.settings.submitHandler.call( validator, validator.currentForm ); - if (validator.submitButton) { - // and clean up afterwards; thanks to no-block-scope, hidden can be referenced - hidden.remove(); - } - return false; - } - return true; - } - - // prevent submit for invalid forms or custom submit handlers - if ( validator.cancelSubmit ) { - validator.cancelSubmit = false; - return handle(); - } - if ( validator.form() ) { - if ( validator.pendingRequest ) { - validator.formSubmitted = true; - return false; - } - return handle(); - } else { - validator.focusInvalid(); - return false; - } - }); - } - - return validator; - }, - // http://docs.jquery.com/Plugins/Validation/valid - valid: function() { - if ( $(this[0]).is('form')) { - return this.validate().form(); - } else { - var valid = true; - var validator = $(this[0].form).validate(); - this.each(function() { - valid &= validator.element(this); - }); - return valid; - } - }, - // attributes: space seperated list of attributes to retrieve and remove - removeAttrs: function(attributes) { - var result = {}, - $element = this; - $.each(attributes.split(/\s/), function(index, value) { - result[value] = $element.attr(value); - $element.removeAttr(value); - }); - return result; - }, - // http://docs.jquery.com/Plugins/Validation/rules - rules: function(command, argument) { - var element = this[0]; - - if (command) { - var settings = $.data(element.form, 'validator').settings; - var staticRules = settings.rules; - var existingRules = $.validator.staticRules(element); - switch(command) { - case "add": - $.extend(existingRules, $.validator.normalizeRule(argument)); - staticRules[element.name] = existingRules; - if (argument.messages) - settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages ); - break; - case "remove": - if (!argument) { - delete staticRules[element.name]; - return existingRules; - } - var filtered = {}; - $.each(argument.split(/\s/), function(index, method) { - filtered[method] = existingRules[method]; - delete existingRules[method]; - }); - return filtered; - } - } - - var data = $.validator.normalizeRules( - $.extend( - {}, - $.validator.metadataRules(element), - $.validator.classRules(element), - $.validator.attributeRules(element), - $.validator.staticRules(element) - ), element); - - // make sure required is at front - if (data.required) { - var param = data.required; - delete data.required; - data = $.extend({required: param}, data); - } - - return data; - } -}); - -// Custom selectors -$.extend($.expr[":"], { - // http://docs.jquery.com/Plugins/Validation/blank - blank: function(a) {return !$.trim("" + a.value);}, - // http://docs.jquery.com/Plugins/Validation/filled - filled: function(a) {return !!$.trim("" + a.value);}, - // http://docs.jquery.com/Plugins/Validation/unchecked - unchecked: function(a) {return !a.checked;} -}); - -// constructor for validator -$.validator = function( options, form ) { - this.settings = $.extend( true, {}, $.validator.defaults, options ); - this.currentForm = form; - this.init(); -}; - -$.validator.format = function(source, params) { - if ( arguments.length == 1 ) - return function() { - var args = $.makeArray(arguments); - args.unshift(source); - return $.validator.format.apply( this, args ); - }; - if ( arguments.length > 2 && params.constructor != Array ) { - params = $.makeArray(arguments).slice(1); - } - if ( params.constructor != Array ) { - params = [ params ]; - } - $.each(params, function(i, n) { - source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n); - }); - return source; -}; - -$.extend($.validator, { - - defaults: { - messages: {}, - groups: {}, - rules: {}, - errorClass: "error", - validClass: "valid", - errorElement: "label", - focusInvalid: true, - errorContainer: $( [] ), - errorLabelContainer: $( [] ), - onsubmit: true, - ignore: [], - ignoreTitle: false, - onfocusin: function(element) { - this.lastActive = element; - - // hide error label and remove error class on focus if enabled - if ( this.settings.focusCleanup && !this.blockFocusCleanup ) { - this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); - this.errorsFor(element).hide(); - } - }, - onfocusout: function(element) { - if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) { - this.element(element); - } - }, - onkeyup: function(element) { - if ( element.name in this.submitted || element == this.lastElement ) { - this.element(element); - } - }, - onclick: function(element) { - // click on selects, radiobuttons and checkboxes - if ( element.name in this.submitted ) - this.element(element); - // or option elements, check parent select in that case - else if (element.parentNode.name in this.submitted) - this.element(element.parentNode); - }, - highlight: function( element, errorClass, validClass ) { - $(element).addClass(errorClass).removeClass(validClass); - }, - unhighlight: function( element, errorClass, validClass ) { - $(element).removeClass(errorClass).addClass(validClass); - } - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults - setDefaults: function(settings) { - $.extend( $.validator.defaults, settings ); - }, - - 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.", - creditcard: "Please enter a valid credit card number.", - equalTo: "Please enter the same value again.", - accept: "Please enter a value with a valid extension.", - maxlength: $.validator.format("Please enter no more than {0} characters."), - minlength: $.validator.format("Please enter at least {0} characters."), - rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), - range: $.validator.format("Please enter a value between {0} and {1}."), - max: $.validator.format("Please enter a value less than or equal to {0}."), - min: $.validator.format("Please enter a value greater than or equal to {0}.") - }, - - autoCreateRanges: false, - - prototype: { - - init: function() { - this.labelContainer = $(this.settings.errorLabelContainer); - this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); - this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer ); - this.submitted = {}; - this.valueCache = {}; - this.pendingRequest = 0; - this.pending = {}; - this.invalid = {}; - this.reset(); - - var groups = (this.groups = {}); - $.each(this.settings.groups, function(key, value) { - $.each(value.split(/\s/), function(index, name) { - groups[name] = key; - }); - }); - var rules = this.settings.rules; - $.each(rules, function(key, value) { - rules[key] = $.validator.normalizeRule(value); - }); - - function delegate(event) { - var validator = $.data(this[0].form, "validator"), - eventType = "on" + event.type.replace(/^validate/, ""); - validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] ); - } - $(this.currentForm) - .validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate) - .validateDelegate(":radio, :checkbox, select, option", "click", delegate); - - if (this.settings.invalidHandler) - $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/form - form: function() { - this.checkForm(); - $.extend(this.submitted, this.errorMap); - this.invalid = $.extend({}, this.errorMap); - if (!this.valid()) - $(this.currentForm).triggerHandler("invalid-form", [this]); - this.showErrors(); - return this.valid(); - }, - - checkForm: function() { - this.prepareForm(); - for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) { - this.check( elements[i] ); - } - return this.valid(); - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/element - element: function( element ) { - element = this.clean( element ); - this.lastElement = element; - this.prepareElement( element ); - this.currentElements = $(element); - var result = this.check( element ); - if ( result ) { - delete this.invalid[element.name]; - } else { - this.invalid[element.name] = true; - } - if ( !this.numberOfInvalids() ) { - // Hide error containers on last error - this.toHide = this.toHide.add( this.containers ); - } - this.showErrors(); - return result; - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/showErrors - showErrors: function(errors) { - if(errors) { - // add items to error list and map - $.extend( this.errorMap, errors ); - this.errorList = []; - for ( var name in errors ) { - this.errorList.push({ - message: errors[name], - element: this.findByName(name)[0] - }); - } - // remove items from success list - this.successList = $.grep( this.successList, function(element) { - return !(element.name in errors); - }); - } - this.settings.showErrors - ? this.settings.showErrors.call( this, this.errorMap, this.errorList ) - : this.defaultShowErrors(); - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/resetForm - resetForm: function() { - if ( $.fn.resetForm ) - $( this.currentForm ).resetForm(); - this.submitted = {}; - this.prepareForm(); - this.hideErrors(); - this.elements().removeClass( this.settings.errorClass ); - }, - - numberOfInvalids: function() { - return this.objectLength(this.invalid); - }, - - objectLength: function( obj ) { - var count = 0; - for ( var i in obj ) - count++; - return count; - }, - - hideErrors: function() { - this.addWrapper( this.toHide ).hide(); - }, - - valid: function() { - return this.size() == 0; - }, - - size: function() { - return this.errorList.length; - }, - - focusInvalid: function() { - if( this.settings.focusInvalid ) { - try { - $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) - .filter(":visible") - .focus() - // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find - .trigger("focusin"); - } catch(e) { - // ignore IE throwing errors when focusing hidden elements - } - } - }, - - findLastActive: function() { - var lastActive = this.lastActive; - return lastActive && $.grep(this.errorList, function(n) { - return n.element.name == lastActive.name; - }).length == 1 && lastActive; - }, - - elements: function() { - var validator = this, - rulesCache = {}; - - // select all valid inputs inside the form (no submit or reset buttons) - // workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved - return $([]).add(this.currentForm.elements) - .filter(":input") - .not(":submit, :reset, :image, [disabled]") - .not( this.settings.ignore ) - .filter(function() { - !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this); - - // select only the first element for each name, and only those with rules specified - if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) - return false; - - rulesCache[this.name] = true; - return true; - }); - }, - - clean: function( selector ) { - return $( selector )[0]; - }, - - errors: function() { - return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext ); - }, - - reset: function() { - this.successList = []; - this.errorList = []; - this.errorMap = {}; - this.toShow = $([]); - this.toHide = $([]); - this.currentElements = $([]); - }, - - prepareForm: function() { - this.reset(); - this.toHide = this.errors().add( this.containers ); - }, - - prepareElement: function( element ) { - this.reset(); - this.toHide = this.errorsFor(element); - }, - - check: function( element ) { - element = this.clean( element ); - - // if radio/checkbox, validate first element in group instead - if (this.checkable(element)) { - element = this.findByName( element.name )[0]; - } - - var rules = $(element).rules(); - var dependencyMismatch = false; - for( method in rules ) { - var rule = { method: method, parameters: rules[method] }; - try { - var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters ); - - // if a method indicates that the field is optional and therefore valid, - // don't mark it as valid when there are no other rules - if ( result == "dependency-mismatch" ) { - dependencyMismatch = true; - continue; - } - dependencyMismatch = false; - - if ( result == "pending" ) { - this.toHide = this.toHide.not( this.errorsFor(element) ); - return; - } - - if( !result ) { - this.formatAndAdd( element, rule ); - return false; - } - } catch(e) { - this.settings.debug && window.console && console.log("exception occured when checking element " + element.id - + ", check the '" + rule.method + "' method", e); - throw e; - } - } - if (dependencyMismatch) - return; - if ( this.objectLength(rules) ) - this.successList.push(element); - return true; - }, - - // return the custom message for the given element and validation method - // specified in the element's "messages" metadata - customMetaMessage: function(element, method) { - if (!$.metadata) - return; - - var meta = this.settings.meta - ? $(element).metadata()[this.settings.meta] - : $(element).metadata(); - - return meta && meta.messages && meta.messages[method]; - }, - - // return the custom message for the given element name and validation method - customMessage: function( name, method ) { - var m = this.settings.messages[name]; - return m && (m.constructor == String - ? m - : m[method]); - }, - - // return the first defined argument, allowing empty strings - findDefined: function() { - for(var i = 0; i < arguments.length; i++) { - if (arguments[i] !== undefined) - return arguments[i]; - } - return undefined; - }, - - defaultMessage: function( element, method) { - return this.findDefined( - this.customMessage( element.name, method ), - this.customMetaMessage( element, method ), - // title is never undefined, so handle empty string as undefined - !this.settings.ignoreTitle && element.title || undefined, - $.validator.messages[method], - "Warning: No message defined for " + element.name + "" - ); - }, - - formatAndAdd: function( element, rule ) { - var message = this.defaultMessage( element, rule.method ), - theregex = /\$?\{(\d+)\}/g; - if ( typeof message == "function" ) { - message = message.call(this, rule.parameters, element); - } else if (theregex.test(message)) { - message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters); - } - this.errorList.push({ - message: message, - element: element - }); - - this.errorMap[element.name] = message; - this.submitted[element.name] = message; - }, - - addWrapper: function(toToggle) { - if ( this.settings.wrapper ) - toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); - return toToggle; - }, - - defaultShowErrors: function() { - for ( var i = 0; this.errorList[i]; i++ ) { - var error = this.errorList[i]; - this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); - this.showLabel( error.element, error.message ); - } - if( this.errorList.length ) { - this.toShow = this.toShow.add( this.containers ); - } - if (this.settings.success) { - for ( var i = 0; this.successList[i]; i++ ) { - this.showLabel( this.successList[i] ); - } - } - if (this.settings.unhighlight) { - for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) { - this.settings.unhighlight.call( this, elements[i], 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 $(this.errorList).map(function() { - return this.element; - }); - }, - - showLabel: function(element, message) { - var label = this.errorsFor( element ); - if ( label.length ) { - // refresh error/success class - label.removeClass().addClass( this.settings.errorClass ); - - // check if we have a generated label, replace the message then - label.attr("generated") && label.html(message); - } else { - // create label - label = $("<" + this.settings.errorElement + "/>") - .attr({"for": this.idOrName(element), generated: true}) - .addClass(this.settings.errorClass) - .html(message || ""); - if ( this.settings.wrapper ) { - // make sure the element is visible, even in IE - // actually showing the wrapped element is handled elsewhere - label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); - } - if ( !this.labelContainer.append(label).length ) - this.settings.errorPlacement - ? this.settings.errorPlacement(label, $(element) ) - : label.insertAfter(element); - } - if ( !message && this.settings.success ) { - label.text(""); - typeof this.settings.success == "string" - ? label.addClass( this.settings.success ) - : this.settings.success( label ); - } - this.toShow = this.toShow.add(label); - }, - - errorsFor: function(element) { - var name = this.idOrName(element); - return this.errors().filter(function() { - return $(this).attr('for') == name; - }); - }, - - idOrName: function(element) { - return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); - }, - - checkable: function( element ) { - return /radio|checkbox/i.test(element.type); - }, - - findByName: function( name ) { - // select by name and filter by form for performance over form.find("[name=...]") - var form = this.currentForm; - return $(document.getElementsByName(name)).map(function(index, element) { - return element.form == form && element.name == name && element || null; - }); - }, - - getLength: function(value, element) { - switch( element.nodeName.toLowerCase() ) { - case 'select': - return $("option:selected", element).length; - case 'input': - if( this.checkable( element) ) - return this.findByName(element.name).filter(':checked').length; - } - return value.length; - }, - - depend: function(param, element) { - return this.dependTypes[typeof param] - ? this.dependTypes[typeof param](param, element) - : true; - }, - - dependTypes: { - "boolean": function(param, element) { - return param; - }, - "string": function(param, element) { - return !!$(param, element.form).length; - }, - "function": function(param, element) { - return param(element); - } - }, - - optional: function(element) { - return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch"; - }, - - startRequest: function(element) { - if (!this.pending[element.name]) { - this.pendingRequest++; - this.pending[element.name] = true; - } - }, - - stopRequest: function(element, valid) { - this.pendingRequest--; - // sometimes synchronization fails, make sure pendingRequest is never < 0 - if (this.pendingRequest < 0) - this.pendingRequest = 0; - delete this.pending[element.name]; - if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) { - $(this.currentForm).submit(); - this.formSubmitted = false; - } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) { - $(this.currentForm).triggerHandler("invalid-form", [this]); - this.formSubmitted = false; - } - }, - - previousValue: function(element) { - return $.data(element, "previousValue") || $.data(element, "previousValue", { - old: null, - valid: true, - message: this.defaultMessage( element, "remote" ) - }); - } - - }, - - classRuleSettings: { - required: {required: true}, - email: {email: true}, - url: {url: true}, - date: {date: true}, - dateISO: {dateISO: true}, - dateDE: {dateDE: true}, - number: {number: true}, - numberDE: {numberDE: true}, - digits: {digits: true}, - creditcard: {creditcard: true} - }, - - addClassRules: function(className, rules) { - className.constructor == String ? - this.classRuleSettings[className] = rules : - $.extend(this.classRuleSettings, className); - }, - - classRules: function(element) { - var rules = {}; - var classes = $(element).attr('class'); - classes && $.each(classes.split(' '), function() { - if (this in $.validator.classRuleSettings) { - $.extend(rules, $.validator.classRuleSettings[this]); - } - }); - return rules; - }, - - attributeRules: function(element) { - var rules = {}; - var $element = $(element); - - for (method in $.validator.methods) { - var value = $element.attr(method); - if (value) { - rules[method] = value; - } - } - - // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs - if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) { - delete rules.maxlength; - } - - return rules; - }, - - metadataRules: function(element) { - if (!$.metadata) return {}; - - var meta = $.data(element.form, 'validator').settings.meta; - return meta ? - $(element).metadata()[meta] : - $(element).metadata(); - }, - - staticRules: function(element) { - var rules = {}; - var validator = $.data(element.form, 'validator'); - if (validator.settings.rules) { - rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; - } - return rules; - }, - - normalizeRules: function(rules, element) { - // handle dependency check - $.each(rules, function(prop, val) { - // ignore rule when param is explicitly false, eg. required:false - if (val === false) { - delete rules[prop]; - return; - } - if (val.param || val.depends) { - var keepRule = true; - switch (typeof val.depends) { - case "string": - keepRule = !!$(val.depends, element.form).length; - break; - case "function": - keepRule = val.depends.call(element, element); - break; - } - if (keepRule) { - rules[prop] = val.param !== undefined ? val.param : true; - } else { - delete rules[prop]; - } - } - }); - - // evaluate parameters - $.each(rules, function(rule, parameter) { - rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; - }); - - // clean number parameters - $.each(['minlength', 'maxlength', 'min', 'max'], function() { - if (rules[this]) { - rules[this] = Number(rules[this]); - } - }); - $.each(['rangelength', 'range'], function() { - if (rules[this]) { - rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; - } - }); - - if ($.validator.autoCreateRanges) { - // auto-create ranges - if (rules.min && rules.max) { - rules.range = [rules.min, rules.max]; - delete rules.min; - delete rules.max; - } - if (rules.minlength && rules.maxlength) { - rules.rangelength = [rules.minlength, rules.maxlength]; - delete rules.minlength; - delete rules.maxlength; - } - } - - // To support custom messages in metadata ignore rule methods titled "messages" - if (rules.messages) { - delete rules.messages; - } - - return rules; - }, - - // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} - normalizeRule: function(data) { - if( typeof data == "string" ) { - var transformed = {}; - $.each(data.split(/\s/), function() { - transformed[this] = true; - }); - data = transformed; - } - return data; - }, - - // http://docs.jquery.com/Plugins/Validation/Validator/addMethod - addMethod: function(name, method, message) { - $.validator.methods[name] = method; - $.validator.messages[name] = message != undefined ? message : $.validator.messages[name]; - if (method.length < 3) { - $.validator.addClassRules(name, $.validator.normalizeRule(name)); - } - }, - - methods: { - - // http://docs.jquery.com/Plugins/Validation/Methods/required - required: function(value, element, param) { - // check if dependency is met - if ( !this.depend(param, element) ) - return "dependency-mismatch"; - switch( element.nodeName.toLowerCase() ) { - case 'select': - // could be an array for select-multiple or a string, both are fine this way - var val = $(element).val(); - return val && val.length > 0; - case 'input': - if ( this.checkable(element) ) - return this.getLength(value, element) > 0; - default: - return $.trim(value).length > 0; - } - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/remote - remote: function(value, element, param) { - if ( this.optional(element) ) - return "dependency-mismatch"; - - var previous = this.previousValue(element); - if (!this.settings.messages[element.name] ) - this.settings.messages[element.name] = {}; - previous.originalMessage = this.settings.messages[element.name].remote; - this.settings.messages[element.name].remote = previous.message; - - param = typeof param == "string" && {url:param} || param; - - if ( previous.old !== value ) { - previous.old = value; - var validator = this; - this.startRequest(element); - var data = {}; - data[element.name] = value; - $.ajax($.extend(true, { - url: param, - mode: "abort", - port: "validate" + element.name, - dataType: "json", - data: data, - success: function(response) { - validator.settings.messages[element.name].remote = previous.originalMessage; - var valid = response === true; - if ( valid ) { - var submitted = validator.formSubmitted; - validator.prepareElement(element); - validator.formSubmitted = submitted; - validator.successList.push(element); - validator.showErrors(); - } else { - var errors = {}; - var message = (previous.message = response || validator.defaultMessage( element, "remote" )); - errors[element.name] = $.isFunction(message) ? message(value) : message; - validator.showErrors(errors); - } - previous.valid = valid; - validator.stopRequest(element, valid); - } - }, param)); - return "pending"; - } else if( this.pending[element.name] ) { - return "pending"; - } - return previous.valid; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/minlength - minlength: function(value, element, param) { - return this.optional(element) || this.getLength($.trim(value), element) >= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/maxlength - maxlength: function(value, element, param) { - return this.optional(element) || this.getLength($.trim(value), element) <= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/rangelength - rangelength: function(value, element, param) { - var length = this.getLength($.trim(value), element); - return this.optional(element) || ( length >= param[0] && length <= param[1] ); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/min - min: function( value, element, param ) { - return this.optional(element) || value >= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/max - max: function( value, element, param ) { - return this.optional(element) || value <= param; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/range - range: function( value, element, param ) { - return this.optional(element) || ( value >= param[0] && value <= param[1] ); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/email - email: function(value, element) { - // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ - return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([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])))\.?$/i.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/url - url: function(value, element) { - // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ - return this.optional(element) || /^(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(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/date - date: function(value, element) { - return this.optional(element) || !/Invalid|NaN/.test(new Date(value)); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/dateISO - dateISO: function(value, element) { - return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/number - number: function(value, element) { - return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/digits - digits: function(value, element) { - return this.optional(element) || /^\d+$/.test(value); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/creditcard - // based on http://en.wikipedia.org/wiki/Luhn - creditcard: function(value, element) { - if ( this.optional(element) ) - return "dependency-mismatch"; - // accept only digits and dashes - if (/[^0-9-]+/.test(value)) - return false; - var nCheck = 0, - nDigit = 0, - bEven = false; - - value = value.replace(/\D/g, ""); - - for (var n = value.length - 1; n >= 0; n--) { - var cDigit = value.charAt(n); - var nDigit = parseInt(cDigit, 10); - if (bEven) { - if ((nDigit *= 2) > 9) - nDigit -= 9; - } - nCheck += nDigit; - bEven = !bEven; - } - - return (nCheck % 10) == 0; - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/accept - accept: function(value, element, param) { - param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif"; - return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i")); - }, - - // http://docs.jquery.com/Plugins/Validation/Methods/equalTo - equalTo: function(value, element, param) { - // bind to the blur event of the target in order to revalidate whenever the target field is updated - // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead - var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { - $(element).valid(); - }); - return value == target.val(); - } - - } - -}); - -// deprecated, use $.validator.format instead -$.format = $.validator.format; - -})(jQuery); - -// ajax mode: abort -// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); -// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() -;(function($) { - var ajax = $.ajax; - var pendingRequests = {}; - $.ajax = function(settings) { - // create settings for compatibility with ajaxSetup - settings = $.extend(settings, $.extend({}, $.ajaxSettings, settings)); - var port = settings.port; - if (settings.mode == "abort") { - if ( pendingRequests[port] ) { - pendingRequests[port].abort(); - } - return (pendingRequests[port] = ajax.apply(this, arguments)); - } - return ajax.apply(this, arguments); - }; -})(jQuery); - -// provides cross-browser focusin and focusout events -// IE has native support, in other browsers, use event caputuring (neither bubbles) - -// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation -// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target -;(function($) { - // only implement if not provided by jQuery core (since 1.4) - // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs - if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) { - $.each({ - focus: 'focusin', - blur: 'focusout' - }, function( original, fix ){ - $.event.special[fix] = { - setup:function() { - this.addEventListener( original, handler, true ); - }, - teardown:function() { - this.removeEventListener( original, handler, true ); - }, - handler: function(e) { - arguments[0] = $.event.fix(e); - arguments[0].type = fix; - return $.event.handle.apply(this, arguments); - } - }; - function handler(e) { - e = $.event.fix(e); - e.type = fix; - return $.event.handle.call(this, e); - } - }); - }; - $.extend($.fn, { - validateDelegate: function(delegate, type, handler) { - return this.bind(type, function(event) { - var target = $(event.target); - if (target.is(delegate)) { - return handler.apply(target, arguments); - } - }); - } - }); -})(jQuery); diff --git a/NzbDrone.Web/Scripts/NzbDrone/grid.js b/NzbDrone.Web/Scripts/NzbDrone/grid.js index 94bcaceda..481c5482a 100644 --- a/NzbDrone.Web/Scripts/NzbDrone/grid.js +++ b/NzbDrone.Web/Scripts/NzbDrone/grid.js @@ -62,4 +62,36 @@ function redrawGrid() { //Force reload using Ajax Binding (bServerSide == false) function reloadGrid() { oTable.fnReloadAjax(); -} \ No newline at end of file +} + + +//SignalR +$(function () { + // Proxy created on the fly + var signalRProvider = $.connection.signalRProvider; + + // Declare a function on the chat hub so the server can invoke it + signalRProvider.updatedStatus = function (episodeId, episodeStatus) { + var imageSrc = '../../Content/Images/' + episodeStatus + '.png'; + var row = $('tr.episodeId_' + episodeId); + + if (row.length == 0) + return; + + var statusImage = $(row).find('img.statusImage'); + + if (statusImage.length == 0) + return; + + statusImage.attr('alt', episodeStatus); + statusImage.attr('title', episodeStatus); + statusImage.attr('src', imageSrc); + + if (episodeStatus != "Missing") { + statusImage.parent('td').removeClass('episodeMissing'); + } + }; + + // Start the connection + $.connection.hub.start(); +}); \ No newline at end of file diff --git a/NzbDrone.Web/Scripts/jquery.signalR.js b/NzbDrone.Web/Scripts/jquery.signalR.js new file mode 100644 index 000000000..c877e0577 --- /dev/null +++ b/NzbDrone.Web/Scripts/jquery.signalR.js @@ -0,0 +1,885 @@ +/// +(function ($, window) { + /// + "use strict"; + + if (typeof ($) !== "function") { + // no jQuery! + throw "SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file."; + } + + if (!window.JSON) { + // no JSON! + throw "SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8."; + } + + var signalR, + _connection, + events = { + onStart: "onStart", + onStarting: "onStarting", + onSending: "onSending", + onReceived: "onReceived", + onError: "onError", + onReconnect: "onReconnect", + onDisconnect: "onDisconnect" + }, + log = function (msg, logging) { + if (logging === false) { + return; + } + var m; + if (typeof (window.console) === "undefined") { + return; + } + m = "[" + new Date().toTimeString() + "] SignalR: " + msg; + if (window.console.debug) { + window.console.debug(m); + } else if (window.console.log) { + window.console.log(m); + } + }; + + signalR = function (url, qs, logging) { + /// Creates a new SignalR connection for the given url + /// The URL of the long polling endpoint + /// + /// [Optional] Custom querystring parameters to add to the connection URL. + /// If an object, every non-function member will be added to the querystring. + /// If a string, it's added to the QS as specified. + /// + /// + /// [Optional] A flag indicating whether connection logging is enabled to the browser + /// console/log. Defaults to false. + /// + /// + + return new signalR.fn.init(url, qs, logging); + }; + + signalR.fn = signalR.prototype = { + init: function (url, qs, logging) { + this.url = url; + this.qs = qs; + if (typeof (logging) === "boolean") { + this.logging = logging; + } + }, + + logging: false, + + reconnectDelay: 2000, + + start: function (options, callback) { + /// Starts the connection + /// Options map + /// A callback function to execute when the connection has started + var connection = this, + config = { + transport: "auto" + }, + initialize, + promise = $.Deferred(); + + if (connection.transport) { + // Already started, just return + promise.resolve(connection); + return promise; + } + + if ($.type(options) === "function") { + // Support calling with single callback parameter + callback = options; + } else if ($.type(options) === "object") { + $.extend(config, options); + if ($.type(config.callback) === "function") { + callback = config.callback; + } + } + + $(connection).bind(events.onStart, function (e, data) { + if ($.type(callback) === "function") { + callback.call(connection); + } + promise.resolve(connection); + }); + + initialize = function (transports, index) { + index = index || 0; + if (index >= transports.length) { + if (!connection.transport) { + // No transport initialized successfully + promise.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."); + } + return; + } + + var transportName = transports[index], + transport = $.type(transportName) === "object" ? transportName : signalR.transports[transportName]; + + transport.start(connection, function () { + connection.transport = transport; + $(connection).trigger(events.onStart); + }, function () { + initialize(transports, index + 1); + }); + }; + + window.setTimeout(function () { + $.ajax(connection.url + "/negotiate", { + global: false, + type: "POST", + data: {}, + error: function (error) { + $(connection).trigger(events.onError, [error]); + promise.reject("SignalR: Error during negotiation request: " + error); + }, + success: function (res) { + connection.appRelativeUrl = res.Url; + connection.id = res.ConnectionId; + connection.webSocketServerUrl = res.WebSocketServerUrl; + + if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") { + $(connection).trigger(events.onError, "SignalR: Incompatible protocol version."); + promise.reject("SignalR: Incompatible protocol version."); + return; + } + + $(connection).trigger(events.onStarting); + + var transports = [], + supportedTransports = []; + + $.each(signalR.transports, function (key) { + if (key === "webSockets" && !res.TryWebSockets) { + // Server said don't even try WebSockets, but keep processing the loop + return true; + } + supportedTransports.push(key); + }); + + if ($.isArray(config.transport)) { + // ordered list provided + $.each(config.transport, function () { + var transport = this; + if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) { + transports.push($.type(transport) === "string" ? "" + transport : transport); + } + }); + } else if ($.type(config.transport) === "object" || + $.inArray(config.transport, supportedTransports) >= 0) { + // specific transport provided, as object or a named transport, e.g. "longPolling" + transports.push(config.transport); + } else { // default "auto" + transports = supportedTransports; + } + initialize(transports); + } + }); + }, 0); + + return promise; + }, + + starting: function (callback) { + /// Adds a callback that will be invoked before the connection is started + /// A callback function to execute when the connection is starting + /// + var connection = this, + $connection = $(connection); + + $connection.bind(events.onStarting, function (e, data) { + callback.call(connection); + // Unbind immediately, we don't want to call this callback again + $connection.unbind(events.onStarting); + }); + + return connection; + }, + + send: function (data) { + /// Sends data over the connection + /// The data to send over the connection + /// + var connection = this; + + if (!connection.transport) { + // Connection hasn't been started yet + throw "SignalR: Connection must be started before data can be sent. Call .start() before .send()"; + } + + connection.transport.send(connection, data); + + return connection; + }, + + sending: function (callback) { + /// Adds a callback that will be invoked before anything is sent over the connection + /// A callback function to execute before each time data is sent on the connection + /// + var connection = this; + $(connection).bind(events.onSending, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + received: function (callback) { + /// Adds a callback that will be invoked after anything is received over the connection + /// A callback function to execute when any data is received on the connection + /// + var connection = this; + $(connection).bind(events.onReceived, function (e, data) { + callback.call(connection, data); + }); + return connection; + }, + + error: function (callback) { + /// Adds a callback that will be invoked after an error occurs with the connection + /// A callback function to execute when an error occurs on the connection + /// + var connection = this; + $(connection).bind(events.onError, function (e, data) { + callback.call(connection, data); + }); + return connection; + }, + + disconnected: function (callback) { + /// Adds a callback that will be invoked when the client disconnects + /// A callback function to execute when the connection is broken + /// + var connection = this; + $(connection).bind(events.onDisconnect, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + reconnected: function (callback) { + /// Adds a callback that will be invoked when the underlying transport reconnects + /// A callback function to execute when the connection is restored + /// + var connection = this; + $(connection).bind(events.onReconnect, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + stop: function () { + /// Stops listening + /// + var connection = this; + + if (connection.transport) { + connection.transport.stop(connection); + connection.transport = null; + } + + delete connection.messageId; + delete connection.groups; + + // Trigger the disconnect event + $connection.trigger(events.onDisconnect); + + return connection; + }, + + log: log + }; + + signalR.fn.init.prototype = signalR.fn; + + + // Transports + var transportLogic = { + + addQs: function (url, connection) { + if (!connection.qs) { + return url; + } + + if (typeof (connection.qs) === "object") { + return url + "&" + $.param(connection.qs); + } + + if (typeof (connection.qs) === "string") { + return url + "&" + connection.qs; + } + + return url + "&" + escape(connection.qs.toString()); + }, + + getUrl: function (connection, transport, reconnecting) { + /// Gets the url for making a GET based connect request + var url = connection.url, + qs = "transport=" + transport + "&connectionId=" + window.escape(connection.id); + + if (connection.data) { + qs += "&connectionData=" + window.escape(connection.data); + } + + if (!reconnecting) { + url = url + "/connect"; + } else { + if (connection.messageId) { + qs += "&messageId=" + connection.messageId; + } + if (connection.groups) { + qs += "&groups=" + window.escape(JSON.stringify(connection.groups)); + } + } + url += "?" + qs; + url = this.addQs(url, connection); + return url; + }, + + ajaxSend: function (connection, data) { + var url = connection.url + "/send" + "?transport=" + connection.transport.name + "&connectionId=" + window.escape(connection.id); + url = this.addQs(url, connection); + $.ajax(url, { + global: false, + type: "POST", + dataType: "json", + data: { + data: data + }, + success: function (result) { + if (result) { + $(connection).trigger(events.onReceived, [result]); + } + }, + error: function (errData, textStatus) { + if (textStatus === "abort") { + return; + } + $(connection).trigger(events.onError, [errData]); + } + }); + }, + + processMessages: function (connection, data) { + var $connection = $(connection); + + if (data) { + if (data.Disconnect) { + log("Disconnect command received from server", connection.logging); + + // Disconnected by the server + connection.stop(); + + // Trigger the disconnect event + $connection.trigger(events.onDisconnect); + return; + } + + if (data.Messages) { + $.each(data.Messages, function () { + try { + $connection.trigger(events.onReceived, [this]); + } + catch (e) { + log("Error raising received " + e, connection.logging); + $(connection).trigger(events.onError, [e]); + } + }); + } + connection.messageId = data.MessageId; + connection.groups = data.TransportData.Groups; + } + }, + + foreverFrame: { + count: 0, + connections: {} + } + }; + + signalR.transports = { + + webSockets: { + name: "webSockets", + + send: function (connection, data) { + connection.socket.send(data); + }, + + start: function (connection, onSuccess, onFailed) { + var url, + opened = false, + protocol; + + if (window.MozWebSocket) { + window.WebSocket = window.MozWebSocket; + } + + if (!window.WebSocket) { + onFailed(); + return; + } + + if (!connection.socket) { + if (connection.webSocketServerUrl) { + url = connection.webSocketServerUrl; + } + else { + // Determine the protocol + protocol = document.location.protocol === "https:" ? "wss://" : "ws://"; + + url = protocol + document.location.host + connection.appRelativeUrl; + } + + // Build the url + $(connection).trigger(events.onSending); + if (connection.data) { + url += "?connectionData=" + connection.data + "&transport=webSockets&connectionId=" + connection.id; + } else { + url += "?transport=webSockets&connectionId=" + connection.id; + } + + connection.socket = new window.WebSocket(url); + connection.socket.onopen = function () { + opened = true; + if (onSuccess) { + onSuccess(); + } + }; + + connection.socket.onclose = function (event) { + if (!opened) { + if (onFailed) { + onFailed(); + } + } else if (typeof event.wasClean != "undefined" && event.wasClean === false) { + // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but + // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers. + $(connection).trigger(events.onError); + // TODO: Support reconnect attempt here, need to ensure last message id, groups, and connection data go up on reconnect + } + connection.socket = null; + }; + + connection.socket.onmessage = function (event) { + var data = window.JSON.parse(event.data), + $connection; + if (data) { + $connection = $(connection); + + if (data.Messages) { + $.each(data.Messages, function () { + try { + $connection.trigger(events.onReceived, [this]); + } + catch (e) { + log("Error raising received " + e, connection.logging); + } + }); + } else { + $connection.trigger(events.onReceived, [data]); + } + } + }; + } + }, + + stop: function (connection) { + if (connection.socket !== null) { + connection.socket.close(); + connection.socket = null; + } + } + }, + + serverSentEvents: { + name: "serverSentEvents", + + timeOut: 3000, + + start: function (connection, onSuccess, onFailed) { + var that = this, + opened = false, + $connection = $(connection), + reconnecting = !onSuccess, + url, + connectTimeOut; + + if (connection.eventSource) { + connection.stop(); + } + + if (!window.EventSource) { + if (onFailed) { + onFailed(); + } + return; + } + + $connection.trigger(events.onSending); + + url = transportLogic.getUrl(connection, this.name, reconnecting); + + try { + connection.eventSource = new window.EventSource(url); + } + catch (e) { + log("EventSource failed trying to connect with error " + e.Message, connection.logging); + if (onFailed) { + // The connection failed, call the failed callback + onFailed(); + } + else { + $connection.trigger(events.onError, [e]); + if (reconnecting) { + // If we were reconnecting, rather than doing initial connect, then try reconnect again + log("EventSource reconnecting", connection.logging); + that.reconnect(connection); + } + } + return; + } + + // After connecting, if after the specified timeout there's no response stop the connection + // and raise on failed + connectTimeOut = window.setTimeout(function () { + if (opened === false) { + log("EventSource timed out trying to connect", connection.logging); + + if (onFailed) { + onFailed(); + } + + if (reconnecting) { + // If we were reconnecting, rather than doing initial connect, then try reconnect again + log("EventSource reconnecting", connection.logging); + that.reconnect(connection); + } else { + that.stop(connection); + } + } + }, + that.timeOut); + + connection.eventSource.addEventListener("open", function (e) { + log("EventSource connected", connection.logging); + + if (connectTimeOut) { + window.clearTimeout(connectTimeOut); + } + + if (opened === false) { + opened = true; + + if (onSuccess) { + onSuccess(); + } + + if (reconnecting) { + $connection.trigger(events.onReconnect); + } + } + }, false); + + connection.eventSource.addEventListener("message", function (e) { + // process messages + if (e.data === "initialized") { + return; + } + transportLogic.processMessages(connection, window.JSON.parse(e.data)); + }, false); + + connection.eventSource.addEventListener("error", function (e) { + if (!opened) { + if (onFailed) { + onFailed(); + } + return; + } + + log("EventSource readyState: " + connection.eventSource.readyState, connection.logging); + + if (e.eventPhase === window.EventSource.CLOSED) { + // connection closed + if (connection.eventSource.readyState === window.EventSource.CONNECTING) { + // We don't use the EventSource's native reconnect function as it + // doesn't allow us to change the URL when reconnecting. We need + // to change the URL to not include the /connect suffix, and pass + // the last message id we received. + log("EventSource reconnecting due to the server connection ending", connection.logging); + that.reconnect(connection); + } + else { + // The EventSource has closed, either because its close() method was called, + // or the server sent down a "don't reconnect" frame. + log("EventSource closed", connection.logging); + that.stop(connection); + } + } else { + // connection error + log("EventSource error", connection.logging); + $connection.trigger(events.onError); + } + }, false); + }, + + reconnect: function (connection) { + var that = this; + window.setTimeout(function () { + that.stop(connection); + that.start(connection); + }, connection.reconnectDelay); + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + stop: function (connection) { + if (connection && connection.eventSource) { + connection.eventSource.close(); + connection.eventSource = null; + delete connection.eventSource; + } + } + }, + + foreverFrame: { + name: "foreverFrame", + + timeOut: 3000, + + start: function (connection, onSuccess, onFailed) { + var that = this, + frameId = (transportLogic.foreverFrame.count += 1), + url, + connectTimeOut, + frame = $(""); + + if (window.EventSource) { + // If the browser supports SSE, don't use Forever Frame + if (onFailed) { + onFailed(); + } + return; + } + + $(connection).trigger(events.onSending); + + // Build the url + url = transportLogic.getUrl(connection, this.name); + url += "&frameId=" + frameId; + + frame.prop("src", url); + transportLogic.foreverFrame.connections[frameId] = connection; + + frame.bind("readystatechange", function () { + if ($.inArray(this.readyState, ["loaded", "complete"]) >= 0) { + log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting", connection.logging); + that.reconnect(connection); + } + }); + + connection.frame = frame[0]; + connection.frameId = frameId; + + if (onSuccess) { + connection.onSuccess = onSuccess; + } + + $("body").append(frame); + + // After connecting, if after the specified timeout there's no response stop the connection + // and raise on failed + connectTimeOut = window.setTimeout(function () { + if (connection.onSuccess) { + that.stop(connection); + + if (onFailed) { + onFailed(); + } + } + }, that.timeOut); + }, + + reconnect: function (connection) { + var that = this; + window.setTimeout(function () { + var frame = connection.frame, + src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId; + frame.src = src; + }, connection.reconnectDelay); + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + receive: transportLogic.processMessages, + + stop: function (connection) { + if (connection.frame) { + if (connection.frame.stop) { + connection.frame.stop(); + } else if (connection.frame.document && connection.frame.document.execCommand) { + connection.frame.document.execCommand("Stop"); + } + $(connection.frame).remove(); + delete transportLogic.foreverFrame.connections[connection.frameId]; + connection.frame = null; + connection.frameId = null; + delete connection.frame; + delete connection.frameId; + } + }, + + getConnection: function (id) { + return transportLogic.foreverFrame.connections[id]; + }, + + started: function (connection) { + if (connection.onSuccess) { + connection.onSuccess(); + connection.onSuccess = null; + delete connection.onSuccess; + } + else { + // If there's no onSuccess handler we assume this is a reconnect + $(connection).trigger(events.onReconnect); + } + } + }, + + longPolling: { + name: "longPolling", + + reconnectDelay: 3000, + + start: function (connection, onSuccess, onFailed) { + /// Starts the long polling connection + /// The SignalR connection to start + var that = this; + if (connection.pollXhr) { + connection.stop(); + } + + connection.messageId = null; + + window.setTimeout(function () { + (function poll(instance, raiseReconnect) { + $(instance).trigger(events.onSending); + + var messageId = instance.messageId, + connect = (messageId === null), + url = transportLogic.getUrl(instance, that.name, !connect), + reconnectTimeOut = null, + reconnectFired = false; + + instance.pollXhr = $.ajax(url, { + global: false, + + type: "GET", + + dataType: "json", + + success: function (data) { + var delay = 0, + timedOutReceived = false; + + if (raiseReconnect === true) { + // Fire the reconnect event if it hasn't been fired as yet + if (reconnectFired === false) { + $(instance).trigger(events.onReconnect); + reconnectFired = true; + } + } + + transportLogic.processMessages(instance, data); + if (data && $.type(data.TransportData.LongPollDelay) === "number") { + delay = data.TransportData.LongPollDelay; + } + + if (data && data.TimedOut) { + timedOutReceived = data.TimedOut; + } + + if (delay > 0) { + window.setTimeout(function () { + poll(instance, timedOutReceived); + }, delay); + } else { + poll(instance, timedOutReceived); + } + }, + + error: function (data, textStatus) { + if (textStatus === "abort") { + return; + } + + if (reconnectTimeOut) { + // If the request failed then we clear the timeout so that the + // reconnect event doesn't get fired + clearTimeout(reconnectTimeOut); + } + + $(instance).trigger(events.onError, [data]); + + window.setTimeout(function () { + poll(instance, true); + }, connection.reconnectDelay); + } + }); + + if (raiseReconnect === true) { + reconnectTimeOut = window.setTimeout(function () { + if (reconnectFired === false) { + $(instance).trigger(events.onReconnect); + reconnectFired = true; + } + }, + that.reconnectDelay); + } + + } (connection)); + + // Now connected + // There's no good way know when the long poll has actually started so + // we assume it only takes around 150ms (max) to start the connection + window.setTimeout(onSuccess, 150); + + }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + stop: function (connection) { + /// Stops the long polling connection + /// The SignalR connection to stop + if (connection.pollXhr) { + connection.pollXhr.abort(); + connection.pollXhr = null; + delete connection.pollXhr; + } + } + } + }; + + signalR.noConflict = function () { + /// Reinstates the original value of $.connection and returns the signalR object for manual assignment + /// + if ($.connection === signalR) { + $.connection = _connection; + } + return signalR; + }; + + if ($.connection) { + _connection = $.connection; + } + + $.connection = $.signalR = signalR; + +} (window.jQuery, window)); \ No newline at end of file diff --git a/NzbDrone.Web/Scripts/jquery.signalR.min.js b/NzbDrone.Web/Scripts/jquery.signalR.min.js new file mode 100644 index 000000000..9e99f53a3 --- /dev/null +++ b/NzbDrone.Web/Scripts/jquery.signalR.min.js @@ -0,0 +1 @@ +(function(n,t){"use strict";var f,e,i,r,u;if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";i={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onDisconnect:"onDisconnect"},r=function(n,i){if(i===!1)return;var r;if(typeof t.console=="undefined")return;r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r)},f=function(n,t,i){return new f.fn.init(n,t,i)},f.fn=f.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},logging:!1,reconnectDelay:2e3,start:function(r,u){var e=this,o={transport:"auto"},h,s=n.Deferred();return e.transport?(s.resolve(e),s):(n.type(r)==="function"?u=r:n.type(r)==="object"&&(n.extend(o,r),n.type(o.callback)==="function"&&(u=o.callback)),n(e).bind(i.onStart,function(){n.type(u)==="function"&&u.call(e),s.resolve(e)}),h=function(t,r){r=r||0;if(r>=t.length){e.transport||s.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var u=t[r],o=n.type(u)==="object"?u:f.transports[u];o.start(e,function(){e.transport=o,n(e).trigger(i.onStart)},function(){h(t,r+1)})},t.setTimeout(function(){n.ajax(e.url+"/negotiate",{global:!1,type:"POST",data:{},error:function(t){n(e).trigger(i.onError,[t]),s.reject("SignalR: Error during negotiation request: "+t)},success:function(t){e.appRelativeUrl=t.Url,e.id=t.ConnectionId,e.webSocketServerUrl=t.WebSocketServerUrl;if(!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(e).trigger(i.onError,"SignalR: Incompatible protocol version."),s.reject("SignalR: Incompatible protocol version.");return}n(e).trigger(i.onStarting);var u=[],r=[];n.each(f.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;r.push(n)}),n.isArray(o.transport)?n.each(o.transport,function(){var t=this;n.type(t)!=="object"&&(n.type(t)!=="string"||n.inArray(""+t,r)<0)||u.push(n.type(t)==="string"?""+t:t)}):n.type(o.transport)!=="object"&&n.inArray(o.transport,r)<0?u=r:u.push(o.transport),h(u)}})},0),s)},starting:function(t){var r=this,u=n(r);return u.bind(i.onStarting,function(){t.call(r),u.unbind(i.onStarting)}),r},send:function(n){var t=this;if(!t.transport)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";return t.transport.send(t,n),t},sending:function(t){var r=this;return n(r).bind(i.onSending,function(){t.call(r)}),r},received:function(t){var r=this;return n(r).bind(i.onReceived,function(n,i){t.call(r,i)}),r},error:function(t){var r=this;return n(r).bind(i.onError,function(n,i){t.call(r,i)}),r},disconnected:function(t){var r=this;return n(r).bind(i.onDisconnect,function(){t.call(r)}),r},reconnected:function(t){var r=this;return n(r).bind(i.onReconnect,function(){t.call(r)}),r},stop:function(){var n=this;return n.transport&&(n.transport.stop(n),n.transport=null),delete n.messageId,delete n.groups,$connection.trigger(i.onDisconnect),n},log:r},f.fn.init.prototype=f.fn,u={addQs:function(t,i){return i.qs?typeof i.qs=="object"?t+"&"+n.param(i.qs):typeof i.qs=="string"?t+"&"+i.qs:t+"&"+escape(i.qs.toString()):t},getUrl:function(n,i,r){var u=n.url,f="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(f+="&connectionData="+t.escape(n.data)),r?(n.messageId&&(f+="&messageId="+n.messageId),n.groups&&(f+="&groups="+t.escape(JSON.stringify(n.groups)))):u=u+"/connect",u+="?"+f,u=this.addQs(u,n)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);f=this.addQs(f,r),n.ajax(f,{global:!1,type:"POST",dataType:"json",data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){if(u==="abort")return;n(r).trigger(i.onError,[t])}})},processMessages:function(t,u){var f=n(t);if(u){if(u.Disconnect){r("Disconnect command received from server",t.logging),t.stop(),f.trigger(i.onDisconnect);return}u.Messages&&n.each(u.Messages,function(){try{f.trigger(i.onReceived,[this])}catch(u){r("Error raising received "+u,t.logging),n(t).trigger(i.onError,[u])}}),t.messageId=u.MessageId,t.groups=u.TransportData.Groups}},foreverFrame:{count:0,connections:{}}},f.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(u,f,e){var o,h=!1,s;t.MozWebSocket&&(t.WebSocket=t.MozWebSocket);if(!t.WebSocket){e();return}u.socket||(u.webSocketServerUrl?o=u.webSocketServerUrl:(s=document.location.protocol==="https:"?"wss://":"ws://",o=s+document.location.host+u.appRelativeUrl),n(u).trigger(i.onSending),o+=u.data?"?connectionData="+u.data+"&transport=webSockets&connectionId="+u.id:"?transport=webSockets&connectionId="+u.id,u.socket=new t.WebSocket(o),u.socket.onopen=function(){h=!0,f&&f()},u.socket.onclose=function(t){h?typeof t.wasClean!="undefined"&&t.wasClean===!1&&n(u).trigger(i.onError):e&&e(),u.socket=null},u.socket.onmessage=function(f){var e=t.JSON.parse(f.data),o;e&&(o=n(u),e.Messages?n.each(e.Messages,function(){try{o.trigger(i.onReceived,[this])}catch(n){r("Error raising received "+n,u.logging)}}):o.trigger(i.onReceived,[e]))})},stop:function(n){n.socket!==null&&(n.socket.close(),n.socket=null)}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(f,e,o){var s=this,l=!1,c=n(f),h=!e,v,a;f.eventSource&&f.stop();if(!t.EventSource){o&&o();return}c.trigger(i.onSending),v=u.getUrl(f,this.name,h);try{f.eventSource=new t.EventSource(v)}catch(y){r("EventSource failed trying to connect with error "+y.Message,f.logging),o?o():(c.trigger(i.onError,[y]),h&&(r("EventSource reconnecting",f.logging),s.reconnect(f)));return}a=t.setTimeout(function(){l===!1&&(r("EventSource timed out trying to connect",f.logging),o&&o(),h?(r("EventSource reconnecting",f.logging),s.reconnect(f)):s.stop(f))},s.timeOut),f.eventSource.addEventListener("open",function(){r("EventSource connected",f.logging),a&&t.clearTimeout(a),l===!1&&(l=!0,e&&e(),h&&c.trigger(i.onReconnect))},!1),f.eventSource.addEventListener("message",function(n){if(n.data==="initialized")return;u.processMessages(f,t.JSON.parse(n.data))},!1),f.eventSource.addEventListener("error",function(n){if(!l){o&&o();return}r("EventSource readyState: "+f.eventSource.readyState,f.logging),n.eventPhase===t.EventSource.CLOSED?f.eventSource.readyState===t.EventSource.CONNECTING?(r("EventSource reconnecting due to the server connection ending",f.logging),s.reconnect(f)):(r("EventSource closed",f.logging),s.stop(f)):(r("EventSource error",f.logging),c.trigger(i.onError))},!1)},reconnect:function(n){var i=this;t.setTimeout(function(){i.stop(n),i.start(n)},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.eventSource.close(),n.eventSource=null,delete n.eventSource)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(f,e,o){var h=this,l=u.foreverFrame.count+=1,c,a,s=n("");if(t.EventSource){o&&o();return}n(f).trigger(i.onSending),c=u.getUrl(f,this.name),c+="&frameId="+l,s.prop("src",c),u.foreverFrame.connections[l]=f,s.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])<0||(r("Forever frame iframe readyState changed to "+this.readyState+", reconnecting",f.logging),h.reconnect(f))}),f.frame=s[0],f.frameId=l,e&&(f.onSuccess=e),n("body").append(s),a=t.setTimeout(function(){f.onSuccess&&(h.stop(f),o&&o())},h.timeOut)},reconnect:function(n){var i=this;t.setTimeout(function(){var r=n.frame,t=u.getUrl(n,i.name,!0)+"&frameId="+n.frameId;r.src=t},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},receive:u.processMessages,stop:function(t){t.frame&&(t.frame.stop?t.frame.stop():t.frame.document&&t.frame.document.execCommand&&t.frame.document.execCommand("Stop"),n(t.frame).remove(),delete u.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId)},getConnection:function(n){return u.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):n(t).trigger(i.onReconnect)}},longPolling:{name:"longPolling",reconnectDelay:3e3,start:function(r,f){var o=this;r.pollXhr&&r.stop(),r.messageId=null,t.setTimeout(function(){(function e(f,s){n(f).trigger(i.onSending);var a=f.messageId,l=a===null,v=u.getUrl(f,o.name,!l),c=null,h=!1;f.pollXhr=n.ajax(v,{global:!1,type:"GET",dataType:"json",success:function(r){var c=0,o=!1;s===!0&&h===!1&&(n(f).trigger(i.onReconnect),h=!0),u.processMessages(f,r),r&&n.type(r.TransportData.LongPollDelay)==="number"&&(c=r.TransportData.LongPollDelay),r&&r.TimedOut&&(o=r.TimedOut),c>0?t.setTimeout(function(){e(f,o)},c):e(f,o)},error:function(u,o){if(o==="abort")return;c&&clearTimeout(c),n(f).trigger(i.onError,[u]),t.setTimeout(function(){e(f,!0)},r.reconnectDelay)}}),s===!0&&(c=t.setTimeout(function(){h===!1&&(n(f).trigger(i.onReconnect),h=!0)},o.reconnectDelay))})(r),t.setTimeout(f,150)},250)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)}}},f.noConflict=function(){return n.connection===f&&(n.connection=e),f},n.connection&&(e=n.connection),n.connection=n.signalR=f})(window.jQuery,window) \ No newline at end of file diff --git a/NzbDrone.Web/Views/Series/Episode.cshtml b/NzbDrone.Web/Views/Series/Episode.cshtml index 146009c7a..f26d0b906 100644 --- a/NzbDrone.Web/Views/Series/Episode.cshtml +++ b/NzbDrone.Web/Views/Series/Episode.cshtml @@ -2,7 +2,7 @@ @using NzbDrone.Web.Helpers @model NzbDrone.Web.Models.EpisodeModel - + @Model.EpisodeNumber @Model.Title @Model.AirDate @@ -25,7 +25,7 @@ @*Commands Column*@ - @Model.Status + @Model.Status @Ajax.ImageActionLink("../../Content/Images/Search.png", new { Alt = "Search", Title = "Search for episode", @class = "gridImage" }, "Search", "Episode", new { episodeId = Model.EpisodeId }, null, null) @Ajax.ImageActionLink("../../Content/Images/Rename.png", new { Alt = "Rename", Title = "Rename episode", @class = "gridImage" }, "Rename", "Episode", new { episodeFileId = Model.EpisodeFileId }, null, null) diff --git a/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml b/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml index 1332bda8d..1c58cb17e 100644 --- a/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml +++ b/NzbDrone.Web/Views/Shared/_ReferenceLayout.cshtml @@ -28,7 +28,10 @@ @Html.IncludeScript("jquery-tgc-countdown-1.0.js") @Html.IncludeScript("jquery.watermark.min.js") @Html.IncludeScript("jquery.hotkeys.js") + @Html.IncludeScript("jquery.signalR.min.js") + @Html.IncludeScript("jquery.validate.min.js") @Html.IncludeScript("doTimeout.js") + @Html.IncludeScript("NzbDrone/localSearch.js") @Html.IncludeScript("NzbDrone/AutoComplete.js") @Html.IncludeScript("NzbDrone/Notification.js") @@ -38,7 +41,6 @@ @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTables.reloadAjax.js") @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.dataTables.editable.js") @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.jeditable.js") - @Html.IncludeScript("DataTables-1.9.0/media/js/jquery.validate.js") @Html.IncludeScript("jquery.dataTables.4button.pagination.js") @RenderSection("Scripts", required: false) diff --git a/NzbDrone.Web/packages.config b/NzbDrone.Web/packages.config index 9e0050eae..1c21698a3 100644 --- a/NzbDrone.Web/packages.config +++ b/NzbDrone.Web/packages.config @@ -14,10 +14,14 @@ + + + + \ No newline at end of file diff --git a/packages/SignalR.Hosting.AspNet.0.4.0.0/SignalR.Hosting.AspNet.0.4.0.0.nupkg b/packages/SignalR.Hosting.AspNet.0.4.0.0/SignalR.Hosting.AspNet.0.4.0.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..4009bc929718103982e1f6fcbb7bc6472fde2e6b GIT binary patch literal 22547 zcmc$_cUTnJ_cw?+BBl`p5i|Nz#Du6Qtz$q(5go^IMg~hoP;9YPM3hk190m~;6$PQq zjv`ZIz*Z5iihziK$UvzGMQ*TxrV|~i>fXJ4fA2oK@9y*Nv-{T?y1KenKeq{Irry)9h>%&5+U1y zc7==}Rd$BV8?|lk-d%HCT|@l01q5#jnJn8Cu#-FqlM&xC8PO2+8Fgew>jdM1G@tLZ!HD~`R|d1$O89H_Ll|!kH*NjNOM!CxK43*4c@df zC@>&o@2C;KY}&ImVDG$9u4{s}?%cHF=gCWDA$v*D$qPbutqj;Zd1q+It^og0BbIHM zH|pov{D;uaosf2-`{Qe^qDiK&D=C&)}|S=rvz@EJ#)*{S+l2Y z-aN~H%j8`l!CU-y{g3%=3Yqyn^jt;cXRuXgtDgUnpY7i& zDwITa44tj49Etq=Kd$2clSDOV^w>CT*`=}LT!Y_7fS(LMu~mDo_dK|9(3sC>=l5@Z zeX^k8e6wSa*XRi;|8?knz^?&*fkWnhXi0i$tc*}+{P)KTkEE5(Mh;8<2;9AFV)bslgLCYbacS4nf4%k`}**($Zroe)V0*6>o3my`N5feIecxBrm!}> zp^ND0tI*xwc_uk9K6_HsuYMN~%=<|m7(L4O&fUi;50c$t)d{~^ehy9hAdB>JXqp%> zwIJRbt@RszsGs$Knj71cs$Q`hayNmM@3-%XKlyKip+dRU`L62*`5D{Cxnc9h_YPaT zPLkwPUj8~Nl9m2#^zUYlityM+~nk2gu`f&S#HKXw5 zMtNb-oKL#@D}y0Dk+1nLs!&`1_CU2Xk1Fu2xnU|IgC%Ij7h1 zuHMAB{Ap!1hDgtjpv|s31NP3C^1sr?EjxDn|13nArhAem)|3Wfs9M$(+K90ci&DWJ zu*}FJ^*xFEJkVdn?q)xf%+;}`a=KZL{qWzE&Md*{nOAJRU))cLp5uF~WXJOdU-zEB zYY4wGBwybY&y*~7%g==x*;Qd@@7nq%MkAez-9QUfD-p6iDEnu)nEWLE4XYWmgJ2JH zoPGpCxb{mlyo{DLVcZ{C=G7aiMpyBfS!yU4iLB9t56R%hqo>3n3sDS60955vIr1cF8D2%aKh_PmvZm#Pdwp? zy5xke@zM0y#h=hCorXN+=QV-aIj$-9s(N1?TIN(LHI5O;wB7ch&1Q28)rApWkf9nQ zIz|i(J*NBs%XEF{6qj&AoJ{NoFVMmq&f-SrCs9h))D3pe;tN3PcZEQPJmy}Lu~f$A zmO$7bGpX=QSV?JBGVxcvMnPNev9lout@tieEqJt?L${HhE%Fe8Z7QRXpsnCOJzP1FPP03 zqQSZ!8`;3Y_qk4#__b7hQbvz9-?1dMT@jG)S~wk9dFq|(YTacg8{h`5O8g4Da(F$g z#0J%Xtz!7MC_|r*H(T0_d>XA$ANJ{W_vrPpzB2;gaO>C{qYB#>0qf*9+)MMxOtUo* zDL!79B?<!eOmCr1!&d?};p&I!l(JP7&Yhv!$Z#Q<>{q z2;0llN1aH8jI?8NSgAl4C{_HA_n(508*Pdyi}c1G)uU0Q%61AYnrta1Zx^-bH zn)4xf%u{G)#O2_6Cqu5)zY43~P8y}}QO-G!IdNs=Q96k#l3$@L4-aT!(_CvtqpOr) z4Wd>I+c0C0F}>C}V2z_w`D`H+#JKj9Q%*DR&At7K^{i#kpDkP?TdO$Q9VV~nTv_q8 zyIn$^#6BbT5bL)>%Q!o3Ub*D~oT*cJ@5PQ6T4BGg{wg+`OoMrBP*p3L#jv?&GVIq! z>HQC#YxjV%jePZru1NJ;&>FRyx3;T{ov`!N>tMC2s@-AQ1MVHU_7-Qd!^ZuT-6}gRSx{GWfkt0TyL|X^C^t?=9WhL8y4X<7j684b z8TX+AFM$gl@LZ}-0)=h!m%mzYYSH_Xi*#o_w++`Ved;+VA%nAvO1LuB{!Oss&=(o< ztNh$YhQvPqq;j>Y*A^GMGTDTG=!wS+5p#a?k#$mqooaNteY=mM^tW(+&$a&qdxx&TOG|E-y}Zm zL<#%4*M#*IJFJIk$ds5!ONf~WjxWsUWQ^!FE7|AKCb(pCwRonM;uV%UmQTB{?8}F7 z$N;LDG{dpN6Hi3zh+t}eFzB&&)16Q?Ysuyg+eb~%n+&wIr5l|us}z>K9SBFJRM)Z2 zExd>SDEcrmr_!lT*v({?qt~hHOl@wWZn;$*>mRTpuHAXz8hD*s^X`D*hm8@A^ybq? zihKOq%$j0~mGT=iJGorb;$LoR6?E>Id%UATDRZ5Yy+ORyL+3hZGj1RoG5qzfF)`Ns z^as`siA6CQ-jJaFq?CMgZ%uGVEBG8g-RzI%y7<=1L%@*rg6FnFv8IsA4}G4V+_q&{ z3KySg3EoHa44N}vaXD?z;=daQy}&PE_bY!AW7o|Z&A9WLF)VL$JJ&h*OIH*wbRJOe zW79k$hxcd|5@7d&?~Eo<^YX|eUpORCEjjqFuu~{!G^#aOl+Hcw3hzzFQKLt`5fk8O zO}=_tC7+hUfyTwUN|_}w!AJ+U!}<*BuBA)&4KvhYAiQ$Gr%fmrTGUr2c3yRovv`{n zG5gVw!^*C%XmWct_bPMNQKjtO{*{`|+ll@ZMElJh>D9lC>#dv0yN#Fwf4%76?|#Tx z!TFdCNF~N&ut}p5&dZ1F6ta(@I=Fb>DKoMA_PZ*lT}>Dhy7nUMKFlr%=T;oM`?AXC zyV}fke($8HjpDst$Wm?>&eIo+6oufb+SF4nv{y}Cy6+GD{Y`K<_DyY+7t7KO(I%a| zp-3ZJ+oe#Zb2+X%S#@?FUr@ps6eba;j>*uKt^;PqxMuiY_pbw5#vePfHciN8l&b?> zEZwaW`3A1My*mc9`7t%#2p>1T!6TCniNA6li!ePujoDiTV; z#uJnKj#*-Rd~>6=i7`mmuG2^8`fbElsgxHv3duF_9iKak9aE^jGw7RCie;$9>^vB@ zV1x8$&I?`=#ByPFf$M82e$T8Ge}38Cqed?2>3Rzf^yZo8h8{N;s?#M$(HG0Y0IQEK zTb7ffarl!=*B7@fSs#0k7oGw^=6sHW`b4|=AdjKMYEyXZR}}8~ujKIRLtl6UJ@26i zY+s9xzg-IIex9;O9imLVX8h~4*hySqIw|2Se%Gf0$CAxQhk(B8t2(Uc=qIL7@95ws zCja8j9oABEW(Z6Unz|%f($A%B0O(h$%X1YC-qGpXG`TmsdDavu=&;6m>RoT_yQC0! zeLTJ)VD{ZkV>jnD8xIXP4Fc9FJ?Q11w!#3DXOH<73$rQHSjnI<#urn!!tVO=FkoF6 zBs5H3bSKZg=Q&NxsVAPI+m2huV#j{6*wAZ49b3B&AEB}ub2N;m93ZK1=SD3t+_jye zv>sg)@Q;?s2ZI`qDK;I(y+5`oIt_$XY}H@U9!gEjIX{yDjj$-$L)&n7lX<`?B)jG$ zTsBwb)^+iJ8Tv2m9?SC?yKx@u{_Vr(XPTIyM!8n{+g80#eR1t_nch?qQ~CJ<={7xb zz!_}&SAq8w+NxAjD^klJ1b-5SHZ~Mp&`cjV7i~oJBlk0s{FvIJez}Ka_a$CAhd3hZ zg0dz~VuJ;9pp~hHt#v+V(O22E}MD@ z9?sQD#ew>T3p>ws9C)M}1^of)nc^$9OUByS9-9PysMW8lO@YTxybo9Te^-Sqra%ib za__>&l$te<-PR*P3_X~!7%v@_^D0pwJuzGNgD#kN@BE!R>S`7Dgdnj28&N^;LEgQ_ z5gCK6t_%DRBHx;8y-MN5LnzqFqUdvf2}F@c4jCN@a_)ti;$UIo&zV@gKbU zSj^L|4h2?vr!F7Cu=%)`)A#{Z@-4gY;8$Wv-@-Tiv4h5<@pEU4-oLHKemtp43^{0w z*n3t`&KrZf%@=Jo#}1jNZbZxfGw$`B8erecxc5es;`zb0&pr& zHTTQ@ZA;od_H9EhuXsf#HCG)*dxa})i#@_d$Z|IQbZu86uub)JE;FU20GlL%CjiKl zmqbB}O=Eof#DSOU*stN;2Tii3Grmg}J;pt;kgG2us_Cp(w?mVY&;XIeSYKD)$nw_r z@dZ!bNV|0Xc$F92!1S)yVL7uK8xKt+f^Hu{#EF+JJ?n-{HgJ z??OJKaX8<~X8`L1Pf;JeSPL&@nyF6|?8;oRK@$n404`mtU?pfv$8QqL&%d|Igx!PA za2wUEsRDSH*}|D6S97$9A##EtHNHZEFLqm#Zjnv8MNzb}ANBhj9BA6E8oN}}OcuzL zVv#M#!2N3bdYaXmys(!(bjx?}%4>${J9z7gRm`y|B3q6OvrOhP*Rh-btkra1q60U^ zf&RoqL{0H^8r{`-im&VbC3LWT?DgwxtKuHodaW6>!Kx#v@@tBhu_`CtEf0$Uo60R= zw`^2?k-Gdt6Ld78JOTd2m!=yaH))<=l;uwCu5ivG^tNA5Gw+HH{wViYLsTATEhtyue4 z{mEUXc-p<3XJ!`M$F*$LZ&k889Ej&qEs`dN`?%@30f_eR#*5*;*j*H2Kr@T|=tRlR zcjx0E1JE&S>GJw=nDmDQ{ zOrl`i6TX0cOgy>na9|kmQ4F$}C+@$urBY5yD~iW_i0w3Y*2rSIDg>43LmYH^sZ2bs z*Qhg-gg4wc;$3B=ay^63a}B<5q0XU1CTZKN^qF!Zqw7!bl$FJ0S#IPp)U!}#aF}_E z2N@l3K9ug|E~F)L7wku#L5A~O70ZVv9;VG>_nXOHr_m`gv3uWOeYqG8QM*iVAnr`1 zWaF^;KW+J^kH%q_q&v%9+?p&Tw{ZU;V^C!R*Y_{+Ym4m12P?kbyP-(ohK*k=NZw6# zBM#VQXQ~s=bv`Lx())-UN;nx!Pqc*U2UWN#Xz3FZ1m1&Y2XhrK?wm0txvUQ#HEugy zP7NCG4tsWCjljdw=>8WSF|L2(!hO9D#1mhoM=4&MLdBM!FGDA$v~ivM(3$;NL!}ON zJ5xuTgoS0kQ|qBgVR8G#P3ubZY)C8$dsE&J%YDJMwmto5jV!pbmKrXu_nlpZzQQ_1 zmfQ>K6}O!r-_98OfF_xL6WL*VFhl(24+ib|GR(g#+^2K2XdH-TM2w#}x$BE%z`N%P zL;9y!$}#|%TNWI1y374G_dXZX^qPv>FxJrCXEaqx3LB&k=wMVuwCvTkliu`8Wmx#cY1mb12fF>qU02`{ zk#FU)s6L0aMKk18Yfj^M)bEaA?E2U?vwEYa?5W0ii8+%O2SS4Rxfu z|5>Fm%Q>Rb*;H$dp5;&aai4`1-QEqgxU~*Q0u%D|jIL332hxdLTRbYfe2zQ0qp;t$ zTuykX_tx1=cM?Bw+1E_d=kKC;*KUjB_F$)(w&Qn1y;-1ljXHY9Mq?9gb}Bwt z3Hpy;)YX(dKe$g{%Nl*TlfKX8Vh~4#@vJ3yg4?EshI4D5-<$F*&!2OTa*GAt{d&_= z?SGMr3BNwdbLP`P5;)byI|lRw<30T|v$rYhO`{!%KT*3T2F@&JflZN5uurAO4ov{ajKxlq-L(;QPx7!LVc*MvG@W za>BRuqN6ry=>TL>J)L~X)_Q$&+;|iWheWlPs;F8RzVhioPhL|5=S2J@!R{6wSX`Ra z&SNi3k^HM?g;upTUN|mUGQ;AAjGQ=pV0dHF@oo`jX@7Eb%qWIA61}u7JfB&xt;Vr^ zw4}6X%3XN#mBsDd3@s0n=_SoJC?N^%=OgS3{jh3%3>A2VwJppdbLpmutX(e7^zKJ^^lLncrMum>_0GP-g!2j(%F zctRc2GX`J59#=9tBc9W7N=fmHMis=N#YB`0A9*0CuGhCRxLmNnN=6ewE-g%)U@tMN zx)c%i5~_2pls3x_>YTDMG7Dod_bQY)v`lHxQy#O_?g9} zQ?*Yuz}v|nu?w!|v>ii^;|6jl7yi&@78I``u)^hN=Cw-K27vEy-Dj9X>4;Ul0=Hn= z(ymuH@ znlq69&I*fR1H+S&Ij;2(jS*EgHJ89xY)B_l=vi$}6zy?~?C=1>xaK(JfDGiVVZF%L z*FZD~teW(@T43dd#A?Px+oWN+EKp%~LtT*yRKrYzR9Hp|nGI3@7NQn^dh& z?Ns40?1sLIZfFNmu|jGaOSaFo?ov8*K`)5$s25nHiRnQUKM#mMBh|>_AAp!Gu+@x) zB@?&9p@gp`{exT}Cc_-=9T0zoj%W_)IuNO*;!whXrV8w7Y-wjS3LOQ8VFPjP)O8Te zM5@^Z!w6C~F}9@UL>J&J7__X3H#1yYSPsPyi**)Tj=?@CoDkYsGjcF7>@KHzpp%^5 zhDf)Lz$88uH`KXfx0OHzt{^dsCT7)LC;&0Ik&uW;Bsgy90WpqJy54+M-vbs>h7QU) zhig{};@kPSgwffQKs*uiC&U-HjS&Zdj}om4DPemnqfv`5(qW;ROhFD?qYj%Ra6isc zK(nM@(SXlVN@sLUBF_}vNOyv}369S(yMboKtx9~&iNLrDP9VzC#Bm1Jlt?!#P-qy4 z0s36Jhoz3e-N584W^A$*))Jd=aqb--nytf@(0w4LrOtSb!}VM}CKDl@$(Eu2I{%{1 zT`%CZqZ~AnGE-Iwys$2wwUa zAIF_AlB4bfpK6N4hHW_C%yCT$6GtEE7@dL6C)U%CkTk6dA*PXwhd&ES;M$lP4hQf&l9|+6XJW-_GR1k#>W1<%zFnrF zu}=mEP2L4+P_5R3bD3x>okgkKotL*epniIF7FRF11LSBjE|8&VqFbXmE-woOFSF1D zT^E_G>4``c8wcqaLi*yBdRDDZe^2ESw7=xnm;b^$u)Tup1(CI>qSPz}E3end+Rq84 z!dKV4cI;(gwJge5#?M8&b?ni|c*%RTwxqWX24KtRrP0Dpm}piNjm{|k3Q@oHthuO} z!o7oTa(tLO5Z&t%#n5(!_{~BiYvP(Ia_pGXMSCA`-7Gb-!Z9L4TkxFg`-L$6vtY=e zbiOd>Ju*bo1%%^tdJM!S*icBEuHZZh6f&X_6W%R`D?tVyF@Yy)dkcuxupN3?)bT0` zIK+r0R4qvNM;0GYaD=L@^3}2uL5f{r!%fPcjCd_1Jg;Wm7fASb)ngKbc?86ESf(~h zg?;kNuvJ)}3v-t9>{eJtj#jTG3V&n7QpP|iO;wJTg+?iPqJ%l$CnL)mBCiHE8L#Jv zxf{c;Gf0yN3>$6ood#AmeruRR%_<{7B(U!B8${65ZBIGYACm6AX7h*`a65L<;tW#df*W$@SpreS zN|@7}EEu*D076{ed&CftWn2&2jbwZ~IKkkHzkXq+J_b=LHksJlv!bewtdl+b5~X9+ zMky5C0^6Aeb^|fVi6Rluw2t5vrJ-KwoN!t>RqObzp1?ZOLkhFvR?uQ#G$&LPY+`uV zVhX%OhV(WH5I?IIHpDklyueafKzt2ftIaB;(zDz+;)fQ23fRcL5Zs;)e@7`h%&)5+ zwXx3yw_k~w)%X(_M50%7))5)H0mPNCvX^MM+eECnI>e%qoriQmF09m1$_hp!X{6*O z6bp0kop~<>1G+(}h$UA?i~v6ftRx$Vc`!$=S7lg2={BiA^o43yktHg0CCmH1hn6i? z6BoQa8pMRzm|YtVQ-`SubF7lh43Sc2x&SEI2wo)|YA1Wo@{3`i(-v$gg_T9Z9MDK6 zK6UU*qZj%9nb9aU6wW56Ft&hijP3*xkfGQRE7}u+AJvSkO-pDJi^_PLd$jWHd99(>yQ)+{y3NtVw5J*1^|A zio{doyn6?F1%eu)azq}-iv~5G({X29p6|rpa*s?;5W zakX><4KlQq;OYCwz=((8Q524@yfluOZ4SjB$Z=l-(Z5t}FYG2ce+jx`gR+TQj#Lq! zvKWm!o{Y;$Wdd$5N9Ky+6%rmL(83lrQ1Ou~ffy^quWBpe-RRpy?yq-f@51${PhJ?P zkYM&1IsJ!{p{<}XWpp*UWd`GLUWKw@4!k&LJR##XPI(j&LqnnTF;OrwRi)k^$@KvC?$L%>hxs${`)|5(6i*|76!q@2sJ~*vm2>r za-bh`B8yW%jHJc(g&HLg;NNjrfF^f7mlh$xuIcreycEPNK_sRd%?UncYxI@ujV_Z{ z5mU7SM(7f;=aauLSMKIS1I$r$j9_bHIz;T}8n|>P&`Ag*;y}kZiYnKe5am#{^RXqJ z)?tFx6X_WEr%V59La?OWoyhb-5-}Bqz^i96UBKfy89`TLkxEY1Mf6Q3 z8lhqyN{FJ?D1_9ebU87FYK}O1pE-izMho$;gmN;4<;Y_FH#vccYI%^6F6}U$DcmG; z$IVY%mk+R(-Jj_KIyG<_sSsqb-H4LN0>7KNatR+s_ApT}NUx%&xSY{-+?vnut!m;$ zI+JDli+DW9LG&Yr_n9h_PX{rObmoQzhpW}d?fyJt1*em~>{v&bRLMusF-7XDyZvR2H!#( zi86|A^cB*&Q7UW~TU{+J^cUjxiT2KA!>j+h3cAO&#*5**HKvPT&c^dedDvQ>lP`FrAB} zp1V2pwQgdrr#bYU5;d%^MCIjz=h3{6&JElNf%#bd%*glQ)y(Y~7r0JJwrpzUodPK` z8mobGB}Bg!fT|MJu7(Sq`03}&w z&af*E;665Q@CW?vw&YT$w!c0ot`|c_b!%v6B6M?eoIfZD%MDEoqt(4 z4u>y(O4u!p14)T+%YFzaia6{pY+bb^IPuZ=^b7OSeXcwO^0}~<8ZBDW4XpVHDBz5& zSzygK&79;479W!tT}Dwx6)F{Y?gK^@#7!rc5Uy;5dCfL+FJ9 zst+coS*@$d8-1gU?l=uy;_6&cXvcBvLj*|0@V=sb+a)j{TZK&w?+=eZF}r{gj-bUP zg2N2%B6F|cGQg)JFK|u7*Y(D^l&uTMX882oty_ps;{hu>^mymhqR+}Oqglr-1G&l$ zUyT@WCt}^2>xJTPtbe$wjg5E@IddAVbx*e#&^Aj~5#8XLiv&ZmPMJ>leRBcQQflkm zb!uMn4nl(KzprE_;Ik|1mT`bgxx}(e95jtT9m{_V4X=PiJf;Hp5BB) zhoy_bLK&C4xB7wb@k+>suW^{U|N<vYNP0O$lT0!4PKtC(XwwNFT!z+)W>w_yQd)I z2^_cQmlo#Kuu`WFa^W>BgS;<&sfsI#bMj{zV|h1_Ei?1Z1U;As!GLo@kig4xAl?ld z)S@rir1wCgj`propqJDjbE<@A!wu!ad9KZscdL#N1K>E}83DB6eEC&kehrLa5UiIk zm1o8CDpNUZWslmlJLC1>n@o2%ZY=IYcu*oICy29Fr!c30EMQ{E-#CmE=0uRyQJ!sg zC8+Sb!kpfu*~z>T_9GDYU5d($`rX_1a=g<;BdgVU>tEW_H}2NNV_~HO#TAoc~VUg=$HI z%n7e=GtiC=Pn2-TGfM$;>~xjGPV@2W1auGCUu&%ZI_YbiNSYc@_{=+xD>RjVVY=D0 zDK>9wVY(&bD^#DMZ{^jOfSr+_{!P1;b}=0ped&y(mHjbL6I(kI*e~R3pA|S6rLSED zo!wU|=OcPS^*N9W&-kL?Z(64I5~yIhxoXt4m$02ei2Z#aZlU}M#O?t~fQ7Z3;*b;e z#`ToSh+Fa=^J$X-58B;D1xS^&DJ14lR7(^NwcsBtLM(0p#GQ}?p5hh2ddm_-a>8bx zB~Gv)0v^|ORI=VO|3AN;$E0loeFB@^MdkjLSV=h2FjEr!7@OH2C)Wa$b~ei-2QGD! z3Aj|*2#%fv`MKrPkq4-atB$=1@EBxtMUHJPoYq5_2%E4V6{28P3D*qB`IE<0d%!P% z{Fb6O6Euv=)mFoi8|}3V5q9k*u^ZKd%s`IdyE|V13JB|ET7IfXf*kQdt~r-(F{^+3 z2*EqGDY}v52ZRYjkC3F|UIMCe}vK+lNHVcmD;b7mjGnm~I#){;cTgD50QA%nc^TWNM9 z?BxNqJN6?+1BH2-3h;L-@pcm{xB_Jn&~Zw3{=O=s+3oBPrYPEaOBb@X{wiCt8hGb+ z-5NbPyZUH3L5|Yy!YT<)!_yPab$}!_otjS(P5dk&6#b$9ex&T!^=`yp2oa>7OX(&V zEl4}u1Sgb;_uToOM2HBJA8O?UD)1_{L3I+cYz2h0F{gDR=OrLQ#0J6%9B`Br-R0-D3c5E`JH&F@DR2V14ZDrWF?df_O4AGG%erA zk>n@znA^NU^&<(iM3|()Onsi3Tn^}YwL$u?o|mrA8;0%IAY%*h0MMn}3y)3ypkmPR z_8x6;DA4vGm|zMH%n>PF&YOXF*Lm zTSzbkxp1IrNh$%0)4-8- zcT*O91Zdn%3UEZynu{Jd@jB4#Bt8VXT*N!^5HvfVSJlNXLm%qoM8^zVBWI2wp@2px z#5|>I)nX3#DidsQ4pzw`jqXEn*U=&<3vF}UK1)b(<*ipEhJ?`$4Y+`(pTVwRJMNVP2;Ie+6 z=-tF^opG3yFkMAr+EN-Uw}^eT<-p}r7qUqvH`>=?yc=|pXUF`GTAGaKw~!&Y4Vh6x zso38>C43@4_?Nm`oB(tFB-QDdguPkJ;)#vWL*$jn-l>G_`vF8!Sv9tCPfao7vlgBE zNI>a;ouGu_ZG;z?ut6O`qf#awg?qpa29;=rm7J&&r^8C9Q;Cl#HCZXTgdzkBFsX1d zMEMjpnhixjlvr3?0z~3DV_#YX8Wy|LB5q@`8i-`2up>B<3tt<-k!;y6(Lpf4*PPiQ zQk7dKX^$5_Q@lUmV#Pj^cDe8wxBK&XC3TCn6?L{_!H?P#;&DLIni+f?HpymKVrYxI zr3Bo>DtC(k)N*z1p5_>6is6JDSm%yLgId_?jw0w<+~$tdq(HN~xf{&Og?Vb?<$Jfj2L9L{CMjrU;OTN}5>-^Eo1Z^JsKQKbt0r8y&^8qAUgAr@hq*7J>*1 zVr%4Dv-&SlIMZ7hRtCXV5rq{)VEaFw#HxxoKaJ@(P`P>*_X$dhjsN}csX-SUEGdJz z7V%6bOp(|Sc7PypH?tBLeXG=7Fh@olp#(uU{V(fB*E=hxJ1V#SbYk?eh+DgWjcAVe zu7r0{)C0Aniu2L)&KBb-8r;x(6c@?2r{A69;}e>kydB^D6HgB|t|*^Zvaje#g~Gtg zR7S2$4O2Pb1@RdgJBrA|BC2nTbJ=}GX%!*C#y`q4KB}okqpO~`wTSV(mA9Wp+-upe zJw5(w>qQ#>1i@_%eo|8tDdK!Lz&0sy7SOH#@V{aB1xIc^Q)&-Aw$)=Vy^)|dr`v>9 zv+xv&b@(7ra+kw8N==Av?xPwQ8U8TBBv@yl#nH672pg!6IJOZ(CE;cT3rDO>wXE$w zMV>9k067T9{%x1t*#~$=lhqE zD=8gii5ZUVK~N&QaM=DirdmD-ZuJc{A|V6@888PQQIccp00 z=V)7=`aRbK2O^<%-7qjnlpq?!A`IEoS2+rJLUVNlK-fcPKDeHaMAf1#Dv^GAwj@=*S z9YZ2~@p1Ay8f-74W8D9&N+f}sf(;51$oTM4`0&ZlXS?5u$9LQY-5Qb06xtx)z4nu?MaDy z>GJ52sgrfn;-~Mxw2ACffY(Y!V@aFki6 zk-mJ85>z=O@I$ryM_(U<;feCHS6Qcl{EpH6M=iU10LS%1xhZRxwI4aA+VT67s)K7w z-~Be!q#6=edKB!tsAV)254Lr)HU=uEmu8xq-J;x?lz_CIKdolp_HJ0ddeN$Y7<2tY z)vO!G|5~hGV^cDDT$kTWc6QNAzdjo0vVpmKOLJ!;(_)f(wf&CNOl{wZpJ+(rO8*h{?OoaD=FpQ&~9b7f}5*vK(MTT>8C-D zz6U0K8B)o-)elK%T&Nj*)!k5k{&Rg$+K7q4-OdE33Hk3WL9cJ-f0vruf>t{WdRun+ zc>ag?oo{z>`*G3FjUEF8Pw5;({|7@&qkIo63VuDN<%!vC-0UkS1omBFFBLU9g+%(g z?|T}w?d`Ubs>go9W25xRmN@u_0_OZO=|Rs|v#+#LwF7TfwV&RMq;??zPh5r`Y-XSJ z{^gIcT{oOGB-)3rjdnBsyXN6@uSlq67T-lipNs|Q?iXye(n4__ZDm@sT)td*^;o5Mck-AB$l z@u>s=?)W9eAW z@TrfxuMv&Y`u(&0*QUYDuCv)Ah7&UlBLhUQGf)3~G%4Zg-tUv%{E|MynLe0v@Q%1I z!Z@m>ke9c#Eb=UmiF_KCzN|bQ=~lh)Vstq z!V4C!RvO}7yx6{Z&Nu$270=A3^6b+>O7al8OP@*OcioS+yV5+|y!mkd2|LSbLN`p* z#O!Fl_q5Obd7cS_g1_(hQgu5ZVoB1|>;vc6h#qHll=<&+3XYt5t@_R-&&H~;yoPzG z31vSFOj=_bE3pX~HEDKS`EE-_l1Wuk{&FRw&Y|QLT0@3OWghqA+?QjUBX)mQJn3R= zcMHz?duAuC9dT!ZF0^0vY@f9D=eiUB1Qh=jn#P1{9v!c&X^UQdm~$I`6SdjSc+9_z zIA)hrJM{at^&(ngKda(y>I`MwhMNxtU3nCczj+cj^Zubx8{XdCl0Wu9_Zt=IJ_lTv zMH<$7_VpdUC}Bm`xVWWpx__2c${sP7K5hB{!|J@ycPf zVs=@O-@-{5JC8Ew6uGX$49Grr`cL%FXH?w=o3D&n{W;!p<8s;BHA#x|k9)1@otQaH zl5yv^2ba;Ux?#Q6_+{>PiY$HPV{@y=p1AW7rCT=K335!|-}d>oRdz8`;I8<2So--N z>lVdq>77AMc(!46WWh2ot3&(lrwly$Y45mAsn<_$9{cb~U2hN*Klt;AFZ_+|6tgbn z{>~`o$F$?mZmJ$_$v!GsVMmVl373|xm^blpA0HdjaJ5Na@n`o*mACndD_1{ntvmkn z_ALH*&f@C*(E*)5X`Fw{es?MO^FfKlZClK#&OPJ)JmK?QaYHh1%)9rJq9Jj=2afui zT4=j#Wqf?Mv8mT8cN|_);z7Bn+Pb)|YdrSn>-Arm-3@sklqU~u`#v5o3~9Z+Fymv@ zQ9C_*vS=CSHICkX$`{1ssuL}Pcj~n%FOD0fcBN>u_4nVM;yy(TSclkI8Mp4d?5?p3 zntbT%h^)0KTb|8zc<$TtMtRM&b*Cgz@jmRq*s~~L$;2sF!M6QVmw4@MuV-F!^Mfz1 zB2nzT8$0t>RQDNuU3R~=*Vvs^nvn%dejD|oaBbGM?#E|I9_P8{R0!t^0wG?$*{VQu z<;l>x_ZzhdXU7J;91h1kp6l}KqW0;=i7(9eU;i^PUNbx7`5f)gn4hI992(Y7yE?5T zreNj!`@K|>_U!}4{dG^#>vYN3XUBFNwp(*uNWJhr85g#;R9+wJ(RWX*AVUK;cM?Qi!+930durRVGRk`A^!G4l*)mnXR@JzK1&ZfA z*6-h@n;!V-o?rQ=AL?>WUKDxOl(7NZKUratP69E_?6tG)?9vGg-^yP81SkG9^ar?P zF?UN}F0g+!8Oci?TInApP}Uejg3-Km?hOtQ};K)hMjd6 zcPXr7c5fUZ7B+^Ks+K{q#b^Jb{b6S5gQi6FC)q3VI!HlY403xKR5w%vD>;&(nD)f) zlX}haXp%QZ^U@K?e>yWv#M)x!^1va>#eU z>E%s9E0Nt-)nrCUy&FQJ6^HXSZ)f z>YH-hPV!GhRoh*7sp-6Dy_)taLF^R#U7^QZdq;7XLjjq5ls<_fBzoE$HK9|gSfPNn zMyo!)IZ5+eGh63#>t5u4LENCXMnn4BeUhaFSKMtpi*6k9_)AN2Y2D~QicP5?nhF1_ zXLv{L-%hZOH-y0M?R`4Z!auGA(I?>8f{W70Pz*O&+%b~fSkq}oQx9PAy^36$$J_lD)VNz*rZu^Ral#N1&j^Hf&a|**>ytC! zN|Hi3B%4V@39v!7x{5sw3g{N{4!GN?k$o(nUA1F%A0bW*v>R9{x*X_7=Ti%v+Z0>E zuND_^uOm0E7d^E`l1fKv=P{ei8ikNXiV!}?ZIZ_)Ih=_wiS@##N80%+|Lx{-^8F0o zcDcN|mLvIpjw_@kKSUA1@#y_-msMzc8>#JSaci#I$DJ$cXvQ|&o3>^bd2L*xl@3@v zgs?qtZ>>MLoupy_JZjbU7(f>@grghBp*t7G8{$7<=6S3%A(@IsB*|iqo|XORBoa9x z$!qM09Lv~MBbu0u#oSKOUQgcJm!g%>5o(s7*R#mwDTt=DzQO{~rhe(roVR0ReJcX9ZH z!K`{wPqgx&w=wtrJ>x1%rG*SbNN4`oBC9r{ro@sVO-9<&wDxNdEWQTd4BH~A;ffKTq!~YQ+}Fa z$dm^;V|V$UtL9>a0`@L#X7i3C`nHmbe2{e(<<_C`Fkm6BV9MB97ezJjh<7%detHYC&t&At zk+}IhASooV!dza zfyIKRE<=P}LQ+AOIfh;~#GWE8v6SyzGA4qCfremZSub4SsFcQEevEI0M2&Gvlb!1> zJw|~FiyfTaXA3;WT z>pe zKakI}Ajn`+J8@;9Xx`H-thC~5yk z=r5znnQ?E>%&@T;B8|b^tXqWR+~gQjfKn*Gzg5j7E>hY@_G}d;`ZlWP0KzyQ&M>&= zRb16B%f@Ipn7XA;9c<>Xvx{QITD*XK7A;&BLR&6x3V=LUBz}4vv$Fzq<&8d?xzE?l zem+}nE$L=PCGb>jPqM}!%2tK34vWy7m>{Qw{j-__UDoWmDB4$1%`6sg-g2uG;j>ki zq4VeBQ%kOK_u#dHN{M33eq`E^&|DYaX3>>BjR-$1;grePbur#la*i?+6T*6c3 zlr^Qv9-u>NM-NwUaP6jTqJBZeoxx3ZakYY=D?8>Z^$J14Bqa3ug^n>uK10&}UDFORqF#|m z!zwiGYRTR3I`cuv{TpiSY_K2j#k*Z_Qlp51l!o2xn0P!WAp#%torvhV_}uvqk$sh{ z4P{tVp@~0VsQYQZ5Y4&nM5gd;<3{I3kuwM8f>gxlF_k0HNqR74kNu=1cK)#VuDZ%0 ztGA;D1#@`}j_ISflwZNRW1W z+rHA@DAhmBD)BU{iqlrcQiX^PzohLU3-V*FPVtKedS)(FoR!{Y2I4BcJ3bxhs%fir z6In~;I|-vY&Pi8z<~o{nK^rc4W0ZffvY-kz=>EO9?(+TJPiEbmgLyZaQ85(^r`<(M zjAO@~ca$mk!W&&h5u;dtK?~1*V#tMu_U=N$+zO>gfH7_E|4ekJA}LB@tn1g2AgfzS zS)RAZnHgOndlUTE3(7`Sg5E<#ZBn6R6EWe?ES=5K*OO^WUmezyDhe11OjQ@wCW>=X zSyDB~_3dIlVcbf^>aZ0;O!?C3_mPr3%=V3xmqy9E>Pk^faUxQOXm29Lrb;?ifHC~X z5^s$6Aivc&=`^>C5)az0ytH{AnU3sU_z*7epQp)LJ9o-|9en5>^;?sGEl;H^ZQRTW z@Fpe=v4;J1Jr0xbsVT$5o!Pvk)*_fVt6?^$I;D%YU~;Tqk^0_5pGvCDg2Iz-5llT@ zPb`{hEpi24=f9i=Fq5H8{8Vk+DoQ5GaxB9syX9JUvTDKS=?28E_Rkn)IdCG9TJ@fH zYfS=?2?}e((-Ca}XX*X;fAVT7X&J&yD~G9`zBYFo25IpLJolf3{5!8@?UeDjU39(Z zrL~SOCcy{1>eeCGKbMR0og0OOC2Vz&r!@OWt>C6rY^TWC8ozZkFPhp()jfGxnP7#< zVRW>U`%_f^k9LWRMD$t{c%q38Yd+i1!9#1qdHk#8M&o zuMkq9P6!NmWmJIX`tNQ1;}6kxp24kWD-~7sR0NE5!V9q7MY=JhzNb_b5|5Sm>~1*w zkb-hwYGhP?ENX&Nh&Lsm}XWg_3m(7tZv=I^K|*LOsAtKR_x+tI2}F~er~R3pwD8*ys+8=Fh03y z{_zvym&;z{(`87GvSNW>c5`vs>$cX{UYWZu2_U?|amZ@v0Lqlzs{Y$@Z5hwq?Mkfz zRwKdG08p+OA6s>)Fmr>oxT5&PiD9pBG69choI_kMHzR3JWl|H3mBBqhaU?10;!AYs zJOTX(m$&njfwT`@^{kP8BesYLR5o?z)bGaI`&xP(x4;GWZxF3_8@rF2vq{zcEFTYX ziI)4#qg9Zlsiv0Ah|e`8axdUyU}-R@L5F4V1pLf;qq0^OqzoDr5#G!Ct8YUv`ZYdN zx#^}efz>G{j7|gv;xHUkr@_S3>Pl;!DQT6`sBDVf1XKa_#{lx_>ukJ5_yY32=?3;V zo8084yHA+$SkWPjn2LeUwvwlpOM&JeWICnvoSGqj@8IJJ)Qri~hTd`XJpahEW7t*O z+vhVf3@7Imm)n~qO8~2q`D^s3=7I{kv(t{8jQ6oIk7L+8NRMcluB_x)o~b%Xw=KA^ zGQkN`>#=3_q0hcwdcfH`JFZ1IsbSZ4>y!cZof$sv!>G1>3l=vE2Az0Rqlm^*L{%kz z)|Z8{%g3V1d~I*vGdeS3he5orwZ`@?!Inko1bbMBaaA31Cudo2wS?HN`im)m?HzM*;fAsGsZ`gA{{_7X?Lmub$!|ZD3iVW|< z4Tar~H(%-3NTZKL51wo=oo{wcv19FP+e=8tw(8{cTwl-T`IqK&YVmXi8hZ#l`WbpF zF0_Ld44@xUqqJ!SOcrc&Vmh+*`LxA*!rDi^W5Pj3YCG`x)Gsd}to`fcz;EH${y8O5 zjXIq7fpqv56FE76^MUKQW_{?Y9xh}6hs9mRUCj*%TgS4tvSy9=P&SMky80tpvbRCc zJ0D6$tPA>3ZFqRNRk&?W#Q>VLX8F3$UC_g%v+r;l8W?gT+5ZR(=)Y=;RQ< znam00`iG&RPA>i%f&xrtqT#E!p<_*4{8tD0hnUO=2=@;SSm(g%RZwjdz+J})4O*jy zX*vO%(hBI5CMy6|X#(6#lXu+39;4m`)rLUy}ul>7oA$VYH{d|C21rdD|z;Fm<1REb78t?!SIjn8}O?=;~XrDZoboz4@;5Z(*bU zYu2m^;`AU%SsOwEKI4~KzKbz6MD-)KbPSBQ2dDXkCf+kfzuE}O3F88*6wdhYOPnTXt6%7?bWMXZ7=P$`unc6&zYGd=%x3+ z-{E2W{nTj@_-5TvSI}>$9MS=0Q>J4A*veA`!qaCgc@W&KHy8T7*Sm&u`L6BQx zL%Ze?y|qrfs2KkwtS*hA0Vdau*@1_|!pC=f^^-BW%wpjO~5Gj8+7 zNw<-=(`|MIb~)seN@INa}=a1>&6$8F}0}lBLh;Ctuj_3&nXeTe;f>Qi3#QyX1UBt<`gQ9iPjC&s&uJ2mJzlcnRtAJE%@9B z7_RNCMK?Y&(6bCF-bD2R6SD<=R`0I?!Gui#(H4lI=?qj4_4CqFJb{O;6TmOenQv78>ki zxAK9Z8i7^Drm`9|@=h+j4v2X&z(hk8h$?V*MSCK`;Q2rKeT?mQHxG;$q$k(9+%b4) zG92%YO=ET3*A^UyuF7NS@^C*8Wu92QGVY(X4ebis{I+cY$F}MJ8`}y*7a|eY(-SMQ zm3d+_a<(lxj=Dzex}pQawqntzn=_%r9Ya)C-kZfboep`X-hT>kmw76nc^b1&4*PZ! zo~R?@iq!xzkG#|I)FrAE`i?bR#@of`xyIYCGO-OYCN|ag&t#1%4#9E%qkT^7 z$Zt#C9mD*n)Sac&VZ7*sIgHT3F=z99Qd#FJoowhPW-oYU!c^}>J%*@?!W~)k-(j-L z^JFpKPR=&#biE%&yUi7>pk$gsNbtHPY+Z|vQ6OPB;6?Q1N!VHmP^x2=-Rq zVRbNMs^irHbgC(Dy6Vg3Ie9v7hfc(*u-=c7+&iE|&0#mNN)#LzV3N?C$4$1H1aj~X7}1+S17f*J()6AV%S9Zjo5-$G4PK9|}4Ng17d#l=oOm#n{~JeS*C_X!!D ze4&t&PuYp^2Rq}O3+uJX%1$&EQlDxk#!6Usnd>79w||bQ)p|dp{1lw~ zwod5$gi#x|HiH*1(io{dW*5>E4JE$|9jemo7E1av`CQhr3q2~!{X&jwrocp#q6`T$uSdbrQZ;%%pMS?l*hIRoi!U`rI|*uwv1zki!h%OqFXpRF4F!& zAUbLF>N||{^HiA@gwM+|a=OfnFpNCU^nwD_-xdX!Bw`uSu4Fq@hjbA`|0fH(T5BsQs;O?!eRhJc9v%Dbc6P zFpOh^Nayn|0Uo;)07^KvoP~D9cn@2%RBSOX15ZpSzZ(AGo!`?KeoE18Uh{HhPlqhJ zeXhhSKrOqOmwX0xBRuy%0KJGi7|ZCHfgLV{D%q<{h6u0k0|QJFdTbm9+YYxQff!|2 zUt|d;2|acKOL!a!#682hiY1sN^w^0kVK@@#>xQ+9C72|14tA4wVEwJ^z{oNzbgaMt zlY}0d014i1VYdU{sBw-M7*;bKDvSzYoI`@+@-gDTmxRAT@ijth;TY=Vmkp4e9X?Y0 zyf|WBo6GJjtq{L;!qmetHJsZbqp?0=i_9Enr*#Ua;ZBTpCaay+E5$ZyNOfMJT08dF zQN>~^=Gf2ecPh%n6cx7afTMWcWo7o(i+cKta&*Z+Dvts4N$8v(HE6eFa2WNX6pIA=sXZi2jB zkFO$Gn>*rQj(IcF^nOn3{a<6sEevi2kmh5CVRBAxzO4PD7Y(%^^I+KeI;7ZsR%2M- z0NgHmVgDW=L)uRY-wP_*OdZRh9b6Q*?brKn1220{^GzW6m9W|9@p4$hY^Nri*86Xl z4CqjKRbftERqVQ)Minb_b!kHRQLYO*9M8Ag*$h;P_1RStHDVs>^=;6Hv_ z@4pj7z5gy|eFp%3No<)QR7PjsMg>|whbh51B+0MeO`aV35p&F)spC$VD1DZbofT>wqPh`D6 z1d;W!9Q3jvE4&|1>j8k+g8^i zsvpJk*s2eJqxSWB|3Re9p8%*ifqjb@8@3(;iFLCqbh8*MeH>5grvR}h0J8SN0Y77j z{+|PyzhG9b{upgx>zAOhJ{E&MmScUt!qa*ZKy9Y;+UnOJIz~Q)wD}tVsXyC@Z`gVo z6xPY2(8*G)^BFv?-vY#*1<2aCT<`xKaF^cy93JMsGB4XkG1m7yNUV>=ppV5^-wSwJ zF9O7V4^WHo=B6#MVG{CWmy!VvxYkQ7wHRU5WgbG(d>No%@+7bM3KE­wvVwg`M% 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 XRn{~!E6bbF%qzwsDyaRS}bu@=wUbC+})f( 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 WAF1OL{1hX&{7zlY?IppVSN{v=XQ+k% literal 0 HcmV?d00001 diff --git a/packages/SignalR.Js.0.4.0/content/Scripts/jquery.signalR.js b/packages/SignalR.Js.0.4.0/content/Scripts/jquery.signalR.js new file mode 100644 index 000000000..c877e0577 --- /dev/null +++ b/packages/SignalR.Js.0.4.0/content/Scripts/jquery.signalR.js @@ -0,0 +1,885 @@ +/// +(function ($, window) { + /// + "use strict"; + + if (typeof ($) !== "function") { + // no jQuery! + throw "SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file."; + } + + if (!window.JSON) { + // no JSON! + throw "SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8."; + } + + var signalR, + _connection, + events = { + onStart: "onStart", + onStarting: "onStarting", + onSending: "onSending", + onReceived: "onReceived", + onError: "onError", + onReconnect: "onReconnect", + onDisconnect: "onDisconnect" + }, + log = function (msg, logging) { + if (logging === false) { + return; + } + var m; + if (typeof (window.console) === "undefined") { + return; + } + m = "[" + new Date().toTimeString() + "] SignalR: " + msg; + if (window.console.debug) { + window.console.debug(m); + } else if (window.console.log) { + window.console.log(m); + } + }; + + signalR = function (url, qs, logging) { + /// Creates a new SignalR connection for the given url + /// The URL of the long polling endpoint + /// + /// [Optional] Custom querystring parameters to add to the connection URL. + /// If an object, every non-function member will be added to the querystring. + /// If a string, it's added to the QS as specified. + /// + /// + /// [Optional] A flag indicating whether connection logging is enabled to the browser + /// console/log. Defaults to false. + /// + /// + + return new signalR.fn.init(url, qs, logging); + }; + + signalR.fn = signalR.prototype = { + init: function (url, qs, logging) { + this.url = url; + this.qs = qs; + if (typeof (logging) === "boolean") { + this.logging = logging; + } + }, + + logging: false, + + reconnectDelay: 2000, + + start: function (options, callback) { + /// Starts the connection + /// Options map + /// A callback function to execute when the connection has started + var connection = this, + config = { + transport: "auto" + }, + initialize, + promise = $.Deferred(); + + if (connection.transport) { + // Already started, just return + promise.resolve(connection); + return promise; + } + + if ($.type(options) === "function") { + // Support calling with single callback parameter + callback = options; + } else if ($.type(options) === "object") { + $.extend(config, options); + if ($.type(config.callback) === "function") { + callback = config.callback; + } + } + + $(connection).bind(events.onStart, function (e, data) { + if ($.type(callback) === "function") { + callback.call(connection); + } + promise.resolve(connection); + }); + + initialize = function (transports, index) { + index = index || 0; + if (index >= transports.length) { + if (!connection.transport) { + // No transport initialized successfully + promise.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization."); + } + return; + } + + var transportName = transports[index], + transport = $.type(transportName) === "object" ? transportName : signalR.transports[transportName]; + + transport.start(connection, function () { + connection.transport = transport; + $(connection).trigger(events.onStart); + }, function () { + initialize(transports, index + 1); + }); + }; + + window.setTimeout(function () { + $.ajax(connection.url + "/negotiate", { + global: false, + type: "POST", + data: {}, + error: function (error) { + $(connection).trigger(events.onError, [error]); + promise.reject("SignalR: Error during negotiation request: " + error); + }, + success: function (res) { + connection.appRelativeUrl = res.Url; + connection.id = res.ConnectionId; + connection.webSocketServerUrl = res.WebSocketServerUrl; + + if (!res.ProtocolVersion || res.ProtocolVersion !== "1.0") { + $(connection).trigger(events.onError, "SignalR: Incompatible protocol version."); + promise.reject("SignalR: Incompatible protocol version."); + return; + } + + $(connection).trigger(events.onStarting); + + var transports = [], + supportedTransports = []; + + $.each(signalR.transports, function (key) { + if (key === "webSockets" && !res.TryWebSockets) { + // Server said don't even try WebSockets, but keep processing the loop + return true; + } + supportedTransports.push(key); + }); + + if ($.isArray(config.transport)) { + // ordered list provided + $.each(config.transport, function () { + var transport = this; + if ($.type(transport) === "object" || ($.type(transport) === "string" && $.inArray("" + transport, supportedTransports) >= 0)) { + transports.push($.type(transport) === "string" ? "" + transport : transport); + } + }); + } else if ($.type(config.transport) === "object" || + $.inArray(config.transport, supportedTransports) >= 0) { + // specific transport provided, as object or a named transport, e.g. "longPolling" + transports.push(config.transport); + } else { // default "auto" + transports = supportedTransports; + } + initialize(transports); + } + }); + }, 0); + + return promise; + }, + + starting: function (callback) { + /// Adds a callback that will be invoked before the connection is started + /// A callback function to execute when the connection is starting + /// + var connection = this, + $connection = $(connection); + + $connection.bind(events.onStarting, function (e, data) { + callback.call(connection); + // Unbind immediately, we don't want to call this callback again + $connection.unbind(events.onStarting); + }); + + return connection; + }, + + send: function (data) { + /// Sends data over the connection + /// The data to send over the connection + /// + var connection = this; + + if (!connection.transport) { + // Connection hasn't been started yet + throw "SignalR: Connection must be started before data can be sent. Call .start() before .send()"; + } + + connection.transport.send(connection, data); + + return connection; + }, + + sending: function (callback) { + /// Adds a callback that will be invoked before anything is sent over the connection + /// A callback function to execute before each time data is sent on the connection + /// + var connection = this; + $(connection).bind(events.onSending, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + received: function (callback) { + /// Adds a callback that will be invoked after anything is received over the connection + /// A callback function to execute when any data is received on the connection + /// + var connection = this; + $(connection).bind(events.onReceived, function (e, data) { + callback.call(connection, data); + }); + return connection; + }, + + error: function (callback) { + /// Adds a callback that will be invoked after an error occurs with the connection + /// A callback function to execute when an error occurs on the connection + /// + var connection = this; + $(connection).bind(events.onError, function (e, data) { + callback.call(connection, data); + }); + return connection; + }, + + disconnected: function (callback) { + /// Adds a callback that will be invoked when the client disconnects + /// A callback function to execute when the connection is broken + /// + var connection = this; + $(connection).bind(events.onDisconnect, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + reconnected: function (callback) { + /// Adds a callback that will be invoked when the underlying transport reconnects + /// A callback function to execute when the connection is restored + /// + var connection = this; + $(connection).bind(events.onReconnect, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + stop: function () { + /// Stops listening + /// + var connection = this; + + if (connection.transport) { + connection.transport.stop(connection); + connection.transport = null; + } + + delete connection.messageId; + delete connection.groups; + + // Trigger the disconnect event + $connection.trigger(events.onDisconnect); + + return connection; + }, + + log: log + }; + + signalR.fn.init.prototype = signalR.fn; + + + // Transports + var transportLogic = { + + addQs: function (url, connection) { + if (!connection.qs) { + return url; + } + + if (typeof (connection.qs) === "object") { + return url + "&" + $.param(connection.qs); + } + + if (typeof (connection.qs) === "string") { + return url + "&" + connection.qs; + } + + return url + "&" + escape(connection.qs.toString()); + }, + + getUrl: function (connection, transport, reconnecting) { + /// Gets the url for making a GET based connect request + var url = connection.url, + qs = "transport=" + transport + "&connectionId=" + window.escape(connection.id); + + if (connection.data) { + qs += "&connectionData=" + window.escape(connection.data); + } + + if (!reconnecting) { + url = url + "/connect"; + } else { + if (connection.messageId) { + qs += "&messageId=" + connection.messageId; + } + if (connection.groups) { + qs += "&groups=" + window.escape(JSON.stringify(connection.groups)); + } + } + url += "?" + qs; + url = this.addQs(url, connection); + return url; + }, + + ajaxSend: function (connection, data) { + var url = connection.url + "/send" + "?transport=" + connection.transport.name + "&connectionId=" + window.escape(connection.id); + url = this.addQs(url, connection); + $.ajax(url, { + global: false, + type: "POST", + dataType: "json", + data: { + data: data + }, + success: function (result) { + if (result) { + $(connection).trigger(events.onReceived, [result]); + } + }, + error: function (errData, textStatus) { + if (textStatus === "abort") { + return; + } + $(connection).trigger(events.onError, [errData]); + } + }); + }, + + processMessages: function (connection, data) { + var $connection = $(connection); + + if (data) { + if (data.Disconnect) { + log("Disconnect command received from server", connection.logging); + + // Disconnected by the server + connection.stop(); + + // Trigger the disconnect event + $connection.trigger(events.onDisconnect); + return; + } + + if (data.Messages) { + $.each(data.Messages, function () { + try { + $connection.trigger(events.onReceived, [this]); + } + catch (e) { + log("Error raising received " + e, connection.logging); + $(connection).trigger(events.onError, [e]); + } + }); + } + connection.messageId = data.MessageId; + connection.groups = data.TransportData.Groups; + } + }, + + foreverFrame: { + count: 0, + connections: {} + } + }; + + signalR.transports = { + + webSockets: { + name: "webSockets", + + send: function (connection, data) { + connection.socket.send(data); + }, + + start: function (connection, onSuccess, onFailed) { + var url, + opened = false, + protocol; + + if (window.MozWebSocket) { + window.WebSocket = window.MozWebSocket; + } + + if (!window.WebSocket) { + onFailed(); + return; + } + + if (!connection.socket) { + if (connection.webSocketServerUrl) { + url = connection.webSocketServerUrl; + } + else { + // Determine the protocol + protocol = document.location.protocol === "https:" ? "wss://" : "ws://"; + + url = protocol + document.location.host + connection.appRelativeUrl; + } + + // Build the url + $(connection).trigger(events.onSending); + if (connection.data) { + url += "?connectionData=" + connection.data + "&transport=webSockets&connectionId=" + connection.id; + } else { + url += "?transport=webSockets&connectionId=" + connection.id; + } + + connection.socket = new window.WebSocket(url); + connection.socket.onopen = function () { + opened = true; + if (onSuccess) { + onSuccess(); + } + }; + + connection.socket.onclose = function (event) { + if (!opened) { + if (onFailed) { + onFailed(); + } + } else if (typeof event.wasClean != "undefined" && event.wasClean === false) { + // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but + // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers. + $(connection).trigger(events.onError); + // TODO: Support reconnect attempt here, need to ensure last message id, groups, and connection data go up on reconnect + } + connection.socket = null; + }; + + connection.socket.onmessage = function (event) { + var data = window.JSON.parse(event.data), + $connection; + if (data) { + $connection = $(connection); + + if (data.Messages) { + $.each(data.Messages, function () { + try { + $connection.trigger(events.onReceived, [this]); + } + catch (e) { + log("Error raising received " + e, connection.logging); + } + }); + } else { + $connection.trigger(events.onReceived, [data]); + } + } + }; + } + }, + + stop: function (connection) { + if (connection.socket !== null) { + connection.socket.close(); + connection.socket = null; + } + } + }, + + serverSentEvents: { + name: "serverSentEvents", + + timeOut: 3000, + + start: function (connection, onSuccess, onFailed) { + var that = this, + opened = false, + $connection = $(connection), + reconnecting = !onSuccess, + url, + connectTimeOut; + + if (connection.eventSource) { + connection.stop(); + } + + if (!window.EventSource) { + if (onFailed) { + onFailed(); + } + return; + } + + $connection.trigger(events.onSending); + + url = transportLogic.getUrl(connection, this.name, reconnecting); + + try { + connection.eventSource = new window.EventSource(url); + } + catch (e) { + log("EventSource failed trying to connect with error " + e.Message, connection.logging); + if (onFailed) { + // The connection failed, call the failed callback + onFailed(); + } + else { + $connection.trigger(events.onError, [e]); + if (reconnecting) { + // If we were reconnecting, rather than doing initial connect, then try reconnect again + log("EventSource reconnecting", connection.logging); + that.reconnect(connection); + } + } + return; + } + + // After connecting, if after the specified timeout there's no response stop the connection + // and raise on failed + connectTimeOut = window.setTimeout(function () { + if (opened === false) { + log("EventSource timed out trying to connect", connection.logging); + + if (onFailed) { + onFailed(); + } + + if (reconnecting) { + // If we were reconnecting, rather than doing initial connect, then try reconnect again + log("EventSource reconnecting", connection.logging); + that.reconnect(connection); + } else { + that.stop(connection); + } + } + }, + that.timeOut); + + connection.eventSource.addEventListener("open", function (e) { + log("EventSource connected", connection.logging); + + if (connectTimeOut) { + window.clearTimeout(connectTimeOut); + } + + if (opened === false) { + opened = true; + + if (onSuccess) { + onSuccess(); + } + + if (reconnecting) { + $connection.trigger(events.onReconnect); + } + } + }, false); + + connection.eventSource.addEventListener("message", function (e) { + // process messages + if (e.data === "initialized") { + return; + } + transportLogic.processMessages(connection, window.JSON.parse(e.data)); + }, false); + + connection.eventSource.addEventListener("error", function (e) { + if (!opened) { + if (onFailed) { + onFailed(); + } + return; + } + + log("EventSource readyState: " + connection.eventSource.readyState, connection.logging); + + if (e.eventPhase === window.EventSource.CLOSED) { + // connection closed + if (connection.eventSource.readyState === window.EventSource.CONNECTING) { + // We don't use the EventSource's native reconnect function as it + // doesn't allow us to change the URL when reconnecting. We need + // to change the URL to not include the /connect suffix, and pass + // the last message id we received. + log("EventSource reconnecting due to the server connection ending", connection.logging); + that.reconnect(connection); + } + else { + // The EventSource has closed, either because its close() method was called, + // or the server sent down a "don't reconnect" frame. + log("EventSource closed", connection.logging); + that.stop(connection); + } + } else { + // connection error + log("EventSource error", connection.logging); + $connection.trigger(events.onError); + } + }, false); + }, + + reconnect: function (connection) { + var that = this; + window.setTimeout(function () { + that.stop(connection); + that.start(connection); + }, connection.reconnectDelay); + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + stop: function (connection) { + if (connection && connection.eventSource) { + connection.eventSource.close(); + connection.eventSource = null; + delete connection.eventSource; + } + } + }, + + foreverFrame: { + name: "foreverFrame", + + timeOut: 3000, + + start: function (connection, onSuccess, onFailed) { + var that = this, + frameId = (transportLogic.foreverFrame.count += 1), + url, + connectTimeOut, + frame = $(""); + + if (window.EventSource) { + // If the browser supports SSE, don't use Forever Frame + if (onFailed) { + onFailed(); + } + return; + } + + $(connection).trigger(events.onSending); + + // Build the url + url = transportLogic.getUrl(connection, this.name); + url += "&frameId=" + frameId; + + frame.prop("src", url); + transportLogic.foreverFrame.connections[frameId] = connection; + + frame.bind("readystatechange", function () { + if ($.inArray(this.readyState, ["loaded", "complete"]) >= 0) { + log("Forever frame iframe readyState changed to " + this.readyState + ", reconnecting", connection.logging); + that.reconnect(connection); + } + }); + + connection.frame = frame[0]; + connection.frameId = frameId; + + if (onSuccess) { + connection.onSuccess = onSuccess; + } + + $("body").append(frame); + + // After connecting, if after the specified timeout there's no response stop the connection + // and raise on failed + connectTimeOut = window.setTimeout(function () { + if (connection.onSuccess) { + that.stop(connection); + + if (onFailed) { + onFailed(); + } + } + }, that.timeOut); + }, + + reconnect: function (connection) { + var that = this; + window.setTimeout(function () { + var frame = connection.frame, + src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId; + frame.src = src; + }, connection.reconnectDelay); + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + receive: transportLogic.processMessages, + + stop: function (connection) { + if (connection.frame) { + if (connection.frame.stop) { + connection.frame.stop(); + } else if (connection.frame.document && connection.frame.document.execCommand) { + connection.frame.document.execCommand("Stop"); + } + $(connection.frame).remove(); + delete transportLogic.foreverFrame.connections[connection.frameId]; + connection.frame = null; + connection.frameId = null; + delete connection.frame; + delete connection.frameId; + } + }, + + getConnection: function (id) { + return transportLogic.foreverFrame.connections[id]; + }, + + started: function (connection) { + if (connection.onSuccess) { + connection.onSuccess(); + connection.onSuccess = null; + delete connection.onSuccess; + } + else { + // If there's no onSuccess handler we assume this is a reconnect + $(connection).trigger(events.onReconnect); + } + } + }, + + longPolling: { + name: "longPolling", + + reconnectDelay: 3000, + + start: function (connection, onSuccess, onFailed) { + /// Starts the long polling connection + /// The SignalR connection to start + var that = this; + if (connection.pollXhr) { + connection.stop(); + } + + connection.messageId = null; + + window.setTimeout(function () { + (function poll(instance, raiseReconnect) { + $(instance).trigger(events.onSending); + + var messageId = instance.messageId, + connect = (messageId === null), + url = transportLogic.getUrl(instance, that.name, !connect), + reconnectTimeOut = null, + reconnectFired = false; + + instance.pollXhr = $.ajax(url, { + global: false, + + type: "GET", + + dataType: "json", + + success: function (data) { + var delay = 0, + timedOutReceived = false; + + if (raiseReconnect === true) { + // Fire the reconnect event if it hasn't been fired as yet + if (reconnectFired === false) { + $(instance).trigger(events.onReconnect); + reconnectFired = true; + } + } + + transportLogic.processMessages(instance, data); + if (data && $.type(data.TransportData.LongPollDelay) === "number") { + delay = data.TransportData.LongPollDelay; + } + + if (data && data.TimedOut) { + timedOutReceived = data.TimedOut; + } + + if (delay > 0) { + window.setTimeout(function () { + poll(instance, timedOutReceived); + }, delay); + } else { + poll(instance, timedOutReceived); + } + }, + + error: function (data, textStatus) { + if (textStatus === "abort") { + return; + } + + if (reconnectTimeOut) { + // If the request failed then we clear the timeout so that the + // reconnect event doesn't get fired + clearTimeout(reconnectTimeOut); + } + + $(instance).trigger(events.onError, [data]); + + window.setTimeout(function () { + poll(instance, true); + }, connection.reconnectDelay); + } + }); + + if (raiseReconnect === true) { + reconnectTimeOut = window.setTimeout(function () { + if (reconnectFired === false) { + $(instance).trigger(events.onReconnect); + reconnectFired = true; + } + }, + that.reconnectDelay); + } + + } (connection)); + + // Now connected + // There's no good way know when the long poll has actually started so + // we assume it only takes around 150ms (max) to start the connection + window.setTimeout(onSuccess, 150); + + }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + stop: function (connection) { + /// Stops the long polling connection + /// The SignalR connection to stop + if (connection.pollXhr) { + connection.pollXhr.abort(); + connection.pollXhr = null; + delete connection.pollXhr; + } + } + } + }; + + signalR.noConflict = function () { + /// Reinstates the original value of $.connection and returns the signalR object for manual assignment + /// + if ($.connection === signalR) { + $.connection = _connection; + } + return signalR; + }; + + if ($.connection) { + _connection = $.connection; + } + + $.connection = $.signalR = signalR; + +} (window.jQuery, window)); \ No newline at end of file diff --git a/packages/SignalR.Js.0.4.0/content/Scripts/jquery.signalR.min.js b/packages/SignalR.Js.0.4.0/content/Scripts/jquery.signalR.min.js new file mode 100644 index 000000000..9e99f53a3 --- /dev/null +++ b/packages/SignalR.Js.0.4.0/content/Scripts/jquery.signalR.min.js @@ -0,0 +1 @@ +(function(n,t){"use strict";var f,e,i,r,u;if(typeof n!="function")throw"SignalR: jQuery not found. Please ensure jQuery is referenced before the SignalR.js file.";if(!t.JSON)throw"SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.";i={onStart:"onStart",onStarting:"onStarting",onSending:"onSending",onReceived:"onReceived",onError:"onError",onReconnect:"onReconnect",onDisconnect:"onDisconnect"},r=function(n,i){if(i===!1)return;var r;if(typeof t.console=="undefined")return;r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r)},f=function(n,t,i){return new f.fn.init(n,t,i)},f.fn=f.prototype={init:function(n,t,i){this.url=n,this.qs=t,typeof i=="boolean"&&(this.logging=i)},logging:!1,reconnectDelay:2e3,start:function(r,u){var e=this,o={transport:"auto"},h,s=n.Deferred();return e.transport?(s.resolve(e),s):(n.type(r)==="function"?u=r:n.type(r)==="object"&&(n.extend(o,r),n.type(o.callback)==="function"&&(u=o.callback)),n(e).bind(i.onStart,function(){n.type(u)==="function"&&u.call(e),s.resolve(e)}),h=function(t,r){r=r||0;if(r>=t.length){e.transport||s.reject("SignalR: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.");return}var u=t[r],o=n.type(u)==="object"?u:f.transports[u];o.start(e,function(){e.transport=o,n(e).trigger(i.onStart)},function(){h(t,r+1)})},t.setTimeout(function(){n.ajax(e.url+"/negotiate",{global:!1,type:"POST",data:{},error:function(t){n(e).trigger(i.onError,[t]),s.reject("SignalR: Error during negotiation request: "+t)},success:function(t){e.appRelativeUrl=t.Url,e.id=t.ConnectionId,e.webSocketServerUrl=t.WebSocketServerUrl;if(!t.ProtocolVersion||t.ProtocolVersion!=="1.0"){n(e).trigger(i.onError,"SignalR: Incompatible protocol version."),s.reject("SignalR: Incompatible protocol version.");return}n(e).trigger(i.onStarting);var u=[],r=[];n.each(f.transports,function(n){if(n==="webSockets"&&!t.TryWebSockets)return!0;r.push(n)}),n.isArray(o.transport)?n.each(o.transport,function(){var t=this;n.type(t)!=="object"&&(n.type(t)!=="string"||n.inArray(""+t,r)<0)||u.push(n.type(t)==="string"?""+t:t)}):n.type(o.transport)!=="object"&&n.inArray(o.transport,r)<0?u=r:u.push(o.transport),h(u)}})},0),s)},starting:function(t){var r=this,u=n(r);return u.bind(i.onStarting,function(){t.call(r),u.unbind(i.onStarting)}),r},send:function(n){var t=this;if(!t.transport)throw"SignalR: Connection must be started before data can be sent. Call .start() before .send()";return t.transport.send(t,n),t},sending:function(t){var r=this;return n(r).bind(i.onSending,function(){t.call(r)}),r},received:function(t){var r=this;return n(r).bind(i.onReceived,function(n,i){t.call(r,i)}),r},error:function(t){var r=this;return n(r).bind(i.onError,function(n,i){t.call(r,i)}),r},disconnected:function(t){var r=this;return n(r).bind(i.onDisconnect,function(){t.call(r)}),r},reconnected:function(t){var r=this;return n(r).bind(i.onReconnect,function(){t.call(r)}),r},stop:function(){var n=this;return n.transport&&(n.transport.stop(n),n.transport=null),delete n.messageId,delete n.groups,$connection.trigger(i.onDisconnect),n},log:r},f.fn.init.prototype=f.fn,u={addQs:function(t,i){return i.qs?typeof i.qs=="object"?t+"&"+n.param(i.qs):typeof i.qs=="string"?t+"&"+i.qs:t+"&"+escape(i.qs.toString()):t},getUrl:function(n,i,r){var u=n.url,f="transport="+i+"&connectionId="+t.escape(n.id);return n.data&&(f+="&connectionData="+t.escape(n.data)),r?(n.messageId&&(f+="&messageId="+n.messageId),n.groups&&(f+="&groups="+t.escape(JSON.stringify(n.groups)))):u=u+"/connect",u+="?"+f,u=this.addQs(u,n)},ajaxSend:function(r,u){var f=r.url+"/send?transport="+r.transport.name+"&connectionId="+t.escape(r.id);f=this.addQs(f,r),n.ajax(f,{global:!1,type:"POST",dataType:"json",data:{data:u},success:function(t){t&&n(r).trigger(i.onReceived,[t])},error:function(t,u){if(u==="abort")return;n(r).trigger(i.onError,[t])}})},processMessages:function(t,u){var f=n(t);if(u){if(u.Disconnect){r("Disconnect command received from server",t.logging),t.stop(),f.trigger(i.onDisconnect);return}u.Messages&&n.each(u.Messages,function(){try{f.trigger(i.onReceived,[this])}catch(u){r("Error raising received "+u,t.logging),n(t).trigger(i.onError,[u])}}),t.messageId=u.MessageId,t.groups=u.TransportData.Groups}},foreverFrame:{count:0,connections:{}}},f.transports={webSockets:{name:"webSockets",send:function(n,t){n.socket.send(t)},start:function(u,f,e){var o,h=!1,s;t.MozWebSocket&&(t.WebSocket=t.MozWebSocket);if(!t.WebSocket){e();return}u.socket||(u.webSocketServerUrl?o=u.webSocketServerUrl:(s=document.location.protocol==="https:"?"wss://":"ws://",o=s+document.location.host+u.appRelativeUrl),n(u).trigger(i.onSending),o+=u.data?"?connectionData="+u.data+"&transport=webSockets&connectionId="+u.id:"?transport=webSockets&connectionId="+u.id,u.socket=new t.WebSocket(o),u.socket.onopen=function(){h=!0,f&&f()},u.socket.onclose=function(t){h?typeof t.wasClean!="undefined"&&t.wasClean===!1&&n(u).trigger(i.onError):e&&e(),u.socket=null},u.socket.onmessage=function(f){var e=t.JSON.parse(f.data),o;e&&(o=n(u),e.Messages?n.each(e.Messages,function(){try{o.trigger(i.onReceived,[this])}catch(n){r("Error raising received "+n,u.logging)}}):o.trigger(i.onReceived,[e]))})},stop:function(n){n.socket!==null&&(n.socket.close(),n.socket=null)}},serverSentEvents:{name:"serverSentEvents",timeOut:3e3,start:function(f,e,o){var s=this,l=!1,c=n(f),h=!e,v,a;f.eventSource&&f.stop();if(!t.EventSource){o&&o();return}c.trigger(i.onSending),v=u.getUrl(f,this.name,h);try{f.eventSource=new t.EventSource(v)}catch(y){r("EventSource failed trying to connect with error "+y.Message,f.logging),o?o():(c.trigger(i.onError,[y]),h&&(r("EventSource reconnecting",f.logging),s.reconnect(f)));return}a=t.setTimeout(function(){l===!1&&(r("EventSource timed out trying to connect",f.logging),o&&o(),h?(r("EventSource reconnecting",f.logging),s.reconnect(f)):s.stop(f))},s.timeOut),f.eventSource.addEventListener("open",function(){r("EventSource connected",f.logging),a&&t.clearTimeout(a),l===!1&&(l=!0,e&&e(),h&&c.trigger(i.onReconnect))},!1),f.eventSource.addEventListener("message",function(n){if(n.data==="initialized")return;u.processMessages(f,t.JSON.parse(n.data))},!1),f.eventSource.addEventListener("error",function(n){if(!l){o&&o();return}r("EventSource readyState: "+f.eventSource.readyState,f.logging),n.eventPhase===t.EventSource.CLOSED?f.eventSource.readyState===t.EventSource.CONNECTING?(r("EventSource reconnecting due to the server connection ending",f.logging),s.reconnect(f)):(r("EventSource closed",f.logging),s.stop(f)):(r("EventSource error",f.logging),c.trigger(i.onError))},!1)},reconnect:function(n){var i=this;t.setTimeout(function(){i.stop(n),i.start(n)},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n&&n.eventSource&&(n.eventSource.close(),n.eventSource=null,delete n.eventSource)}},foreverFrame:{name:"foreverFrame",timeOut:3e3,start:function(f,e,o){var h=this,l=u.foreverFrame.count+=1,c,a,s=n("");if(t.EventSource){o&&o();return}n(f).trigger(i.onSending),c=u.getUrl(f,this.name),c+="&frameId="+l,s.prop("src",c),u.foreverFrame.connections[l]=f,s.bind("readystatechange",function(){n.inArray(this.readyState,["loaded","complete"])<0||(r("Forever frame iframe readyState changed to "+this.readyState+", reconnecting",f.logging),h.reconnect(f))}),f.frame=s[0],f.frameId=l,e&&(f.onSuccess=e),n("body").append(s),a=t.setTimeout(function(){f.onSuccess&&(h.stop(f),o&&o())},h.timeOut)},reconnect:function(n){var i=this;t.setTimeout(function(){var r=n.frame,t=u.getUrl(n,i.name,!0)+"&frameId="+n.frameId;r.src=t},n.reconnectDelay)},send:function(n,t){u.ajaxSend(n,t)},receive:u.processMessages,stop:function(t){t.frame&&(t.frame.stop?t.frame.stop():t.frame.document&&t.frame.document.execCommand&&t.frame.document.execCommand("Stop"),n(t.frame).remove(),delete u.foreverFrame.connections[t.frameId],t.frame=null,t.frameId=null,delete t.frame,delete t.frameId)},getConnection:function(n){return u.foreverFrame.connections[n]},started:function(t){t.onSuccess?(t.onSuccess(),t.onSuccess=null,delete t.onSuccess):n(t).trigger(i.onReconnect)}},longPolling:{name:"longPolling",reconnectDelay:3e3,start:function(r,f){var o=this;r.pollXhr&&r.stop(),r.messageId=null,t.setTimeout(function(){(function e(f,s){n(f).trigger(i.onSending);var a=f.messageId,l=a===null,v=u.getUrl(f,o.name,!l),c=null,h=!1;f.pollXhr=n.ajax(v,{global:!1,type:"GET",dataType:"json",success:function(r){var c=0,o=!1;s===!0&&h===!1&&(n(f).trigger(i.onReconnect),h=!0),u.processMessages(f,r),r&&n.type(r.TransportData.LongPollDelay)==="number"&&(c=r.TransportData.LongPollDelay),r&&r.TimedOut&&(o=r.TimedOut),c>0?t.setTimeout(function(){e(f,o)},c):e(f,o)},error:function(u,o){if(o==="abort")return;c&&clearTimeout(c),n(f).trigger(i.onError,[u]),t.setTimeout(function(){e(f,!0)},r.reconnectDelay)}}),s===!0&&(c=t.setTimeout(function(){h===!1&&(n(f).trigger(i.onReconnect),h=!0)},o.reconnectDelay))})(r),t.setTimeout(f,150)},250)},send:function(n,t){u.ajaxSend(n,t)},stop:function(n){n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)}}},f.noConflict=function(){return n.connection===f&&(n.connection=e),f},n.connection&&(e=n.connection),n.connection=n.signalR=f})(window.jQuery,window) \ No newline at end of file diff --git a/packages/SignalR.Server.0.4.0.0/SignalR.Server.0.4.0.0.nupkg b/packages/SignalR.Server.0.4.0.0/SignalR.Server.0.4.0.0.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..5011cccc0d191f696cb5df385c29059221edb091 GIT binary patch literal 59220 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

I9 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 literal 0 HcmV?d00001 diff --git a/packages/SignalR.Server.0.4.0.0/lib/net40/SignalR.dll b/packages/SignalR.Server.0.4.0.0/lib/net40/SignalR.dll new file mode 100644 index 0000000000000000000000000000000000000000..b845a49c6cedfb4f6ba90e0331d80106f868a288 GIT binary patch literal 106496 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 z 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