summaryrefslogtreecommitdiffstats
path: root/src/OAuth
diff options
context:
space:
mode:
Diffstat (limited to 'src/OAuth')
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Code/Client.cs64
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Code/DataClasses.dbml49
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Code/DataClasses.dbml.layout50
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Code/DataClasses.designer.cs977
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Code/DatabaseKeyNonceStore.cs96
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Code/HttpHeaderAttribute.cs41
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs191
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Code/Utilities.cs21
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Content/Site.css344
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Controllers/AccountController.cs78
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Controllers/HomeController.cs59
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Controllers/OAuthController.cs92
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Global.asax1
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Global.asax.cs123
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Models/AccountAuthorizeModel.cs16
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Models/AccountModels.cs13
-rw-r--r--src/OAuth/OAuthAuthorizationServer/OAuthAuthorizationServer.csproj192
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Properties/AssemblyInfo.cs35
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftAjax.debug.js7117
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftAjax.js6
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcAjax.debug.js408
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcAjax.js25
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcValidation.debug.js881
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcValidation.js55
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1-vsdoc.js8061
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1.js6111
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1.min.js167
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate-vsdoc.js1292
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate.js1155
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate.min.js31
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/Account/LogOn.aspx31
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/Home/About.aspx12
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/Home/CreateDatabase.aspx19
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/Home/Index.aspx18
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/OAuth/Authorize.aspx65
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/Shared/Error.aspx11
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/Shared/LogOnUserControl.ascx14
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/Shared/Site.Master40
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Views/Web.config35
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Web.Debug.config30
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Web.Release.config31
-rw-r--r--src/OAuth/OAuthAuthorizationServer/Web.config110
-rw-r--r--src/OAuth/OAuthAuthorizationServer/packages.config12
-rw-r--r--src/OAuth/OAuthClient/Code/Logging.cs22
-rw-r--r--src/OAuth/OAuthClient/Code/TracePageAppender.cs13
-rw-r--r--src/OAuth/OAuthClient/Default.aspx17
-rw-r--r--src/OAuth/OAuthClient/Facebook.aspx16
-rw-r--r--src/OAuth/OAuthClient/Facebook.aspx.cs32
-rw-r--r--src/OAuth/OAuthClient/Facebook.aspx.designer.cs33
-rw-r--r--src/OAuth/OAuthClient/Global.asax1
-rw-r--r--src/OAuth/OAuthClient/Global.asax.cs35
-rw-r--r--src/OAuth/OAuthClient/GoogleAddressBook.aspx26
-rw-r--r--src/OAuth/OAuthClient/GoogleAddressBook.aspx.cs75
-rw-r--r--src/OAuth/OAuthClient/GoogleAddressBook.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthClient/GoogleApps2Legged.aspx25
-rw-r--r--src/OAuth/OAuthClient/GoogleApps2Legged.aspx.cs39
-rw-r--r--src/OAuth/OAuthClient/GoogleApps2Legged.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthClient/MasterPage.master23
-rw-r--r--src/OAuth/OAuthClient/OAuthClient.csproj250
-rw-r--r--src/OAuth/OAuthClient/Properties/AssemblyInfo.cs35
-rw-r--r--src/OAuth/OAuthClient/SampleWcf2.aspx33
-rw-r--r--src/OAuth/OAuthClient/SampleWcf2.aspx.cs137
-rw-r--r--src/OAuth/OAuthClient/SampleWcf2.aspx.designer.cs96
-rw-r--r--src/OAuth/OAuthClient/SampleWcf2Javascript.html53
-rw-r--r--src/OAuth/OAuthClient/SampleWcf2Javascript.js101
-rw-r--r--src/OAuth/OAuthClient/Scripts/jquery-1.6.1.js8936
-rw-r--r--src/OAuth/OAuthClient/Scripts/jquery-1.6.1.min.js18
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.disco4
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.wsdl310
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.xsd40
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi1.xsd42
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi2.xsd9
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/Reference.cs67
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/Reference.svcmap34
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/configuration.svcinfo10
-rw-r--r--src/OAuth/OAuthClient/Service References/SampleResourceServer/configuration91.svcinfo216
-rw-r--r--src/OAuth/OAuthClient/Settings.StyleCop1
-rw-r--r--src/OAuth/OAuthClient/SignInWithTwitter.aspx38
-rw-r--r--src/OAuth/OAuthClient/SignInWithTwitter.aspx.cs39
-rw-r--r--src/OAuth/OAuthClient/SignInWithTwitter.aspx.designer.cs87
-rw-r--r--src/OAuth/OAuthClient/TracePage.aspx18
-rw-r--r--src/OAuth/OAuthClient/TracePage.aspx.cs23
-rw-r--r--src/OAuth/OAuthClient/TracePage.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthClient/Twitter.aspx35
-rw-r--r--src/OAuth/OAuthClient/Twitter.aspx.cs96
-rw-r--r--src/OAuth/OAuthClient/Twitter.aspx.designer.cs78
-rw-r--r--src/OAuth/OAuthClient/Web.config141
-rw-r--r--src/OAuth/OAuthClient/WindowsLive.aspx29
-rw-r--r--src/OAuth/OAuthClient/WindowsLive.aspx.cs45
-rw-r--r--src/OAuth/OAuthClient/WindowsLive.aspx.designer.cs51
-rw-r--r--src/OAuth/OAuthClient/Yammer.aspx48
-rw-r--r--src/OAuth/OAuthClient/Yammer.aspx.cs76
-rw-r--r--src/OAuth/OAuthClient/Yammer.aspx.designer.cs123
-rw-r--r--src/OAuth/OAuthClient/favicon.icobin0 -> 1150 bytes
-rw-r--r--src/OAuth/OAuthClient/images/Sign-in-with-Twitter-darker.pngbin0 -> 2370 bytes
-rw-r--r--src/OAuth/OAuthClient/packages.config16
-rw-r--r--src/OAuth/OAuthConsumer/Code/Logging.cs22
-rw-r--r--src/OAuth/OAuthConsumer/Code/TracePageAppender.cs13
-rw-r--r--src/OAuth/OAuthConsumer/Default.aspx14
-rw-r--r--src/OAuth/OAuthConsumer/Global.asax1
-rw-r--r--src/OAuth/OAuthConsumer/Global.asax.cs35
-rw-r--r--src/OAuth/OAuthConsumer/GoogleAddressBook.aspx26
-rw-r--r--src/OAuth/OAuthConsumer/GoogleAddressBook.aspx.cs75
-rw-r--r--src/OAuth/OAuthConsumer/GoogleAddressBook.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx25
-rw-r--r--src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx.cs39
-rw-r--r--src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthConsumer/MasterPage.master23
-rw-r--r--src/OAuth/OAuthConsumer/OAuthConsumer.csproj220
-rw-r--r--src/OAuth/OAuthConsumer/Properties/AssemblyInfo.cs35
-rw-r--r--src/OAuth/OAuthConsumer/SampleWcf.aspx23
-rw-r--r--src/OAuth/OAuthConsumer/SampleWcf.aspx.cs119
-rw-r--r--src/OAuth/OAuthConsumer/SampleWcf.aspx.designer.cs96
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.disco4
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.wsdl310
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.xsd40
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi1.xsd42
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi2.xsd9
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/Reference.cs67
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/Reference.svcmap34
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/configuration.svcinfo10
-rw-r--r--src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/configuration91.svcinfo216
-rw-r--r--src/OAuth/OAuthConsumer/Settings.StyleCop1
-rw-r--r--src/OAuth/OAuthConsumer/SignInWithTwitter.aspx38
-rw-r--r--src/OAuth/OAuthConsumer/SignInWithTwitter.aspx.cs39
-rw-r--r--src/OAuth/OAuthConsumer/SignInWithTwitter.aspx.designer.cs87
-rw-r--r--src/OAuth/OAuthConsumer/TracePage.aspx18
-rw-r--r--src/OAuth/OAuthConsumer/TracePage.aspx.cs23
-rw-r--r--src/OAuth/OAuthConsumer/TracePage.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthConsumer/Twitter.aspx35
-rw-r--r--src/OAuth/OAuthConsumer/Twitter.aspx.cs96
-rw-r--r--src/OAuth/OAuthConsumer/Twitter.aspx.designer.cs78
-rw-r--r--src/OAuth/OAuthConsumer/Web.config140
-rw-r--r--src/OAuth/OAuthConsumer/Yammer.aspx48
-rw-r--r--src/OAuth/OAuthConsumer/Yammer.aspx.cs76
-rw-r--r--src/OAuth/OAuthConsumer/Yammer.aspx.designer.cs123
-rw-r--r--src/OAuth/OAuthConsumer/favicon.icobin0 -> 1150 bytes
-rw-r--r--src/OAuth/OAuthConsumer/images/Sign-in-with-Twitter-darker.pngbin0 -> 2370 bytes
-rw-r--r--src/OAuth/OAuthConsumer/packages.config12
-rw-r--r--src/OAuth/OAuthConsumerWpf/App.config98
-rw-r--r--src/OAuth/OAuthConsumerWpf/App.xaml8
-rw-r--r--src/OAuth/OAuthConsumerWpf/App.xaml.cs14
-rw-r--r--src/OAuth/OAuthConsumerWpf/Authorize.xaml12
-rw-r--r--src/OAuth/OAuthConsumerWpf/Authorize.xaml.cs58
-rw-r--r--src/OAuth/OAuthConsumerWpf/Authorize2.xaml11
-rw-r--r--src/OAuth/OAuthConsumerWpf/Authorize2.xaml.cs26
-rw-r--r--src/OAuth/OAuthConsumerWpf/InMemoryTokenManager.cs58
-rw-r--r--src/OAuth/OAuthConsumerWpf/MainWindow.xaml195
-rw-r--r--src/OAuth/OAuthConsumerWpf/MainWindow.xaml.cs233
-rw-r--r--src/OAuth/OAuthConsumerWpf/OAuthConsumerWpf.csproj262
-rw-r--r--src/OAuth/OAuthConsumerWpf/Properties/AssemblyInfo.cs48
-rw-r--r--src/OAuth/OAuthConsumerWpf/Properties/Resources.Designer.cs63
-rw-r--r--src/OAuth/OAuthConsumerWpf/Properties/Resources.resx117
-rw-r--r--src/OAuth/OAuthConsumerWpf/Properties/Settings.Designer.cs26
-rw-r--r--src/OAuth/OAuthConsumerWpf/Properties/Settings.settings7
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.disco4
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.wsdl310
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.xsd9
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi1.xsd40
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi2.xsd42
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/Reference.cs67
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/Reference.svcmap33
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/configuration.svcinfo10
-rw-r--r--src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/configuration91.svcinfo210
-rw-r--r--src/OAuth/OAuthConsumerWpf/favicon.icobin0 -> 1150 bytes
-rw-r--r--src/OAuth/OAuthConsumerWpf/packages.config14
-rw-r--r--src/OAuth/OAuthResourceServer/Code/Global.cs106
-rw-r--r--src/OAuth/OAuthResourceServer/Code/IDataApi.cs21
-rw-r--r--src/OAuth/OAuthResourceServer/Code/OAuthAuthorizationManager.cs80
-rw-r--r--src/OAuth/OAuthResourceServer/Code/OAuthPrincipalAuthorizationPolicy.cs47
-rw-r--r--src/OAuth/OAuthResourceServer/Code/TracePageAppender.cs13
-rw-r--r--src/OAuth/OAuthResourceServer/DataApi.cs42
-rw-r--r--src/OAuth/OAuthResourceServer/DataApi.svc1
-rw-r--r--src/OAuth/OAuthResourceServer/Default.aspx4
-rw-r--r--src/OAuth/OAuthResourceServer/Default.aspx.cs10
-rw-r--r--src/OAuth/OAuthResourceServer/Default.aspx.designer.cs15
-rw-r--r--src/OAuth/OAuthResourceServer/Global.asax1
-rw-r--r--src/OAuth/OAuthResourceServer/Login.aspx11
-rw-r--r--src/OAuth/OAuthResourceServer/MasterPage.master23
-rw-r--r--src/OAuth/OAuthResourceServer/Members/Logoff.aspx8
-rw-r--r--src/OAuth/OAuthResourceServer/Members/Web.config8
-rw-r--r--src/OAuth/OAuthResourceServer/OAuthResourceServer.csproj156
-rw-r--r--src/OAuth/OAuthResourceServer/Properties/AssemblyInfo.cs35
-rw-r--r--src/OAuth/OAuthResourceServer/Settings.StyleCop1
-rw-r--r--src/OAuth/OAuthResourceServer/TracePage.aspx18
-rw-r--r--src/OAuth/OAuthResourceServer/TracePage.aspx.cs24
-rw-r--r--src/OAuth/OAuthResourceServer/TracePage.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthResourceServer/Web.config117
-rw-r--r--src/OAuth/OAuthResourceServer/favicon.icobin0 -> 1150 bytes
-rw-r--r--src/OAuth/OAuthResourceServer/packages.config11
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/Constants.cs32
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/CustomOAuthTypeProvider.cs34
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml57
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml.layout57
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DataClasses.designer.cs1190
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DatabaseNonceStore.cs55
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/DatabaseTokenManager.cs163
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/Global.cs135
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/IDataApi.cs20
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs65
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/OAuthConsumer.cs43
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/OAuthPrincipalAuthorizationPolicy.cs47
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/OAuthToken.cs95
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/RequestScopedTokenMessage.cs25
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/TokenAuthorizationState.cs26
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/TracePageAppender.cs13
-rw-r--r--src/OAuth/OAuthServiceProvider/Code/Utilities.cs28
-rw-r--r--src/OAuth/OAuthServiceProvider/DataApi.cs34
-rw-r--r--src/OAuth/OAuthServiceProvider/DataApi.svc1
-rw-r--r--src/OAuth/OAuthServiceProvider/Default.aspx13
-rw-r--r--src/OAuth/OAuthServiceProvider/Default.aspx.cs49
-rw-r--r--src/OAuth/OAuthServiceProvider/Default.aspx.designer.cs33
-rw-r--r--src/OAuth/OAuthServiceProvider/Global.asax1
-rw-r--r--src/OAuth/OAuthServiceProvider/Login.aspx7
-rw-r--r--src/OAuth/OAuthServiceProvider/MasterPage.master23
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Authorize.aspx58
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.cs80
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.designer.cs105
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx6
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.cs17
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.designer.cs15
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Logoff.aspx8
-rw-r--r--src/OAuth/OAuthServiceProvider/Members/Web.config8
-rw-r--r--src/OAuth/OAuthServiceProvider/OAuth.ashx42
-rw-r--r--src/OAuth/OAuthServiceProvider/OAuthServiceProvider.csproj206
-rw-r--r--src/OAuth/OAuthServiceProvider/Properties/AssemblyInfo.cs35
-rw-r--r--src/OAuth/OAuthServiceProvider/Settings.StyleCop1
-rw-r--r--src/OAuth/OAuthServiceProvider/TracePage.aspx18
-rw-r--r--src/OAuth/OAuthServiceProvider/TracePage.aspx.cs24
-rw-r--r--src/OAuth/OAuthServiceProvider/TracePage.aspx.designer.cs42
-rw-r--r--src/OAuth/OAuthServiceProvider/Web.config180
-rw-r--r--src/OAuth/OAuthServiceProvider/favicon.icobin0 -> 1150 bytes
232 files changed, 48295 insertions, 0 deletions
diff --git a/src/OAuth/OAuthAuthorizationServer/Code/Client.cs b/src/OAuth/OAuthAuthorizationServer/Code/Client.cs
new file mode 100644
index 0000000..0013f27
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Code/Client.cs
@@ -0,0 +1,64 @@
+namespace OAuthAuthorizationServer.Code {
+ using System;
+ using System.Collections.Generic;
+
+ using DotNetOpenAuth.OAuth2;
+
+ /// <summary>
+ /// An OAuth 2.0 Client that has registered with this Authorization Server.
+ /// </summary>
+ public partial class Client : IClientDescription {
+ #region IConsumerDescription Members
+
+ /// <summary>
+ /// Gets the client secret.
+ /// </summary>
+ string IClientDescription.Secret {
+ get { return this.ClientSecret; }
+ }
+
+ /// <summary>
+ /// Gets the callback to use when an individual authorization request
+ /// does not include an explicit callback URI.
+ /// </summary>
+ /// <value>
+ /// An absolute URL; or <c>null</c> if none is registered.
+ /// </value>
+ Uri IClientDescription.DefaultCallback {
+ get { return string.IsNullOrEmpty(this.Callback) ? null : new Uri(this.Callback); }
+ }
+
+ /// <summary>
+ /// Gets the type of the client.
+ /// </summary>
+ ClientType IClientDescription.ClientType {
+ get { return (ClientType)this.ClientType; }
+ }
+
+ /// <summary>
+ /// Determines whether a callback URI included in a client's authorization request
+ /// is among those allowed callbacks for the registered client.
+ /// </summary>
+ /// <param name="callback">The absolute URI the client has requested the authorization result be received at.</param>
+ /// <returns>
+ /// <c>true</c> if the callback URL is allowable for this client; otherwise, <c>false</c>.
+ /// </returns>
+ bool IClientDescription.IsCallbackAllowed(Uri callback) {
+ if (string.IsNullOrEmpty(this.Callback)) {
+ // No callback rules have been set up for this client.
+ return true;
+ }
+
+ // In this sample, it's enough of a callback URL match if the scheme and host match.
+ // In a production app, it is advisable to require a match on the path as well.
+ Uri acceptableCallbackPattern = new Uri(this.Callback);
+ if (string.Equals(acceptableCallbackPattern.GetLeftPart(UriPartial.Authority), callback.GetLeftPart(UriPartial.Authority), StringComparison.Ordinal)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.dbml b/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.dbml
new file mode 100644
index 0000000..fe621c2
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.dbml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?><Database Name="Database" EntityNamespace="OAuthAuthorizationServer.Code" Class="DataClassesDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
+ <Connection Mode="WebSettings" ConnectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" SettingsObjectName="System.Configuration.ConfigurationManager.ConnectionStrings" SettingsPropertyName="DatabaseConnectionString" Provider="System.Data.SqlClient" />
+ <Table Name="dbo.[User]" Member="Users">
+ <Type Name="User">
+ <Column Name="UserId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="OpenIDClaimedIdentifier" Type="System.String" DbType="NVarChar(150) NOT NULL" CanBeNull="false" />
+ <Column Name="OpenIDFriendlyIdentifier" Type="System.String" DbType="NVarChar(150)" CanBeNull="true" />
+ <Association Name="User_ClientAuthorization" Member="ClientAuthorizations" Storage="_OAuthTokens" ThisKey="UserId" OtherKey="UserId" Type="ClientAuthorization" />
+ </Type>
+ </Table>
+ <Table Name="dbo.Client" Member="Clients">
+ <Type Name="Client">
+ <Column Name="ClientId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="ClientIdentifier" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="ClientSecret" Type="System.String" DbType="NVarChar(50)" CanBeNull="true" />
+ <Column Name="Callback" Type="System.String" CanBeNull="true" />
+ <Column Name="Name" Type="System.String" CanBeNull="false" />
+ <Column Member="ClientType" Type="System.Int32" CanBeNull="false" />
+ <Association Name="Client_ClientAuthorization" Member="ClientAuthorizations" Storage="_OAuthTokens" ThisKey="ClientId" OtherKey="ClientId" Type="ClientAuthorization" />
+ </Type>
+ </Table>
+ <Table Name="dbo.ClientAuthorization" Member="ClientAuthorizations">
+ <Type Name="ClientAuthorization">
+ <Column Name="AuthorizationId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="CreatedOnUtc" Storage="_IssueDate" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" />
+ <Column Name="ClientId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+ <Column Name="UserId" Type="System.Int32" DbType="Int" CanBeNull="false" />
+ <Column Name="Scope" Type="System.String" DbType="nvarchar(MAX)" CanBeNull="false" />
+ <Column Name="ExpirationDateUtc" Type="System.DateTime" DbType="DateTime NULL" CanBeNull="true" />
+ <Association Name="Client_ClientAuthorization" Member="Client" ThisKey="ClientId" OtherKey="ClientId" Type="Client" IsForeignKey="true" DeleteRule="CASCADE" DeleteOnNull="true" />
+ <Association Name="User_ClientAuthorization" Member="User" ThisKey="UserId" OtherKey="UserId" Type="User" IsForeignKey="true" DeleteRule="CASCADE" />
+ </Type>
+ </Table>
+ <Table Name="dbo.Nonce" Member="Nonces">
+ <Type Name="Nonce">
+ <Column Name="Context" Type="System.String" IsPrimaryKey="true" CanBeNull="false" />
+ <Column Name="Code" Type="System.String" IsPrimaryKey="true" CanBeNull="false" />
+ <Column Name="Timestamp" Type="System.DateTime" IsPrimaryKey="true" CanBeNull="false" />
+ </Type>
+ </Table>
+ <Table Name="" Member="SymmetricCryptoKeys">
+ <Type Name="SymmetricCryptoKey">
+ <Column Name="Bucket" Type="System.String" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
+ <Column Name="Handle" Type="System.String" IsPrimaryKey="true" CanBeNull="false" UpdateCheck="Never" />
+ <Column Name="ExpiresUtc" Type="System.DateTime" CanBeNull="false" UpdateCheck="Never" />
+ <Column Name="Secret" Type="System.Byte[]" CanBeNull="false" UpdateCheck="Never" />
+ </Type>
+ </Table>
+</Database> \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.dbml.layout b/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.dbml.layout
new file mode 100644
index 0000000..f4de725
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.dbml.layout
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ordesignerObjectsDiagram dslVersion="1.0.0.0" absoluteBounds="0, 0, 11, 8.5" name="DataClasses">
+ <DataContextMoniker Name="/DataClassesDataContext" />
+ <nestedChildShapes>
+ <classShape Id="696d2c69-040e-411d-9257-bb664b743834" absoluteBounds="0.5, 0.5, 2.125, 1.3862939453125">
+ <DataClassMoniker Name="/DataClassesDataContext/User" />
+ <nestedChildShapes>
+ <elementListCompartment Id="cd90aeff-476c-44a9-897f-a986e4a8305b" absoluteBounds="0.515, 0.96, 2.0949999999999998, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" absoluteBounds="0.5, 3.5, 2, 1.7708968098958327">
+ <DataClassMoniker Name="/DataClassesDataContext/Client" />
+ <nestedChildShapes>
+ <elementListCompartment Id="464308c4-d112-4448-b0c9-d9b82fb0ca4e" absoluteBounds="0.515, 3.96, 1.9700000000000002, 1.2108968098958333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" absoluteBounds="3.5, 3.125, 2, 1.9631982421874996">
+ <DataClassMoniker Name="/DataClassesDataContext/ClientAuthorization" />
+ <nestedChildShapes>
+ <elementListCompartment Id="403126d0-3d2a-4af4-b0b8-c489a830bbd4" absoluteBounds="3.515, 3.585, 1.9700000000000002, 1.4031982421875" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="a63562a7-acf2-4ed9-9686-52a1ad85633e" absoluteBounds="1.375, 6.375, 2, 1.3862939453124996">
+ <DataClassMoniker Name="/DataClassesDataContext/Nonce" />
+ <nestedChildShapes>
+ <elementListCompartment Id="9e4514ef-bc7b-4179-88e6-05363bf6ee5e" absoluteBounds="1.39, 6.835, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <associationConnector edgePoints="[(2.5 : 4.29409912109375); (3.5 : 4.29409912109375)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+ <AssociationMoniker Name="/DataClassesDataContext/Client/Client_ClientAuthorization" />
+ <nodes>
+ <classShapeMoniker Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" />
+ <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" />
+ </nodes>
+ </associationConnector>
+ <associationConnector edgePoints="[(2.59375 : 1.8862939453125); (2.59375 : 3.28125); (3.5 : 3.28125)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+ <AssociationMoniker Name="/DataClassesDataContext/User/User_ClientAuthorization" />
+ <nodes>
+ <classShapeMoniker Id="696d2c69-040e-411d-9257-bb664b743834" />
+ <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" />
+ </nodes>
+ </associationConnector>
+ <classShape Id="93df6fa9-cc66-44a9-8885-960b1e670dd7" absoluteBounds="4.125, 6.25, 2, 1.5785953776041666">
+ <DataClassMoniker Name="/DataClassesDataContext/SymmetricCryptoKey" />
+ <nestedChildShapes>
+ <elementListCompartment Id="0b486eb8-31a4-4f11-b58f-09540c56319b" absoluteBounds="4.14, 6.71, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ </nestedChildShapes>
+</ordesignerObjectsDiagram> \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.designer.cs b/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.designer.cs
new file mode 100644
index 0000000..c7af82a
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Code/DataClasses.designer.cs
@@ -0,0 +1,977 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.235
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthAuthorizationServer.Code
+{
+ using System.Data.Linq;
+ using System.Data.Linq.Mapping;
+ using System.Data;
+ using System.Collections.Generic;
+ using System.Reflection;
+ using System.Linq;
+ using System.Linq.Expressions;
+ using System.ComponentModel;
+ using System;
+
+
+ [global::System.Data.Linq.Mapping.DatabaseAttribute(Name="Database")]
+ public partial class DataClassesDataContext : System.Data.Linq.DataContext
+ {
+
+ private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
+
+ #region Extensibility Method Definitions
+ partial void OnCreated();
+ partial void InsertUser(User instance);
+ partial void UpdateUser(User instance);
+ partial void DeleteUser(User instance);
+ partial void InsertClient(Client instance);
+ partial void UpdateClient(Client instance);
+ partial void DeleteClient(Client instance);
+ partial void InsertClientAuthorization(ClientAuthorization instance);
+ partial void UpdateClientAuthorization(ClientAuthorization instance);
+ partial void DeleteClientAuthorization(ClientAuthorization instance);
+ partial void InsertNonce(Nonce instance);
+ partial void UpdateNonce(Nonce instance);
+ partial void DeleteNonce(Nonce instance);
+ partial void InsertSymmetricCryptoKey(SymmetricCryptoKey instance);
+ partial void UpdateSymmetricCryptoKey(SymmetricCryptoKey instance);
+ partial void DeleteSymmetricCryptoKey(SymmetricCryptoKey instance);
+ #endregion
+
+ public DataClassesDataContext() :
+ base(global::System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(string connection) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(System.Data.IDbConnection connection) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public System.Data.Linq.Table<User> Users
+ {
+ get
+ {
+ return this.GetTable<User>();
+ }
+ }
+
+ public System.Data.Linq.Table<Client> Clients
+ {
+ get
+ {
+ return this.GetTable<Client>();
+ }
+ }
+
+ public System.Data.Linq.Table<ClientAuthorization> ClientAuthorizations
+ {
+ get
+ {
+ return this.GetTable<ClientAuthorization>();
+ }
+ }
+
+ public System.Data.Linq.Table<Nonce> Nonces
+ {
+ get
+ {
+ return this.GetTable<Nonce>();
+ }
+ }
+
+ public System.Data.Linq.Table<SymmetricCryptoKey> SymmetricCryptoKeys
+ {
+ get
+ {
+ return this.GetTable<SymmetricCryptoKey>();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[User]")]
+ public partial class User : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _UserId;
+
+ private string _OpenIDClaimedIdentifier;
+
+ private string _OpenIDFriendlyIdentifier;
+
+ private EntitySet<ClientAuthorization> _OAuthTokens;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnUserIdChanging(int value);
+ partial void OnUserIdChanged();
+ partial void OnOpenIDClaimedIdentifierChanging(string value);
+ partial void OnOpenIDClaimedIdentifierChanged();
+ partial void OnOpenIDFriendlyIdentifierChanging(string value);
+ partial void OnOpenIDFriendlyIdentifierChanged();
+ #endregion
+
+ public User()
+ {
+ this._OAuthTokens = new EntitySet<ClientAuthorization>(new Action<ClientAuthorization>(this.attach_OAuthTokens), new Action<ClientAuthorization>(this.detach_OAuthTokens));
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int UserId
+ {
+ get
+ {
+ return this._UserId;
+ }
+ set
+ {
+ if ((this._UserId != value))
+ {
+ this.OnUserIdChanging(value);
+ this.SendPropertyChanging();
+ this._UserId = value;
+ this.SendPropertyChanged("UserId");
+ this.OnUserIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OpenIDClaimedIdentifier", DbType="NVarChar(150) NOT NULL", CanBeNull=false)]
+ public string OpenIDClaimedIdentifier
+ {
+ get
+ {
+ return this._OpenIDClaimedIdentifier;
+ }
+ set
+ {
+ if ((this._OpenIDClaimedIdentifier != value))
+ {
+ this.OnOpenIDClaimedIdentifierChanging(value);
+ this.SendPropertyChanging();
+ this._OpenIDClaimedIdentifier = value;
+ this.SendPropertyChanged("OpenIDClaimedIdentifier");
+ this.OnOpenIDClaimedIdentifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OpenIDFriendlyIdentifier", DbType="NVarChar(150)")]
+ public string OpenIDFriendlyIdentifier
+ {
+ get
+ {
+ return this._OpenIDFriendlyIdentifier;
+ }
+ set
+ {
+ if ((this._OpenIDFriendlyIdentifier != value))
+ {
+ this.OnOpenIDFriendlyIdentifierChanging(value);
+ this.SendPropertyChanging();
+ this._OpenIDFriendlyIdentifier = value;
+ this.SendPropertyChanged("OpenIDFriendlyIdentifier");
+ this.OnOpenIDFriendlyIdentifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_ClientAuthorization", Storage="_OAuthTokens", ThisKey="UserId", OtherKey="UserId")]
+ public EntitySet<ClientAuthorization> ClientAuthorizations
+ {
+ get
+ {
+ return this._OAuthTokens;
+ }
+ set
+ {
+ this._OAuthTokens.Assign(value);
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_OAuthTokens(ClientAuthorization entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = this;
+ }
+
+ private void detach_OAuthTokens(ClientAuthorization entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = null;
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Client")]
+ public partial class Client : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _ClientId;
+
+ private string _ClientIdentifier;
+
+ private string _ClientSecret;
+
+ private string _Callback;
+
+ private string _Name;
+
+ private int _ClientType;
+
+ private EntitySet<ClientAuthorization> _OAuthTokens;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnClientIdChanging(int value);
+ partial void OnClientIdChanged();
+ partial void OnClientIdentifierChanging(string value);
+ partial void OnClientIdentifierChanged();
+ partial void OnClientSecretChanging(string value);
+ partial void OnClientSecretChanged();
+ partial void OnCallbackChanging(string value);
+ partial void OnCallbackChanged();
+ partial void OnNameChanging(string value);
+ partial void OnNameChanged();
+ partial void OnClientTypeChanging(int value);
+ partial void OnClientTypeChanged();
+ #endregion
+
+ public Client()
+ {
+ this._OAuthTokens = new EntitySet<ClientAuthorization>(new Action<ClientAuthorization>(this.attach_OAuthTokens), new Action<ClientAuthorization>(this.detach_OAuthTokens));
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int ClientId
+ {
+ get
+ {
+ return this._ClientId;
+ }
+ set
+ {
+ if ((this._ClientId != value))
+ {
+ this.OnClientIdChanging(value);
+ this.SendPropertyChanging();
+ this._ClientId = value;
+ this.SendPropertyChanged("ClientId");
+ this.OnClientIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientIdentifier", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string ClientIdentifier
+ {
+ get
+ {
+ return this._ClientIdentifier;
+ }
+ set
+ {
+ if ((this._ClientIdentifier != value))
+ {
+ this.OnClientIdentifierChanging(value);
+ this.SendPropertyChanging();
+ this._ClientIdentifier = value;
+ this.SendPropertyChanged("ClientIdentifier");
+ this.OnClientIdentifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientSecret", DbType="NVarChar(50)")]
+ public string ClientSecret
+ {
+ get
+ {
+ return this._ClientSecret;
+ }
+ set
+ {
+ if ((this._ClientSecret != value))
+ {
+ this.OnClientSecretChanging(value);
+ this.SendPropertyChanging();
+ this._ClientSecret = value;
+ this.SendPropertyChanged("ClientSecret");
+ this.OnClientSecretChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Callback")]
+ public string Callback
+ {
+ get
+ {
+ return this._Callback;
+ }
+ set
+ {
+ if ((this._Callback != value))
+ {
+ this.OnCallbackChanging(value);
+ this.SendPropertyChanging();
+ this._Callback = value;
+ this.SendPropertyChanged("Callback");
+ this.OnCallbackChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Name", CanBeNull=false)]
+ public string Name
+ {
+ get
+ {
+ return this._Name;
+ }
+ set
+ {
+ if ((this._Name != value))
+ {
+ this.OnNameChanging(value);
+ this.SendPropertyChanging();
+ this._Name = value;
+ this.SendPropertyChanged("Name");
+ this.OnNameChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientType")]
+ public int ClientType
+ {
+ get
+ {
+ return this._ClientType;
+ }
+ set
+ {
+ if ((this._ClientType != value))
+ {
+ this.OnClientTypeChanging(value);
+ this.SendPropertyChanging();
+ this._ClientType = value;
+ this.SendPropertyChanged("ClientType");
+ this.OnClientTypeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Client_ClientAuthorization", Storage="_OAuthTokens", ThisKey="ClientId", OtherKey="ClientId")]
+ public EntitySet<ClientAuthorization> ClientAuthorizations
+ {
+ get
+ {
+ return this._OAuthTokens;
+ }
+ set
+ {
+ this._OAuthTokens.Assign(value);
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_OAuthTokens(ClientAuthorization entity)
+ {
+ this.SendPropertyChanging();
+ entity.Client = this;
+ }
+
+ private void detach_OAuthTokens(ClientAuthorization entity)
+ {
+ this.SendPropertyChanging();
+ entity.Client = null;
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.ClientAuthorization")]
+ public partial class ClientAuthorization : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _AuthorizationId;
+
+ private System.DateTime _IssueDate;
+
+ private int _ClientId;
+
+ private int _UserId;
+
+ private string _Scope;
+
+ private System.Nullable<System.DateTime> _ExpirationDateUtc;
+
+ private EntityRef<Client> _Client;
+
+ private EntityRef<User> _User;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnAuthorizationIdChanging(int value);
+ partial void OnAuthorizationIdChanged();
+ partial void OnCreatedOnUtcChanging(System.DateTime value);
+ partial void OnCreatedOnUtcChanged();
+ partial void OnClientIdChanging(int value);
+ partial void OnClientIdChanged();
+ partial void OnUserIdChanging(int value);
+ partial void OnUserIdChanged();
+ partial void OnScopeChanging(string value);
+ partial void OnScopeChanged();
+ partial void OnExpirationDateUtcChanging(System.Nullable<System.DateTime> value);
+ partial void OnExpirationDateUtcChanged();
+ #endregion
+
+ public ClientAuthorization()
+ {
+ this._Client = default(EntityRef<Client>);
+ this._User = default(EntityRef<User>);
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_AuthorizationId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int AuthorizationId
+ {
+ get
+ {
+ return this._AuthorizationId;
+ }
+ set
+ {
+ if ((this._AuthorizationId != value))
+ {
+ this.OnAuthorizationIdChanging(value);
+ this.SendPropertyChanging();
+ this._AuthorizationId = value;
+ this.SendPropertyChanged("AuthorizationId");
+ this.OnAuthorizationIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_IssueDate", DbType="DateTime NOT NULL")]
+ public System.DateTime CreatedOnUtc
+ {
+ get
+ {
+ return this._IssueDate;
+ }
+ set
+ {
+ if ((this._IssueDate != value))
+ {
+ this.OnCreatedOnUtcChanging(value);
+ this.SendPropertyChanging();
+ this._IssueDate = value;
+ this.SendPropertyChanged("CreatedOnUtc");
+ this.OnCreatedOnUtcChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ClientId", DbType="Int NOT NULL")]
+ public int ClientId
+ {
+ get
+ {
+ return this._ClientId;
+ }
+ set
+ {
+ if ((this._ClientId != value))
+ {
+ if (this._Client.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnClientIdChanging(value);
+ this.SendPropertyChanging();
+ this._ClientId = value;
+ this.SendPropertyChanged("ClientId");
+ this.OnClientIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="Int")]
+ public int UserId
+ {
+ get
+ {
+ return this._UserId;
+ }
+ set
+ {
+ if ((this._UserId != value))
+ {
+ if (this._User.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnUserIdChanging(value);
+ this.SendPropertyChanging();
+ this._UserId = value;
+ this.SendPropertyChanged("UserId");
+ this.OnUserIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Scope", DbType="nvarchar(MAX)", CanBeNull=false)]
+ public string Scope
+ {
+ get
+ {
+ return this._Scope;
+ }
+ set
+ {
+ if ((this._Scope != value))
+ {
+ this.OnScopeChanging(value);
+ this.SendPropertyChanging();
+ this._Scope = value;
+ this.SendPropertyChanged("Scope");
+ this.OnScopeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExpirationDateUtc", DbType="DateTime NULL")]
+ public System.Nullable<System.DateTime> ExpirationDateUtc
+ {
+ get
+ {
+ return this._ExpirationDateUtc;
+ }
+ set
+ {
+ if ((this._ExpirationDateUtc != value))
+ {
+ this.OnExpirationDateUtcChanging(value);
+ this.SendPropertyChanging();
+ this._ExpirationDateUtc = value;
+ this.SendPropertyChanged("ExpirationDateUtc");
+ this.OnExpirationDateUtcChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="Client_ClientAuthorization", Storage="_Client", ThisKey="ClientId", OtherKey="ClientId", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
+ public Client Client
+ {
+ get
+ {
+ return this._Client.Entity;
+ }
+ set
+ {
+ Client previousValue = this._Client.Entity;
+ if (((previousValue != value)
+ || (this._Client.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._Client.Entity = null;
+ previousValue.ClientAuthorizations.Remove(this);
+ }
+ this._Client.Entity = value;
+ if ((value != null))
+ {
+ value.ClientAuthorizations.Add(this);
+ this._ClientId = value.ClientId;
+ }
+ else
+ {
+ this._ClientId = default(int);
+ }
+ this.SendPropertyChanged("Client");
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_ClientAuthorization", Storage="_User", ThisKey="UserId", OtherKey="UserId", IsForeignKey=true, DeleteRule="CASCADE")]
+ public User User
+ {
+ get
+ {
+ return this._User.Entity;
+ }
+ set
+ {
+ User previousValue = this._User.Entity;
+ if (((previousValue != value)
+ || (this._User.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._User.Entity = null;
+ previousValue.ClientAuthorizations.Remove(this);
+ }
+ this._User.Entity = value;
+ if ((value != null))
+ {
+ value.ClientAuthorizations.Add(this);
+ this._UserId = value.UserId;
+ }
+ else
+ {
+ this._UserId = default(int);
+ }
+ this.SendPropertyChanged("User");
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Nonce")]
+ public partial class Nonce : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private string _Context;
+
+ private string _Code;
+
+ private System.DateTime _Timestamp;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnContextChanging(string value);
+ partial void OnContextChanged();
+ partial void OnCodeChanging(string value);
+ partial void OnCodeChanged();
+ partial void OnTimestampChanging(System.DateTime value);
+ partial void OnTimestampChanged();
+ #endregion
+
+ public Nonce()
+ {
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Context", CanBeNull=false, IsPrimaryKey=true)]
+ public string Context
+ {
+ get
+ {
+ return this._Context;
+ }
+ set
+ {
+ if ((this._Context != value))
+ {
+ this.OnContextChanging(value);
+ this.SendPropertyChanging();
+ this._Context = value;
+ this.SendPropertyChanged("Context");
+ this.OnContextChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Code", CanBeNull=false, IsPrimaryKey=true)]
+ public string Code
+ {
+ get
+ {
+ return this._Code;
+ }
+ set
+ {
+ if ((this._Code != value))
+ {
+ this.OnCodeChanging(value);
+ this.SendPropertyChanging();
+ this._Code = value;
+ this.SendPropertyChanged("Code");
+ this.OnCodeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Timestamp", IsPrimaryKey=true)]
+ public System.DateTime Timestamp
+ {
+ get
+ {
+ return this._Timestamp;
+ }
+ set
+ {
+ if ((this._Timestamp != value))
+ {
+ this.OnTimestampChanging(value);
+ this.SendPropertyChanging();
+ this._Timestamp = value;
+ this.SendPropertyChanged("Timestamp");
+ this.OnTimestampChanged();
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+ public partial class SymmetricCryptoKey : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private string _Bucket;
+
+ private string _Handle;
+
+ private System.DateTime _ExpiresUtc;
+
+ private byte[] _Secret;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnBucketChanging(string value);
+ partial void OnBucketChanged();
+ partial void OnHandleChanging(string value);
+ partial void OnHandleChanged();
+ partial void OnExpiresUtcChanging(System.DateTime value);
+ partial void OnExpiresUtcChanged();
+ partial void OnSecretChanging(byte[] value);
+ partial void OnSecretChanged();
+ #endregion
+
+ public SymmetricCryptoKey()
+ {
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Bucket", CanBeNull=false, IsPrimaryKey=true, UpdateCheck=UpdateCheck.Never)]
+ public string Bucket
+ {
+ get
+ {
+ return this._Bucket;
+ }
+ set
+ {
+ if ((this._Bucket != value))
+ {
+ this.OnBucketChanging(value);
+ this.SendPropertyChanging();
+ this._Bucket = value;
+ this.SendPropertyChanged("Bucket");
+ this.OnBucketChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Handle", CanBeNull=false, IsPrimaryKey=true, UpdateCheck=UpdateCheck.Never)]
+ public string Handle
+ {
+ get
+ {
+ return this._Handle;
+ }
+ set
+ {
+ if ((this._Handle != value))
+ {
+ this.OnHandleChanging(value);
+ this.SendPropertyChanging();
+ this._Handle = value;
+ this.SendPropertyChanged("Handle");
+ this.OnHandleChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExpiresUtc", UpdateCheck=UpdateCheck.Never)]
+ public System.DateTime ExpiresUtc
+ {
+ get
+ {
+ return this._ExpiresUtc;
+ }
+ set
+ {
+ if ((this._ExpiresUtc != value))
+ {
+ this.OnExpiresUtcChanging(value);
+ this.SendPropertyChanging();
+ this._ExpiresUtc = value;
+ this.SendPropertyChanged("ExpiresUtc");
+ this.OnExpiresUtcChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Secret", CanBeNull=false, UpdateCheck=UpdateCheck.Never)]
+ public byte[] Secret
+ {
+ get
+ {
+ return this._Secret;
+ }
+ set
+ {
+ if ((this._Secret != value))
+ {
+ this.OnSecretChanging(value);
+ this.SendPropertyChanging();
+ this._Secret = value;
+ this.SendPropertyChanged("Secret");
+ this.OnSecretChanged();
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+}
+#pragma warning restore 1591
diff --git a/src/OAuth/OAuthAuthorizationServer/Code/DatabaseKeyNonceStore.cs b/src/OAuth/OAuthAuthorizationServer/Code/DatabaseKeyNonceStore.cs
new file mode 100644
index 0000000..0a1d8af
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Code/DatabaseKeyNonceStore.cs
@@ -0,0 +1,96 @@
+namespace OAuthAuthorizationServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Data.SqlClient;
+ using System.Linq;
+ using DotNetOpenAuth.Messaging.Bindings;
+
+ /// <summary>
+ /// A database-persisted nonce store.
+ /// </summary>
+ public class DatabaseKeyNonceStore : INonceStore, ICryptoKeyStore {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DatabaseKeyNonceStore"/> class.
+ /// </summary>
+ public DatabaseKeyNonceStore() {
+ }
+
+ #region INonceStore Members
+
+ /// <summary>
+ /// Stores a given nonce and timestamp.
+ /// </summary>
+ /// <param name="context">The context, or namespace, within which the
+ /// <paramref name="nonce"/> must be unique.
+ /// The context SHOULD be treated as case-sensitive.
+ /// The value will never be <c>null</c> but may be the empty string.</param>
+ /// <param name="nonce">A series of random characters.</param>
+ /// <param name="timestampUtc">The UTC timestamp that together with the nonce string make it unique
+ /// within the given <paramref name="context"/>.
+ /// The timestamp may also be used by the data store to clear out old nonces.</param>
+ /// <returns>
+ /// True if the context+nonce+timestamp (combination) was not previously in the database.
+ /// False if the nonce was stored previously with the same timestamp and context.
+ /// </returns>
+ /// <remarks>
+ /// The nonce must be stored for no less than the maximum time window a message may
+ /// be processed within before being discarded as an expired message.
+ /// This maximum message age can be looked up via the
+ /// <see cref="DotNetOpenAuth.Configuration.MessagingElement.MaximumMessageLifetime"/>
+ /// property, accessible via the <see cref="DotNetOpenAuth.Configuration.DotNetOpenAuthSection.Configuration"/>
+ /// property.
+ /// </remarks>
+ public bool StoreNonce(string context, string nonce, DateTime timestampUtc) {
+ MvcApplication.DataContext.Nonces.InsertOnSubmit(new Nonce { Context = context, Code = nonce, Timestamp = timestampUtc });
+ try {
+ MvcApplication.DataContext.SubmitChanges();
+ return true;
+ } catch (System.Data.Linq.DuplicateKeyException) {
+ return false;
+ } catch (SqlException) {
+ return false;
+ }
+ }
+
+ #endregion
+
+ #region ICryptoKeyStore Members
+
+ public CryptoKey GetKey(string bucket, string handle) {
+ // It is critical that this lookup be case-sensitive, which can only be configured at the database.
+ var matches = from key in MvcApplication.DataContext.SymmetricCryptoKeys
+ where key.Bucket == bucket && key.Handle == handle
+ select new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc());
+
+ return matches.FirstOrDefault();
+ }
+
+ public IEnumerable<KeyValuePair<string, CryptoKey>> GetKeys(string bucket) {
+ return from key in MvcApplication.DataContext.SymmetricCryptoKeys
+ where key.Bucket == bucket
+ orderby key.ExpiresUtc descending
+ select new KeyValuePair<string, CryptoKey>(key.Handle, new CryptoKey(key.Secret, key.ExpiresUtc.AsUtc()));
+ }
+
+ public void StoreKey(string bucket, string handle, CryptoKey key) {
+ var keyRow = new SymmetricCryptoKey() {
+ Bucket = bucket,
+ Handle = handle,
+ Secret = key.Key,
+ ExpiresUtc = key.ExpiresUtc,
+ };
+
+ MvcApplication.DataContext.SymmetricCryptoKeys.InsertOnSubmit(keyRow);
+ MvcApplication.DataContext.SubmitChanges();
+ }
+
+ public void RemoveKey(string bucket, string handle) {
+ var match = MvcApplication.DataContext.SymmetricCryptoKeys.FirstOrDefault(k => k.Bucket == bucket && k.Handle == handle);
+ if (match != null) {
+ MvcApplication.DataContext.SymmetricCryptoKeys.DeleteOnSubmit(match);
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Code/HttpHeaderAttribute.cs b/src/OAuth/OAuthAuthorizationServer/Code/HttpHeaderAttribute.cs
new file mode 100644
index 0000000..d3201c2
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Code/HttpHeaderAttribute.cs
@@ -0,0 +1,41 @@
+namespace OAuthAuthorizationServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Mvc;
+
+ /// <summary>
+ /// Represents an attribute that is used to add HTTP Headers to a Controller Action response.
+ /// </summary>
+ public class HttpHeaderAttribute : ActionFilterAttribute {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="HttpHeaderAttribute"/> class.
+ /// </summary>
+ /// <param name="name">The HTTP header name.</param>
+ /// <param name="value">The HTTP header value.</param>
+ public HttpHeaderAttribute(string name, string value) {
+ this.Name = name;
+ this.Value = value;
+ }
+
+ /// <summary>
+ /// Gets or sets the name of the HTTP Header.
+ /// </summary>
+ public string Name { get; set; }
+
+ /// <summary>
+ /// Gets or sets the value of the HTTP Header.
+ /// </summary>
+ public string Value { get; set; }
+
+ /// <summary>
+ /// Called by the MVC framework after the action result executes.
+ /// </summary>
+ /// <param name="filterContext">The filter context.</param>
+ public override void OnResultExecuted(ResultExecutedContext filterContext) {
+ filterContext.HttpContext.Response.AppendHeader(this.Name, this.Value);
+ base.OnResultExecuted(filterContext);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs b/src/OAuth/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs
new file mode 100644
index 0000000..b837d4c
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Code/OAuth2AuthorizationServer.cs
@@ -0,0 +1,191 @@
+namespace OAuthAuthorizationServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.Web;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.Messaging.Bindings;
+ using DotNetOpenAuth.OAuth2;
+ using DotNetOpenAuth.OAuth2.ChannelElements;
+ using DotNetOpenAuth.OAuth2.Messages;
+
+ internal class OAuth2AuthorizationServer : IAuthorizationServer {
+ private static readonly RSACryptoServiceProvider AsymmetricTokenSigningPrivateKey = CreateRSA();
+
+#if SAMPLESONLY
+ /// <summary>
+ /// This is the FOR SAMPLE ONLY hard-coded public key of the complementary OAuthResourceServer sample.
+ /// </summary>
+ /// <remarks>
+ /// In a real app, the authorization server would need to determine which resource server the access token needs to be encoded for
+ /// based on the authorization request. It would then need to look up the public key for that resource server and use that in
+ /// preparing the access token for the client to use against that resource server.
+ /// </remarks>
+ private static readonly RSAParameters ResourceServerEncryptionPublicKey = new RSAParameters {
+ Exponent = new byte[] { 1, 0, 1 },
+ Modulus = new byte[] { 166, 175, 117, 169, 211, 251, 45, 215, 55, 53, 202, 65, 153, 155, 92, 219, 235, 243, 61, 170, 101, 250, 221, 214, 239, 175, 238, 175, 239, 20, 144, 72, 227, 221, 4, 219, 32, 225, 101, 96, 18, 33, 117, 176, 110, 123, 109, 23, 29, 85, 93, 50, 129, 163, 113, 57, 122, 212, 141, 145, 17, 31, 67, 165, 181, 91, 117, 23, 138, 251, 198, 132, 188, 213, 10, 157, 116, 229, 48, 168, 8, 127, 28, 156, 239, 124, 117, 36, 232, 100, 222, 23, 52, 186, 239, 5, 63, 207, 185, 16, 137, 73, 137, 147, 252, 71, 9, 239, 113, 27, 88, 255, 91, 56, 192, 142, 210, 21, 34, 81, 204, 239, 57, 60, 140, 249, 15, 101 },
+ };
+#else
+ [Obsolete("You must use a real key for a real app.", true)]
+ private static readonly RSAParameters ResourceServerEncryptionPublicKey;
+#endif
+
+ #region Implementation of IAuthorizationServer
+
+ public ICryptoKeyStore CryptoKeyStore {
+ get { return MvcApplication.KeyNonceStore; }
+ }
+
+ public INonceStore VerificationCodeNonceStore {
+ get { return MvcApplication.KeyNonceStore; }
+ }
+
+ public RSACryptoServiceProvider AccessTokenSigningKey {
+ get { return AsymmetricTokenSigningPrivateKey; }
+ }
+
+ public TimeSpan GetAccessTokenLifetime(IAccessTokenRequest accessTokenRequestMessage) {
+ // Just for the sake of the sample, we use a short-lived token. This can be useful to mitigate the security risks
+ // of access tokens that are used over standard HTTP.
+ // But this is just the lifetime of the access token. The client can still renew it using their refresh token until
+ // the authorization itself expires.
+ TimeSpan lifetime = TimeSpan.FromMinutes(2);
+
+ // Also take into account the remaining life of the authorization and artificially shorten the access token's lifetime
+ // to account for that if necessary.
+ //// TODO: code here
+
+ return lifetime;
+ }
+
+ public RSACryptoServiceProvider GetResourceServerEncryptionKey(IAccessTokenRequest accessTokenRequestMessage) {
+ var resourceServerEncryptionKey = new RSACryptoServiceProvider();
+
+ // For this sample, we assume just one resource server.
+ // If this authorization server needs to mint access tokens for more than one resource server,
+ // we'd look at the request message passed to us and decide which public key to return.
+ resourceServerEncryptionKey.ImportParameters(ResourceServerEncryptionPublicKey);
+
+ return resourceServerEncryptionKey;
+ }
+
+ public IClientDescription GetClient(string clientIdentifier) {
+ var consumerRow = MvcApplication.DataContext.Clients.SingleOrDefault(
+ consumerCandidate => consumerCandidate.ClientIdentifier == clientIdentifier);
+ if (consumerRow == null) {
+ throw new ArgumentOutOfRangeException("clientIdentifier");
+ }
+
+ return consumerRow;
+ }
+
+ public bool IsAuthorizationValid(IAuthorizationDescription authorization) {
+ return this.IsAuthorizationValid(authorization.Scope, authorization.ClientIdentifier, authorization.UtcIssued, authorization.User);
+ }
+
+ public bool IsResourceOwnerCredentialValid(string userName, string password) {
+ // This web site delegates user authentication to OpenID Providers, and as such no users have local passwords with this server.
+ throw new NotSupportedException();
+ }
+
+ #endregion
+
+ public bool CanBeAutoApproved(EndUserAuthorizationRequest authorizationRequest) {
+ if (authorizationRequest == null) {
+ throw new ArgumentNullException("authorizationRequest");
+ }
+
+ // NEVER issue an auto-approval to a client that would end up getting an access token immediately
+ // (without a client secret), as that would allow arbitrary clients to masquarade as an approved client
+ // and obtain unauthorized access to user data.
+ if (authorizationRequest.ResponseType == EndUserAuthorizationResponseType.AuthorizationCode) {
+ // Never issue auto-approval if the client secret is blank, since that too makes it easy to spoof
+ // a client's identity and obtain unauthorized access.
+ var requestingClient = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == authorizationRequest.ClientIdentifier);
+ if (!string.IsNullOrEmpty(requestingClient.ClientSecret)) {
+ return this.IsAuthorizationValid(
+ authorizationRequest.Scope,
+ authorizationRequest.ClientIdentifier,
+ DateTime.UtcNow,
+ HttpContext.Current.User.Identity.Name);
+ }
+ }
+
+ // Default to not auto-approving.
+ return false;
+ }
+
+ /// <summary>
+ /// Creates the RSA key used by all the crypto service provider instances we create.
+ /// </summary>
+ /// <returns>RSA data that includes the private key.</returns>
+ private static RSAParameters CreateRSAKey() {
+#if SAMPLESONLY
+ // Since the sample authorization server and the sample resource server must work together,
+ // we hard-code a FOR SAMPLE USE ONLY key pair. The matching public key information is hard-coded into the OAuthResourceServer sample.
+ // In a real app, the RSA parameters would typically come from a certificate that may already exist. It may simply be the HTTPS certificate for the auth server.
+ return new RSAParameters {
+ Exponent = new byte[] { 1, 0, 1 },
+ Modulus = new byte[] { 210, 95, 53, 12, 203, 114, 150, 23, 23, 88, 4, 200, 47, 219, 73, 54, 146, 253, 126, 121, 105, 91, 118, 217, 182, 167, 140, 6, 67, 112, 97, 183, 66, 112, 245, 103, 136, 222, 205, 28, 196, 45, 6, 223, 192, 76, 56, 180, 90, 120, 144, 19, 31, 193, 37, 129, 186, 214, 36, 53, 204, 53, 108, 133, 112, 17, 133, 244, 3, 12, 230, 29, 243, 51, 79, 253, 10, 111, 185, 23, 74, 230, 99, 94, 78, 49, 209, 39, 95, 213, 248, 212, 22, 4, 222, 145, 77, 190, 136, 230, 134, 70, 228, 241, 194, 216, 163, 234, 52, 1, 64, 181, 139, 128, 90, 255, 214, 60, 168, 233, 254, 110, 31, 102, 58, 67, 201, 33 },
+ P = new byte[] { 237, 238, 79, 75, 29, 57, 145, 201, 57, 177, 215, 108, 40, 77, 232, 237, 113, 38, 157, 195, 174, 134, 188, 175, 121, 28, 11, 236, 80, 146, 12, 38, 8, 12, 104, 46, 6, 247, 14, 149, 196, 23, 130, 116, 141, 137, 225, 74, 84, 111, 44, 163, 55, 10, 246, 154, 195, 158, 186, 241, 162, 11, 217, 77 },
+ Q = new byte[] { 226, 89, 29, 67, 178, 205, 30, 152, 184, 165, 15, 152, 131, 245, 141, 80, 150, 3, 224, 136, 188, 248, 149, 36, 200, 250, 207, 156, 224, 79, 150, 191, 84, 214, 233, 173, 95, 192, 55, 123, 124, 255, 53, 85, 11, 233, 156, 66, 14, 27, 27, 163, 108, 199, 90, 37, 118, 38, 78, 171, 80, 26, 101, 37 },
+ DP = new byte[] { 108, 176, 122, 132, 131, 187, 50, 191, 203, 157, 84, 29, 82, 100, 20, 205, 178, 236, 195, 17, 10, 254, 253, 222, 226, 226, 79, 8, 10, 222, 76, 178, 106, 230, 208, 8, 134, 162, 1, 133, 164, 232, 96, 109, 193, 226, 132, 138, 33, 252, 15, 86, 23, 228, 232, 54, 86, 186, 130, 7, 179, 208, 217, 217 },
+ DQ = new byte[] { 175, 63, 252, 46, 140, 99, 208, 138, 194, 123, 218, 101, 101, 214, 91, 65, 199, 196, 220, 182, 66, 73, 221, 128, 11, 180, 85, 198, 202, 206, 20, 147, 179, 102, 106, 170, 247, 245, 229, 127, 81, 58, 111, 218, 151, 76, 154, 213, 114, 2, 127, 21, 187, 133, 102, 64, 151, 7, 245, 229, 34, 50, 45, 153 },
+ InverseQ = new byte[] { 137, 156, 11, 248, 118, 201, 135, 145, 134, 121, 14, 162, 149, 14, 98, 84, 108, 160, 27, 91, 230, 116, 216, 181, 200, 49, 34, 254, 119, 153, 179, 52, 231, 234, 36, 148, 71, 161, 182, 171, 35, 182, 46, 164, 179, 100, 226, 71, 119, 23, 0, 16, 240, 4, 30, 57, 76, 109, 89, 131, 56, 219, 71, 206 },
+ D = new byte[] { 108, 15, 123, 176, 150, 208, 197, 72, 23, 53, 159, 63, 53, 85, 238, 197, 153, 187, 156, 187, 192, 226, 186, 170, 26, 168, 245, 196, 65, 223, 248, 81, 170, 79, 91, 191, 83, 15, 31, 77, 39, 119, 249, 143, 245, 183, 49, 105, 115, 15, 122, 242, 87, 221, 94, 230, 196, 146, 59, 7, 103, 94, 9, 223, 146, 180, 189, 86, 190, 94, 242, 59, 32, 54, 23, 181, 124, 170, 63, 172, 90, 158, 169, 140, 6, 102, 170, 0, 135, 199, 35, 196, 212, 238, 196, 56, 14, 0, 140, 197, 169, 240, 156, 43, 182, 123, 102, 79, 89, 20, 120, 171, 43, 223, 58, 190, 230, 166, 185, 162, 186, 226, 31, 206, 196, 188, 104, 1 },
+ };
+#else
+ // This is how you could generate your own public/private key pair.
+ // As we generate a new random key, we need to set the UseMachineKeyStore flag so that this doesn't
+ // crash on IIS. For more information:
+ // http://social.msdn.microsoft.com/Forums/en-US/clr/thread/7ea48fd0-8d6b-43ed-b272-1a0249ae490f?prof=required
+ var cspParameters = new CspParameters();
+ cspParameters.Flags = CspProviderFlags.UseArchivableKey | CspProviderFlags.UseMachineKeyStore;
+ var keyPair = new RSACryptoServiceProvider(cspParameters);
+
+ // After exporting the private/public key information, read the information out and store it somewhere
+ var privateKey = keyPair.ExportParameters(true);
+ var publicKey = keyPair.ExportParameters(false);
+
+ // Ultimately the private key information must be what is returned through the AccessTokenSigningPrivateKey property.
+ return privateKey;
+#endif
+ }
+
+ private static RSACryptoServiceProvider CreateRSA() {
+ var rsa = new RSACryptoServiceProvider();
+ rsa.ImportParameters(CreateRSAKey());
+ return rsa;
+ }
+
+ private bool IsAuthorizationValid(HashSet<string> requestedScopes, string clientIdentifier, DateTime issuedUtc, string username) {
+ // If db precision exceeds token time precision (which is common), the following query would
+ // often disregard a token that is minted immediately after the authorization record is stored in the db.
+ // To compensate for this, we'll increase the timestamp on the token's issue date by 1 second.
+ issuedUtc += TimeSpan.FromSeconds(1);
+ var grantedScopeStrings = from auth in MvcApplication.DataContext.ClientAuthorizations
+ where
+ auth.Client.ClientIdentifier == clientIdentifier &&
+ auth.CreatedOnUtc <= issuedUtc &&
+ (!auth.ExpirationDateUtc.HasValue || auth.ExpirationDateUtc.Value >= DateTime.UtcNow) &&
+ auth.User.OpenIDClaimedIdentifier == username
+ select auth.Scope;
+
+ if (!grantedScopeStrings.Any()) {
+ // No granted authorizations prior to the issuance of this token, so it must have been revoked.
+ // Even if later authorizations restore this client's ability to call in, we can't allow
+ // access tokens issued before the re-authorization because the revoked authorization should
+ // effectively and permanently revoke all access and refresh tokens.
+ return false;
+ }
+
+ var grantedScopes = new HashSet<string>(OAuthUtilities.ScopeStringComparer);
+ foreach (string scope in grantedScopeStrings) {
+ grantedScopes.UnionWith(OAuthUtilities.SplitScopes(scope));
+ }
+
+ return requestedScopes.IsSubsetOf(grantedScopes);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Code/Utilities.cs b/src/OAuth/OAuthAuthorizationServer/Code/Utilities.cs
new file mode 100644
index 0000000..c9109bd
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Code/Utilities.cs
@@ -0,0 +1,21 @@
+namespace OAuthAuthorizationServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ internal static class Utilities {
+ /// <summary>
+ /// Ensures that local times are converted to UTC times. Unspecified kinds are recast to UTC with no conversion.
+ /// </summary>
+ /// <param name="value">The date-time to convert.</param>
+ /// <returns>The date-time in UTC time.</returns>
+ internal static DateTime AsUtc(this DateTime value) {
+ if (value.Kind == DateTimeKind.Unspecified) {
+ return new DateTime(value.Ticks, DateTimeKind.Utc);
+ }
+
+ return value.ToUniversalTime();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Content/Site.css b/src/OAuth/OAuthAuthorizationServer/Content/Site.css
new file mode 100644
index 0000000..fedbbc3
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Content/Site.css
@@ -0,0 +1,344 @@
+/*----------------------------------------------------------
+The base color for this template is #5c87b2. If you'd like
+to use a different color start by replacing all instances of
+#5c87b2 with your new color.
+----------------------------------------------------------*/
+body
+{
+ background-color: #5c87b2;
+ font-size: .75em;
+ font-family: Verdana, Helvetica, Sans-Serif;
+ margin: 0;
+ padding: 0;
+ color: #696969;
+}
+
+a:link
+{
+ color: #034af3;
+ text-decoration: underline;
+}
+a:visited
+{
+ color: #505abc;
+}
+a:hover
+{
+ color: #1d60ff;
+ text-decoration: none;
+}
+a:active
+{
+ color: #12eb87;
+}
+
+p, ul
+{
+ margin-bottom: 20px;
+ line-height: 1.6em;
+}
+
+/* HEADINGS
+----------------------------------------------------------*/
+h1, h2, h3, h4, h5, h6
+{
+ font-size: 1.5em;
+ color: #000;
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+h1
+{
+ font-size: 2em;
+ padding-bottom: 0;
+ margin-bottom: 0;
+}
+h2
+{
+ padding: 0 0 10px 0;
+}
+h3
+{
+ font-size: 1.2em;
+}
+h4
+{
+ font-size: 1.1em;
+}
+h5, h6
+{
+ font-size: 1em;
+}
+
+/* this rule styles <h2> tags that are the
+first child of the left and right table columns */
+.rightColumn > h1, .rightColumn > h2, .leftColumn > h1, .leftColumn > h2
+{
+ margin-top: 0;
+}
+
+/* PRIMARY LAYOUT ELEMENTS
+----------------------------------------------------------*/
+
+/* you can specify a greater or lesser percentage for the
+page width. Or, you can specify an exact pixel width. */
+.page
+{
+ width: 90%;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+#header
+{
+ position: relative;
+ margin-bottom: 0px;
+ color: #000;
+ padding: 0;
+}
+
+#header h1
+{
+ font-weight: bold;
+ padding: 5px 0;
+ margin: 0;
+ color: #fff;
+ border: none;
+ line-height: 2em;
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 32px !important;
+}
+
+#main
+{
+ padding: 30px 30px 15px 30px;
+ background-color: #fff;
+ margin-bottom: 30px;
+ _height: 1px; /* only IE6 applies CSS properties starting with an underscore */
+}
+
+#footer
+{
+ color: #999;
+ padding: 10px 0;
+ text-align: center;
+ line-height: normal;
+ margin: 0;
+ font-size: .9em;
+}
+
+/* TAB MENU
+----------------------------------------------------------*/
+ul#menu
+{
+ border-bottom: 1px #5C87B2 solid;
+ padding: 0 0 2px;
+ position: relative;
+ margin: 0;
+ text-align: right;
+}
+
+ul#menu li
+{
+ display: inline;
+ list-style: none;
+}
+
+ul#menu li#greeting
+{
+ padding: 10px 20px;
+ font-weight: bold;
+ text-decoration: none;
+ line-height: 2.8em;
+ color: #fff;
+}
+
+ul#menu li a
+{
+ padding: 10px 20px;
+ font-weight: bold;
+ text-decoration: none;
+ line-height: 2.8em;
+ background-color: #e8eef4;
+ color: #034af3;
+}
+
+ul#menu li a:hover
+{
+ background-color: #fff;
+ text-decoration: none;
+}
+
+ul#menu li a:active
+{
+ background-color: #a6e2a6;
+ text-decoration: none;
+}
+
+ul#menu li.selected a
+{
+ background-color: #fff;
+ color: #000;
+}
+
+/* FORM LAYOUT ELEMENTS
+----------------------------------------------------------*/
+
+fieldset
+{
+ margin: 1em 0;
+ padding: 1em;
+ border: 1px solid #CCC;
+}
+
+fieldset p
+{
+ margin: 2px 12px 10px 10px;
+}
+
+legend
+{
+ font-size: 1.1em;
+ font-weight: 600;
+ padding: 2px 4px 8px 4px;
+}
+
+input[type="text"]
+{
+ width: 200px;
+ border: 1px solid #CCC;
+}
+
+input[type="password"]
+{
+ width: 200px;
+ border: 1px solid #CCC;
+}
+
+/* TABLE
+----------------------------------------------------------*/
+
+table
+{
+ border: solid 1px #e8eef4;
+ border-collapse: collapse;
+}
+
+table td
+{
+ padding: 5px;
+ border: solid 1px #e8eef4;
+}
+
+table th
+{
+ padding: 6px 5px;
+ text-align: left;
+ background-color: #e8eef4;
+ border: solid 1px #e8eef4;
+}
+
+/* MISC
+----------------------------------------------------------*/
+.clear
+{
+ clear: both;
+}
+
+.error
+{
+ color:Red;
+}
+
+#menucontainer
+{
+ margin-top:40px;
+}
+
+div#title
+{
+ display:block;
+ float:left;
+ text-align:left;
+}
+
+#logindisplay
+{
+ font-size:1.1em;
+ display:block;
+ text-align:right;
+ margin:10px;
+ color:White;
+}
+
+#logindisplay a:link
+{
+ color: white;
+ text-decoration: underline;
+}
+
+#logindisplay a:visited
+{
+ color: white;
+ text-decoration: underline;
+}
+
+#logindisplay a:hover
+{
+ color: white;
+ text-decoration: none;
+}
+
+/* Styles for validation helpers
+-----------------------------------------------------------*/
+.field-validation-error
+{
+ color: #ff0000;
+}
+
+.field-validation-valid
+{
+ display: none;
+}
+
+.input-validation-error
+{
+ border: 1px solid #ff0000;
+ background-color: #ffeeee;
+}
+
+.validation-summary-errors
+{
+ font-weight: bold;
+ color: #ff0000;
+}
+
+.validation-summary-valid
+{
+ display: none;
+}
+
+/* Styles for editor and display helpers
+----------------------------------------------------------*/
+.display-label,
+.editor-label,
+.display-field,
+.editor-field
+{
+ margin: 0.5em 0;
+}
+
+.text-box
+{
+ width: 30em;
+}
+
+.text-box.multi-line
+{
+ height: 6.5em;
+}
+
+.tri-state
+{
+ width: 6em;
+}
diff --git a/src/OAuth/OAuthAuthorizationServer/Controllers/AccountController.cs b/src/OAuth/OAuthAuthorizationServer/Controllers/AccountController.cs
new file mode 100644
index 0000000..d69a3b5
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Controllers/AccountController.cs
@@ -0,0 +1,78 @@
+namespace OAuthAuthorizationServer.Controllers {
+ using System;
+ using System.Linq;
+ using System.Web.Mvc;
+ using System.Web.Security;
+
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OpenId;
+ using DotNetOpenAuth.OpenId.RelyingParty;
+
+ using OAuthAuthorizationServer.Code;
+ using OAuthAuthorizationServer.Models;
+
+ [HandleError]
+ public class AccountController : Controller {
+ // **************************************
+ // URL: /Account/LogOn
+ // **************************************
+ public ActionResult LogOn() {
+ return View();
+ }
+
+ [HttpPost]
+ public ActionResult LogOn(LogOnModel model, string returnUrl) {
+ if (ModelState.IsValid) {
+ var rp = new OpenIdRelyingParty();
+ var request = rp.CreateRequest(model.UserSuppliedIdentifier, Realm.AutoDetect, new Uri(Request.Url, Url.Action("Authenticate")));
+ if (request != null) {
+ if (returnUrl != null) {
+ request.AddCallbackArguments("returnUrl", returnUrl);
+ }
+
+ return request.RedirectingResponse.AsActionResult();
+ } else {
+ ModelState.AddModelError(string.Empty, "The identifier you supplied is not recognized as a valid OpenID Identifier.");
+ }
+ }
+
+ // If we got this far, something failed, redisplay form
+ return View(model);
+ }
+
+ public ActionResult Authenticate(string returnUrl) {
+ var rp = new OpenIdRelyingParty();
+ var response = rp.GetResponse();
+ if (response != null) {
+ switch (response.Status) {
+ case AuthenticationStatus.Authenticated:
+ // Make sure we have a user account for this guy.
+ string identifier = response.ClaimedIdentifier; // convert to string so LinqToSQL expression parsing works.
+ if (MvcApplication.DataContext.Users.FirstOrDefault(u => u.OpenIDClaimedIdentifier == identifier) == null) {
+ MvcApplication.DataContext.Users.InsertOnSubmit(new User {
+ OpenIDFriendlyIdentifier = response.FriendlyIdentifierForDisplay,
+ OpenIDClaimedIdentifier = response.ClaimedIdentifier,
+ });
+ }
+
+ FormsAuthentication.SetAuthCookie(response.ClaimedIdentifier, false);
+ return this.Redirect(returnUrl ?? Url.Action("Index", "Home"));
+ default:
+ ModelState.AddModelError(string.Empty, "An error occurred during login.");
+ break;
+ }
+ }
+
+ return this.View("LogOn");
+ }
+
+ // **************************************
+ // URL: /Account/LogOff
+ // **************************************
+ public ActionResult LogOff() {
+ FormsAuthentication.SignOut();
+
+ return RedirectToAction("Index", "Home");
+ }
+ }
+}
diff --git a/src/OAuth/OAuthAuthorizationServer/Controllers/HomeController.cs b/src/OAuth/OAuthAuthorizationServer/Controllers/HomeController.cs
new file mode 100644
index 0000000..d6dd144
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Controllers/HomeController.cs
@@ -0,0 +1,59 @@
+namespace OAuthAuthorizationServer.Controllers {
+ using System.Configuration;
+ using System.Data.SqlClient;
+ using System.IO;
+ using System.Linq;
+ using System.Web.Mvc;
+ using System.Web.Security;
+ using OAuthAuthorizationServer.Code;
+
+ [HandleError]
+ public class HomeController : Controller {
+ public ActionResult Index() {
+ return View();
+ }
+
+ public ActionResult About() {
+ return View();
+ }
+
+ [HttpPost]
+ public ActionResult CreateDatabase() {
+ string databasePath = Path.Combine(Server.MapPath(Request.ApplicationPath), "App_Data");
+ if (!Directory.Exists(databasePath)) {
+ Directory.CreateDirectory(databasePath);
+ }
+ string connectionString = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString.Replace("|DataDirectory|", databasePath);
+ var dc = new DataClassesDataContext(connectionString);
+ if (dc.DatabaseExists()) {
+ dc.DeleteDatabase();
+ }
+ try {
+ dc.CreateDatabase();
+
+ // Add the necessary row for the sample client.
+ dc.Clients.InsertOnSubmit(new Client {
+ ClientIdentifier = "sampleconsumer",
+ ClientSecret = "samplesecret",
+ Name = "Some sample client",
+ });
+ dc.Clients.InsertOnSubmit(new Client {
+ ClientIdentifier = "sampleImplicitConsumer",
+ Name = "Some sample client used for implicit grants (no secret)",
+ Callback = "http://localhost:59721/",
+ });
+
+ dc.SubmitChanges();
+
+ // Force the user to log out because a new database warrants a new row in the users table, which we create
+ // when the user logs in.
+ FormsAuthentication.SignOut();
+ ViewData["Success"] = true;
+ } catch (SqlException ex) {
+ ViewData["Error"] = string.Join("<br>", ex.Errors.OfType<SqlError>().Select(er => er.Message).ToArray());
+ }
+
+ return this.View();
+ }
+ }
+}
diff --git a/src/OAuth/OAuthAuthorizationServer/Controllers/OAuthController.cs b/src/OAuth/OAuthAuthorizationServer/Controllers/OAuthController.cs
new file mode 100644
index 0000000..4260b48
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Controllers/OAuthController.cs
@@ -0,0 +1,92 @@
+namespace OAuthAuthorizationServer.Controllers {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Net;
+ using System.Security.Cryptography;
+ using System.Web;
+ using System.Web.Mvc;
+
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth2;
+
+ using OAuthAuthorizationServer.Code;
+ using OAuthAuthorizationServer.Models;
+
+ public class OAuthController : Controller {
+ private readonly AuthorizationServer authorizationServer = new AuthorizationServer(new OAuth2AuthorizationServer());
+
+ /// <summary>
+ /// The OAuth 2.0 token endpoint.
+ /// </summary>
+ /// <returns>The response to the Client.</returns>
+ public ActionResult Token() {
+ return this.authorizationServer.HandleTokenRequest(this.Request).AsActionResult();
+ }
+
+ /// <summary>
+ /// Prompts the user to authorize a client to access the user's private data.
+ /// </summary>
+ /// <returns>The browser HTML response that prompts the user to authorize the client.</returns>
+ [Authorize, AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
+ [HttpHeader("x-frame-options", "SAMEORIGIN")] // mitigates clickjacking
+ public ActionResult Authorize() {
+ var pendingRequest = this.authorizationServer.ReadAuthorizationRequest();
+ if (pendingRequest == null) {
+ throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
+ }
+
+ var requestingClient = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
+
+ // Consider auto-approving if safe to do so.
+ if (((OAuth2AuthorizationServer)this.authorizationServer.AuthorizationServerServices).CanBeAutoApproved(pendingRequest)) {
+ var approval = this.authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, HttpContext.User.Identity.Name);
+ return this.authorizationServer.Channel.PrepareResponse(approval).AsActionResult();
+ }
+
+ var model = new AccountAuthorizeModel {
+ ClientApp = requestingClient.Name,
+ Scope = pendingRequest.Scope,
+ AuthorizationRequest = pendingRequest,
+ };
+
+ return View(model);
+ }
+
+ /// <summary>
+ /// Processes the user's response as to whether to authorize a Client to access his/her private data.
+ /// </summary>
+ /// <param name="isApproved">if set to <c>true</c>, the user has authorized the Client; <c>false</c> otherwise.</param>
+ /// <returns>HTML response that redirects the browser to the Client.</returns>
+ [Authorize, HttpPost, ValidateAntiForgeryToken]
+ public ActionResult AuthorizeResponse(bool isApproved) {
+ var pendingRequest = this.authorizationServer.ReadAuthorizationRequest();
+ if (pendingRequest == null) {
+ throw new HttpException((int)HttpStatusCode.BadRequest, "Missing authorization request.");
+ }
+
+ IDirectedProtocolMessage response;
+ if (isApproved) {
+ // The authorization we file in our database lasts until the user explicitly revokes it.
+ // You can cause the authorization to expire by setting the ExpirationDateUTC
+ // property in the below created ClientAuthorization.
+ var client = MvcApplication.DataContext.Clients.First(c => c.ClientIdentifier == pendingRequest.ClientIdentifier);
+ client.ClientAuthorizations.Add(
+ new ClientAuthorization {
+ Scope = OAuthUtilities.JoinScopes(pendingRequest.Scope),
+ User = MvcApplication.LoggedInUser,
+ CreatedOnUtc = DateTime.UtcNow,
+ });
+ MvcApplication.DataContext.SubmitChanges(); // submit now so that this new row can be retrieved later in this same HTTP request
+
+ // In this simple sample, the user either agrees to the entire scope requested by the client or none of it.
+ // But in a real app, you could grant a reduced scope of access to the client by passing a scope parameter to this method.
+ response = this.authorizationServer.PrepareApproveAuthorizationRequest(pendingRequest, User.Identity.Name);
+ } else {
+ response = this.authorizationServer.PrepareRejectAuthorizationRequest(pendingRequest);
+ }
+
+ return this.authorizationServer.Channel.PrepareResponse(response).AsActionResult();
+ }
+ }
+}
diff --git a/src/OAuth/OAuthAuthorizationServer/Global.asax b/src/OAuth/OAuthAuthorizationServer/Global.asax
new file mode 100644
index 0000000..77c9760
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Global.asax
@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="OAuthAuthorizationServer.MvcApplication" Language="C#" %>
diff --git a/src/OAuth/OAuthAuthorizationServer/Global.asax.cs b/src/OAuth/OAuthAuthorizationServer/Global.asax.cs
new file mode 100644
index 0000000..da5c393
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Global.asax.cs
@@ -0,0 +1,123 @@
+namespace OAuthAuthorizationServer {
+ using System;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+ using System.Web.Mvc;
+ using System.Web.Routing;
+
+ using Code;
+
+ /// <summary>
+ /// The global MVC Application.
+ /// </summary>
+ /// <remarks>
+ /// Note: For instructions on enabling IIS6 or IIS7 classic mode,
+ /// visit http://go.microsoft.com/?LinkId=9394801
+ /// </remarks>
+ public class MvcApplication : System.Web.HttpApplication {
+ /// <summary>
+ /// An application memory cache of recent log messages.
+ /// </summary>
+ public static StringBuilder LogMessages = new StringBuilder();
+
+ /// <summary>
+ /// The logger for this sample to use.
+ /// </summary>
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthAuthorizationServer");
+
+ public static DatabaseKeyNonceStore KeyNonceStore { get; set; }
+
+ /// <summary>
+ /// Gets the transaction-protected database connection for the current request.
+ /// </summary>
+ public static DataClassesDataContext DataContext {
+ get {
+ DataClassesDataContext dataContext = DataContextSimple;
+ if (dataContext == null) {
+ dataContext = new DataClassesDataContext();
+ dataContext.Connection.Open();
+ dataContext.Transaction = dataContext.Connection.BeginTransaction();
+ DataContextSimple = dataContext;
+ }
+
+ return dataContext;
+ }
+ }
+
+ public static User LoggedInUser {
+ get { return DataContext.Users.SingleOrDefault(user => user.OpenIDClaimedIdentifier == HttpContext.Current.User.Identity.Name); }
+ }
+
+ private static DataClassesDataContext DataContextSimple {
+ get {
+ if (HttpContext.Current != null) {
+ return HttpContext.Current.Items["DataContext"] as DataClassesDataContext;
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+
+ set {
+ if (HttpContext.Current != null) {
+ HttpContext.Current.Items["DataContext"] = value;
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public static void RegisterRoutes(RouteCollection routes) {
+ routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
+
+ routes.MapRoute(
+ "Default", // Route name
+ "{controller}/{action}/{id}", // URL with parameters
+ new { controller = "Home", action = "Index", id = UrlParameter.Optional }); // Parameter defaults
+ }
+
+ protected void Application_Start() {
+ AreaRegistration.RegisterAllAreas();
+
+ RegisterRoutes(RouteTable.Routes);
+
+ KeyNonceStore = new DatabaseKeyNonceStore();
+
+ log4net.Config.XmlConfigurator.Configure();
+ Logger.Info("Sample starting...");
+ }
+
+ protected void Application_End(object sender, EventArgs e) {
+ Logger.Info("Sample shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ protected void Application_Error(object sender, EventArgs e) {
+ Logger.Error("An unhandled exception occurred in ASP.NET processing: " + Server.GetLastError(), Server.GetLastError());
+
+ // In the event of an unhandled exception, reverse any changes that were made to the database to avoid any partial database updates.
+ var dataContext = DataContextSimple;
+ if (dataContext != null) {
+ dataContext.Transaction.Rollback();
+ dataContext.Connection.Close();
+ dataContext.Dispose();
+ DataContextSimple = null;
+ }
+ }
+
+ protected void Application_EndRequest(object sender, EventArgs e) {
+ CommitAndCloseDatabaseIfNecessary();
+ }
+
+ private static void CommitAndCloseDatabaseIfNecessary() {
+ var dataContext = DataContextSimple;
+ if (dataContext != null) {
+ dataContext.SubmitChanges();
+ dataContext.Transaction.Commit();
+ dataContext.Connection.Close();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Models/AccountAuthorizeModel.cs b/src/OAuth/OAuthAuthorizationServer/Models/AccountAuthorizeModel.cs
new file mode 100644
index 0000000..ee91416
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Models/AccountAuthorizeModel.cs
@@ -0,0 +1,16 @@
+namespace OAuthAuthorizationServer.Models {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ using DotNetOpenAuth.OAuth2.Messages;
+
+ public class AccountAuthorizeModel {
+ public string ClientApp { get; set; }
+
+ public HashSet<string> Scope { get; set; }
+
+ public EndUserAuthorizationRequest AuthorizationRequest { get; set; }
+ }
+}
diff --git a/src/OAuth/OAuthAuthorizationServer/Models/AccountModels.cs b/src/OAuth/OAuthAuthorizationServer/Models/AccountModels.cs
new file mode 100644
index 0000000..32deb0b
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Models/AccountModels.cs
@@ -0,0 +1,13 @@
+namespace OAuthAuthorizationServer.Models {
+ using System.ComponentModel;
+ using System.ComponentModel.DataAnnotations;
+
+ public class LogOnModel {
+ [Required]
+ [DisplayName("OpenID")]
+ public string UserSuppliedIdentifier { get; set; }
+
+ [DisplayName("Remember me?")]
+ public bool RememberMe { get; set; }
+ }
+}
diff --git a/src/OAuth/OAuthAuthorizationServer/OAuthAuthorizationServer.csproj b/src/OAuth/OAuthAuthorizationServer/OAuthAuthorizationServer.csproj
new file mode 100644
index 0000000..f148eca
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/OAuthAuthorizationServer.csproj
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C78E8235-1D46-43EB-A912-80B522C4E9AE}</ProjectGuid>
+ <ProjectTypeGuids>{F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>OAuthAuthorizationServer</RootNamespace>
+ <AssemblyName>OAuthAuthorizationServer</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <MvcBuildViews>false</MvcBuildViews>
+ <UseIISExpress>false</UseIISExpress>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;SAMPLESONLY</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;SAMPLESONLY</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="DotNetOpenAuth.Core">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.Core.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2.AuthorizationServer">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.AuthorizationServer.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.AuthorizationServer.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OpenId">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OpenId.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OpenId.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OpenId.RelyingParty">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OpenId.RelyingParty.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OpenId.RelyingParty.dll</HintPath>
+ </Reference>
+ <Reference Include="log4net">
+ <HintPath>..\..\..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.Linq" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web.DynamicData" />
+ <Reference Include="System.Web.Entity" />
+ <Reference Include="System.Web.ApplicationServices" />
+ <Reference Include="System.ComponentModel.DataAnnotations">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Extensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.Routing" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Code\Client.cs" />
+ <Compile Include="Code\DatabaseKeyNonceStore.cs" />
+ <Compile Include="Code\DataClasses.designer.cs">
+ <DependentUpon>DataClasses.dbml</DependentUpon>
+ <DesignTime>True</DesignTime>
+ <AutoGen>True</AutoGen>
+ </Compile>
+ <Compile Include="Code\HttpHeaderAttribute.cs" />
+ <Compile Include="Code\OAuth2AuthorizationServer.cs" />
+ <Compile Include="Code\Utilities.cs" />
+ <Compile Include="Controllers\AccountController.cs" />
+ <Compile Include="Controllers\HomeController.cs" />
+ <Compile Include="Controllers\OAuthController.cs" />
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="Models\AccountAuthorizeModel.cs" />
+ <Compile Include="Models\AccountModels.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Global.asax" />
+ <Content Include="Views\Home\CreateDatabase.aspx" />
+ <Content Include="Views\OAuth\Authorize.aspx" />
+ <Content Include="Web.config" />
+ <Content Include="Web.Debug.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </Content>
+ <Content Include="Web.Release.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </Content>
+ <Content Include="Content\Site.css" />
+ <Content Include="Scripts\jquery-1.4.1.js" />
+ <Content Include="Scripts\jquery-1.4.1.min.js" />
+ <Content Include="Scripts\jquery-1.4.1-vsdoc.js" />
+ <Content Include="Scripts\jquery.validate.js" />
+ <Content Include="Scripts\jquery.validate.min.js" />
+ <Content Include="Scripts\jquery.validate-vsdoc.js" />
+ <Content Include="Scripts\MicrosoftAjax.js" />
+ <Content Include="Scripts\MicrosoftAjax.debug.js" />
+ <Content Include="Scripts\MicrosoftMvcAjax.js" />
+ <Content Include="Scripts\MicrosoftMvcAjax.debug.js" />
+ <Content Include="Scripts\MicrosoftMvcValidation.js" />
+ <Content Include="Scripts\MicrosoftMvcValidation.debug.js" />
+ <Content Include="Views\Account\LogOn.aspx" />
+ <Content Include="Views\Home\About.aspx" />
+ <Content Include="Views\Home\Index.aspx" />
+ <Content Include="Views\Shared\Error.aspx" />
+ <Content Include="Views\Shared\LogOnUserControl.ascx" />
+ <Content Include="Views\Shared\Site.Master" />
+ <Content Include="Views\Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\DataClasses.dbml">
+ <Generator>MSLinqToSQLGenerator</Generator>
+ <LastGenOutput>DataClasses.designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </None>
+ <Content Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\DataClasses.dbml.layout">
+ <DependentUpon>DataClasses.dbml</DependentUpon>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target> -->
+ <Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
+ <AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
+ </Target>
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>50172</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+</Project> \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Properties/AssemblyInfo.cs b/src/OAuth/OAuthAuthorizationServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..0ec2b48
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OAuthAuthorizationServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("OAuthAuthorizationServer")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("be2911ac-b0a2-406e-bffa-acd8484d179e")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftAjax.debug.js b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftAjax.debug.js
new file mode 100644
index 0000000..a5f7942
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftAjax.debug.js
@@ -0,0 +1,7117 @@
+// Name: MicrosoftAjax.debug.js
+// Assembly: System.Web.Extensions
+// Version: 4.0.0.0
+// FileVersion: 4.0.20526.0
+//-----------------------------------------------------------------------
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//-----------------------------------------------------------------------
+// MicrosoftAjax.js
+// Microsoft AJAX Framework.
+
+Function.__typeName = 'Function';
+Function.__class = true;
+Function.createCallback = function Function$createCallback(method, context) {
+ /// <summary locid="M:J#Function.createCallback" />
+ /// <param name="method" type="Function"></param>
+ /// <param name="context" mayBeNull="true"></param>
+ /// <returns type="Function"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "method", type: Function},
+ {name: "context", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ return function() {
+ var l = arguments.length;
+ if (l > 0) {
+ var args = [];
+ for (var i = 0; i < l; i++) {
+ args[i] = arguments[i];
+ }
+ args[l] = context;
+ return method.apply(this, args);
+ }
+ return method.call(this, context);
+ }
+}
+Function.createDelegate = function Function$createDelegate(instance, method) {
+ /// <summary locid="M:J#Function.createDelegate" />
+ /// <param name="instance" mayBeNull="true"></param>
+ /// <param name="method" type="Function"></param>
+ /// <returns type="Function"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "instance", mayBeNull: true},
+ {name: "method", type: Function}
+ ]);
+ if (e) throw e;
+ return function() {
+ return method.apply(instance, arguments);
+ }
+}
+Function.emptyFunction = Function.emptyMethod = function Function$emptyMethod() {
+ /// <summary locid="M:J#Function.emptyMethod" />
+}
+Function.validateParameters = function Function$validateParameters(parameters, expectedParameters, validateParameterCount) {
+ /// <summary locid="M:J#Function.validateParameters" />
+ /// <param name="parameters"></param>
+ /// <param name="expectedParameters"></param>
+ /// <param name="validateParameterCount" type="Boolean" optional="true"></param>
+ /// <returns type="Error" mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "parameters"},
+ {name: "expectedParameters"},
+ {name: "validateParameterCount", type: Boolean, optional: true}
+ ]);
+ if (e) throw e;
+ return Function._validateParams(parameters, expectedParameters, validateParameterCount);
+}
+Function._validateParams = function Function$_validateParams(params, expectedParams, validateParameterCount) {
+ var e, expectedLength = expectedParams.length;
+ validateParameterCount = validateParameterCount || (typeof(validateParameterCount) === "undefined");
+ e = Function._validateParameterCount(params, expectedParams, validateParameterCount);
+ if (e) {
+ e.popStackFrame();
+ return e;
+ }
+ for (var i = 0, l = params.length; i < l; i++) {
+ var expectedParam = expectedParams[Math.min(i, expectedLength - 1)],
+ paramName = expectedParam.name;
+ if (expectedParam.parameterArray) {
+ paramName += "[" + (i - expectedLength + 1) + "]";
+ }
+ else if (!validateParameterCount && (i >= expectedLength)) {
+ break;
+ }
+ e = Function._validateParameter(params[i], expectedParam, paramName);
+ if (e) {
+ e.popStackFrame();
+ return e;
+ }
+ }
+ return null;
+}
+Function._validateParameterCount = function Function$_validateParameterCount(params, expectedParams, validateParameterCount) {
+ var i, error,
+ expectedLen = expectedParams.length,
+ actualLen = params.length;
+ if (actualLen < expectedLen) {
+ var minParams = expectedLen;
+ for (i = 0; i < expectedLen; i++) {
+ var param = expectedParams[i];
+ if (param.optional || param.parameterArray) {
+ minParams--;
+ }
+ }
+ if (actualLen < minParams) {
+ error = true;
+ }
+ }
+ else if (validateParameterCount && (actualLen > expectedLen)) {
+ error = true;
+ for (i = 0; i < expectedLen; i++) {
+ if (expectedParams[i].parameterArray) {
+ error = false;
+ break;
+ }
+ }
+ }
+ if (error) {
+ var e = Error.parameterCount();
+ e.popStackFrame();
+ return e;
+ }
+ return null;
+}
+Function._validateParameter = function Function$_validateParameter(param, expectedParam, paramName) {
+ var e,
+ expectedType = expectedParam.type,
+ expectedInteger = !!expectedParam.integer,
+ expectedDomElement = !!expectedParam.domElement,
+ mayBeNull = !!expectedParam.mayBeNull;
+ e = Function._validateParameterType(param, expectedType, expectedInteger, expectedDomElement, mayBeNull, paramName);
+ if (e) {
+ e.popStackFrame();
+ return e;
+ }
+ var expectedElementType = expectedParam.elementType,
+ elementMayBeNull = !!expectedParam.elementMayBeNull;
+ if (expectedType === Array && typeof(param) !== "undefined" && param !== null &&
+ (expectedElementType || !elementMayBeNull)) {
+ var expectedElementInteger = !!expectedParam.elementInteger,
+ expectedElementDomElement = !!expectedParam.elementDomElement;
+ for (var i=0; i < param.length; i++) {
+ var elem = param[i];
+ e = Function._validateParameterType(elem, expectedElementType,
+ expectedElementInteger, expectedElementDomElement, elementMayBeNull,
+ paramName + "[" + i + "]");
+ if (e) {
+ e.popStackFrame();
+ return e;
+ }
+ }
+ }
+ return null;
+}
+Function._validateParameterType = function Function$_validateParameterType(param, expectedType, expectedInteger, expectedDomElement, mayBeNull, paramName) {
+ var e, i;
+ if (typeof(param) === "undefined") {
+ if (mayBeNull) {
+ return null;
+ }
+ else {
+ e = Error.argumentUndefined(paramName);
+ e.popStackFrame();
+ return e;
+ }
+ }
+ if (param === null) {
+ if (mayBeNull) {
+ return null;
+ }
+ else {
+ e = Error.argumentNull(paramName);
+ e.popStackFrame();
+ return e;
+ }
+ }
+ if (expectedType && expectedType.__enum) {
+ if (typeof(param) !== 'number') {
+ e = Error.argumentType(paramName, Object.getType(param), expectedType);
+ e.popStackFrame();
+ return e;
+ }
+ if ((param % 1) === 0) {
+ var values = expectedType.prototype;
+ if (!expectedType.__flags || (param === 0)) {
+ for (i in values) {
+ if (values[i] === param) return null;
+ }
+ }
+ else {
+ var v = param;
+ for (i in values) {
+ var vali = values[i];
+ if (vali === 0) continue;
+ if ((vali & param) === vali) {
+ v -= vali;
+ }
+ if (v === 0) return null;
+ }
+ }
+ }
+ e = Error.argumentOutOfRange(paramName, param, String.format(Sys.Res.enumInvalidValue, param, expectedType.getName()));
+ e.popStackFrame();
+ return e;
+ }
+ if (expectedDomElement && (!Sys._isDomElement(param) || (param.nodeType === 3))) {
+ e = Error.argument(paramName, Sys.Res.argumentDomElement);
+ e.popStackFrame();
+ return e;
+ }
+ if (expectedType && !Sys._isInstanceOfType(expectedType, param)) {
+ e = Error.argumentType(paramName, Object.getType(param), expectedType);
+ e.popStackFrame();
+ return e;
+ }
+ if (expectedType === Number && expectedInteger) {
+ if ((param % 1) !== 0) {
+ e = Error.argumentOutOfRange(paramName, param, Sys.Res.argumentInteger);
+ e.popStackFrame();
+ return e;
+ }
+ }
+ return null;
+}
+
+Error.__typeName = 'Error';
+Error.__class = true;
+Error.create = function Error$create(message, errorInfo) {
+ /// <summary locid="M:J#Error.create" />
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <param name="errorInfo" optional="true" mayBeNull="true"></param>
+ /// <returns type="Error"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "message", type: String, mayBeNull: true, optional: true},
+ {name: "errorInfo", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var err = new Error(message);
+ err.message = message;
+ if (errorInfo) {
+ for (var v in errorInfo) {
+ err[v] = errorInfo[v];
+ }
+ }
+ err.popStackFrame();
+ return err;
+}
+Error.argument = function Error$argument(paramName, message) {
+ /// <summary locid="M:J#Error.argument" />
+ /// <param name="paramName" type="String" optional="true" mayBeNull="true"></param>
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "paramName", type: String, mayBeNull: true, optional: true},
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.ArgumentException: " + (message ? message : Sys.Res.argument);
+ if (paramName) {
+ displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
+ }
+ var err = Error.create(displayMessage, { name: "Sys.ArgumentException", paramName: paramName });
+ err.popStackFrame();
+ return err;
+}
+Error.argumentNull = function Error$argumentNull(paramName, message) {
+ /// <summary locid="M:J#Error.argumentNull" />
+ /// <param name="paramName" type="String" optional="true" mayBeNull="true"></param>
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "paramName", type: String, mayBeNull: true, optional: true},
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.ArgumentNullException: " + (message ? message : Sys.Res.argumentNull);
+ if (paramName) {
+ displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
+ }
+ var err = Error.create(displayMessage, { name: "Sys.ArgumentNullException", paramName: paramName });
+ err.popStackFrame();
+ return err;
+}
+Error.argumentOutOfRange = function Error$argumentOutOfRange(paramName, actualValue, message) {
+ /// <summary locid="M:J#Error.argumentOutOfRange" />
+ /// <param name="paramName" type="String" optional="true" mayBeNull="true"></param>
+ /// <param name="actualValue" optional="true" mayBeNull="true"></param>
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "paramName", type: String, mayBeNull: true, optional: true},
+ {name: "actualValue", mayBeNull: true, optional: true},
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.ArgumentOutOfRangeException: " + (message ? message : Sys.Res.argumentOutOfRange);
+ if (paramName) {
+ displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
+ }
+ if (typeof(actualValue) !== "undefined" && actualValue !== null) {
+ displayMessage += "\n" + String.format(Sys.Res.actualValue, actualValue);
+ }
+ var err = Error.create(displayMessage, {
+ name: "Sys.ArgumentOutOfRangeException",
+ paramName: paramName,
+ actualValue: actualValue
+ });
+ err.popStackFrame();
+ return err;
+}
+Error.argumentType = function Error$argumentType(paramName, actualType, expectedType, message) {
+ /// <summary locid="M:J#Error.argumentType" />
+ /// <param name="paramName" type="String" optional="true" mayBeNull="true"></param>
+ /// <param name="actualType" type="Type" optional="true" mayBeNull="true"></param>
+ /// <param name="expectedType" type="Type" optional="true" mayBeNull="true"></param>
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "paramName", type: String, mayBeNull: true, optional: true},
+ {name: "actualType", type: Type, mayBeNull: true, optional: true},
+ {name: "expectedType", type: Type, mayBeNull: true, optional: true},
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.ArgumentTypeException: ";
+ if (message) {
+ displayMessage += message;
+ }
+ else if (actualType && expectedType) {
+ displayMessage +=
+ String.format(Sys.Res.argumentTypeWithTypes, actualType.getName(), expectedType.getName());
+ }
+ else {
+ displayMessage += Sys.Res.argumentType;
+ }
+ if (paramName) {
+ displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
+ }
+ var err = Error.create(displayMessage, {
+ name: "Sys.ArgumentTypeException",
+ paramName: paramName,
+ actualType: actualType,
+ expectedType: expectedType
+ });
+ err.popStackFrame();
+ return err;
+}
+Error.argumentUndefined = function Error$argumentUndefined(paramName, message) {
+ /// <summary locid="M:J#Error.argumentUndefined" />
+ /// <param name="paramName" type="String" optional="true" mayBeNull="true"></param>
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "paramName", type: String, mayBeNull: true, optional: true},
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.ArgumentUndefinedException: " + (message ? message : Sys.Res.argumentUndefined);
+ if (paramName) {
+ displayMessage += "\n" + String.format(Sys.Res.paramName, paramName);
+ }
+ var err = Error.create(displayMessage, { name: "Sys.ArgumentUndefinedException", paramName: paramName });
+ err.popStackFrame();
+ return err;
+}
+Error.format = function Error$format(message) {
+ /// <summary locid="M:J#Error.format" />
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.FormatException: " + (message ? message : Sys.Res.format);
+ var err = Error.create(displayMessage, {name: 'Sys.FormatException'});
+ err.popStackFrame();
+ return err;
+}
+Error.invalidOperation = function Error$invalidOperation(message) {
+ /// <summary locid="M:J#Error.invalidOperation" />
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.InvalidOperationException: " + (message ? message : Sys.Res.invalidOperation);
+ var err = Error.create(displayMessage, {name: 'Sys.InvalidOperationException'});
+ err.popStackFrame();
+ return err;
+}
+Error.notImplemented = function Error$notImplemented(message) {
+ /// <summary locid="M:J#Error.notImplemented" />
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.NotImplementedException: " + (message ? message : Sys.Res.notImplemented);
+ var err = Error.create(displayMessage, {name: 'Sys.NotImplementedException'});
+ err.popStackFrame();
+ return err;
+}
+Error.parameterCount = function Error$parameterCount(message) {
+ /// <summary locid="M:J#Error.parameterCount" />
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "message", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var displayMessage = "Sys.ParameterCountException: " + (message ? message : Sys.Res.parameterCount);
+ var err = Error.create(displayMessage, {name: 'Sys.ParameterCountException'});
+ err.popStackFrame();
+ return err;
+}
+Error.prototype.popStackFrame = function Error$popStackFrame() {
+ /// <summary locid="M:J#checkParam" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (typeof(this.stack) === "undefined" || this.stack === null ||
+ typeof(this.fileName) === "undefined" || this.fileName === null ||
+ typeof(this.lineNumber) === "undefined" || this.lineNumber === null) {
+ return;
+ }
+ var stackFrames = this.stack.split("\n");
+ var currentFrame = stackFrames[0];
+ var pattern = this.fileName + ":" + this.lineNumber;
+ while(typeof(currentFrame) !== "undefined" &&
+ currentFrame !== null &&
+ currentFrame.indexOf(pattern) === -1) {
+ stackFrames.shift();
+ currentFrame = stackFrames[0];
+ }
+ var nextFrame = stackFrames[1];
+ if (typeof(nextFrame) === "undefined" || nextFrame === null) {
+ return;
+ }
+ var nextFrameParts = nextFrame.match(/@(.*):(\d+)$/);
+ if (typeof(nextFrameParts) === "undefined" || nextFrameParts === null) {
+ return;
+ }
+ this.fileName = nextFrameParts[1];
+ this.lineNumber = parseInt(nextFrameParts[2]);
+ stackFrames.shift();
+ this.stack = stackFrames.join("\n");
+}
+
+Object.__typeName = 'Object';
+Object.__class = true;
+Object.getType = function Object$getType(instance) {
+ /// <summary locid="M:J#Object.getType" />
+ /// <param name="instance"></param>
+ /// <returns type="Type"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "instance"}
+ ]);
+ if (e) throw e;
+ var ctor = instance.constructor;
+ if (!ctor || (typeof(ctor) !== "function") || !ctor.__typeName || (ctor.__typeName === 'Object')) {
+ return Object;
+ }
+ return ctor;
+}
+Object.getTypeName = function Object$getTypeName(instance) {
+ /// <summary locid="M:J#Object.getTypeName" />
+ /// <param name="instance"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "instance"}
+ ]);
+ if (e) throw e;
+ return Object.getType(instance).getName();
+}
+
+String.__typeName = 'String';
+String.__class = true;
+String.prototype.endsWith = function String$endsWith(suffix) {
+ /// <summary locid="M:J#String.endsWith" />
+ /// <param name="suffix" type="String"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "suffix", type: String}
+ ]);
+ if (e) throw e;
+ return (this.substr(this.length - suffix.length) === suffix);
+}
+String.prototype.startsWith = function String$startsWith(prefix) {
+ /// <summary locid="M:J#String.startsWith" />
+ /// <param name="prefix" type="String"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "prefix", type: String}
+ ]);
+ if (e) throw e;
+ return (this.substr(0, prefix.length) === prefix);
+}
+String.prototype.trim = function String$trim() {
+ /// <summary locid="M:J#String.trim" />
+ /// <returns type="String"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this.replace(/^\s+|\s+$/g, '');
+}
+String.prototype.trimEnd = function String$trimEnd() {
+ /// <summary locid="M:J#String.trimEnd" />
+ /// <returns type="String"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this.replace(/\s+$/, '');
+}
+String.prototype.trimStart = function String$trimStart() {
+ /// <summary locid="M:J#String.trimStart" />
+ /// <returns type="String"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this.replace(/^\s+/, '');
+}
+String.format = function String$format(format, args) {
+ /// <summary locid="M:J#String.format" />
+ /// <param name="format" type="String"></param>
+ /// <param name="args" parameterArray="true" mayBeNull="true"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "format", type: String},
+ {name: "args", mayBeNull: true, parameterArray: true}
+ ]);
+ if (e) throw e;
+ return String._toFormattedString(false, arguments);
+}
+String._toFormattedString = function String$_toFormattedString(useLocale, args) {
+ var result = '';
+ var format = args[0];
+ for (var i=0;;) {
+ var open = format.indexOf('{', i);
+ var close = format.indexOf('}', i);
+ if ((open < 0) && (close < 0)) {
+ result += format.slice(i);
+ break;
+ }
+ if ((close > 0) && ((close < open) || (open < 0))) {
+ if (format.charAt(close + 1) !== '}') {
+ throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
+ }
+ result += format.slice(i, close + 1);
+ i = close + 2;
+ continue;
+ }
+ result += format.slice(i, open);
+ i = open + 1;
+ if (format.charAt(i) === '{') {
+ result += '{';
+ i++;
+ continue;
+ }
+ if (close < 0) throw Error.argument('format', Sys.Res.stringFormatBraceMismatch);
+ var brace = format.substring(i, close);
+ var colonIndex = brace.indexOf(':');
+ var argNumber = parseInt((colonIndex < 0)? brace : brace.substring(0, colonIndex), 10) + 1;
+ if (isNaN(argNumber)) throw Error.argument('format', Sys.Res.stringFormatInvalid);
+ var argFormat = (colonIndex < 0)? '' : brace.substring(colonIndex + 1);
+ var arg = args[argNumber];
+ if (typeof(arg) === "undefined" || arg === null) {
+ arg = '';
+ }
+ if (arg.toFormattedString) {
+ result += arg.toFormattedString(argFormat);
+ }
+ else if (useLocale && arg.localeFormat) {
+ result += arg.localeFormat(argFormat);
+ }
+ else if (arg.format) {
+ result += arg.format(argFormat);
+ }
+ else
+ result += arg.toString();
+ i = close + 1;
+ }
+ return result;
+}
+
+Boolean.__typeName = 'Boolean';
+Boolean.__class = true;
+Boolean.parse = function Boolean$parse(value) {
+ /// <summary locid="M:J#Boolean.parse" />
+ /// <param name="value" type="String"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "value", type: String}
+ ], false);
+ if (e) throw e;
+ var v = value.trim().toLowerCase();
+ if (v === 'false') return false;
+ if (v === 'true') return true;
+ throw Error.argumentOutOfRange('value', value, Sys.Res.boolTrueOrFalse);
+}
+
+Date.__typeName = 'Date';
+Date.__class = true;
+
+Number.__typeName = 'Number';
+Number.__class = true;
+
+RegExp.__typeName = 'RegExp';
+RegExp.__class = true;
+
+if (!window) this.window = this;
+window.Type = Function;
+Type.__fullyQualifiedIdentifierRegExp = new RegExp("^[^.0-9 \\s|,;:&*=+\\-()\\[\\]{}^%#@!~\\n\\r\\t\\f\\\\]([^ \\s|,;:&*=+\\-()\\[\\]{}^%#@!~\\n\\r\\t\\f\\\\]*[^. \\s|,;:&*=+\\-()\\[\\]{}^%#@!~\\n\\r\\t\\f\\\\])?$", "i");
+Type.__identifierRegExp = new RegExp("^[^.0-9 \\s|,;:&*=+\\-()\\[\\]{}^%#@!~\\n\\r\\t\\f\\\\][^. \\s|,;:&*=+\\-()\\[\\]{}^%#@!~\\n\\r\\t\\f\\\\]*$", "i");
+Type.prototype.callBaseMethod = function Type$callBaseMethod(instance, name, baseArguments) {
+ /// <summary locid="M:J#Type.callBaseMethod" />
+ /// <param name="instance"></param>
+ /// <param name="name" type="String"></param>
+ /// <param name="baseArguments" type="Array" optional="true" mayBeNull="true" elementMayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "instance"},
+ {name: "name", type: String},
+ {name: "baseArguments", type: Array, mayBeNull: true, optional: true, elementMayBeNull: true}
+ ]);
+ if (e) throw e;
+ var baseMethod = Sys._getBaseMethod(this, instance, name);
+ if (!baseMethod) throw Error.invalidOperation(String.format(Sys.Res.methodNotFound, name));
+ if (!baseArguments) {
+ return baseMethod.apply(instance);
+ }
+ else {
+ return baseMethod.apply(instance, baseArguments);
+ }
+}
+Type.prototype.getBaseMethod = function Type$getBaseMethod(instance, name) {
+ /// <summary locid="M:J#Type.getBaseMethod" />
+ /// <param name="instance"></param>
+ /// <param name="name" type="String"></param>
+ /// <returns type="Function" mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "instance"},
+ {name: "name", type: String}
+ ]);
+ if (e) throw e;
+ return Sys._getBaseMethod(this, instance, name);
+}
+Type.prototype.getBaseType = function Type$getBaseType() {
+ /// <summary locid="M:J#Type.getBaseType" />
+ /// <returns type="Type" mayBeNull="true"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return (typeof(this.__baseType) === "undefined") ? null : this.__baseType;
+}
+Type.prototype.getInterfaces = function Type$getInterfaces() {
+ /// <summary locid="M:J#Type.getInterfaces" />
+ /// <returns type="Array" elementType="Type" mayBeNull="false" elementMayBeNull="false"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ var result = [];
+ var type = this;
+ while(type) {
+ var interfaces = type.__interfaces;
+ if (interfaces) {
+ for (var i = 0, l = interfaces.length; i < l; i++) {
+ var interfaceType = interfaces[i];
+ if (!Array.contains(result, interfaceType)) {
+ result[result.length] = interfaceType;
+ }
+ }
+ }
+ type = type.__baseType;
+ }
+ return result;
+}
+Type.prototype.getName = function Type$getName() {
+ /// <summary locid="M:J#Type.getName" />
+ /// <returns type="String"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return (typeof(this.__typeName) === "undefined") ? "" : this.__typeName;
+}
+Type.prototype.implementsInterface = function Type$implementsInterface(interfaceType) {
+ /// <summary locid="M:J#Type.implementsInterface" />
+ /// <param name="interfaceType" type="Type"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "interfaceType", type: Type}
+ ]);
+ if (e) throw e;
+ this.resolveInheritance();
+ var interfaceName = interfaceType.getName();
+ var cache = this.__interfaceCache;
+ if (cache) {
+ var cacheEntry = cache[interfaceName];
+ if (typeof(cacheEntry) !== 'undefined') return cacheEntry;
+ }
+ else {
+ cache = this.__interfaceCache = {};
+ }
+ var baseType = this;
+ while (baseType) {
+ var interfaces = baseType.__interfaces;
+ if (interfaces) {
+ if (Array.indexOf(interfaces, interfaceType) !== -1) {
+ return cache[interfaceName] = true;
+ }
+ }
+ baseType = baseType.__baseType;
+ }
+ return cache[interfaceName] = false;
+}
+Type.prototype.inheritsFrom = function Type$inheritsFrom(parentType) {
+ /// <summary locid="M:J#Type.inheritsFrom" />
+ /// <param name="parentType" type="Type"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "parentType", type: Type}
+ ]);
+ if (e) throw e;
+ this.resolveInheritance();
+ var baseType = this.__baseType;
+ while (baseType) {
+ if (baseType === parentType) {
+ return true;
+ }
+ baseType = baseType.__baseType;
+ }
+ return false;
+}
+Type.prototype.initializeBase = function Type$initializeBase(instance, baseArguments) {
+ /// <summary locid="M:J#Type.initializeBase" />
+ /// <param name="instance"></param>
+ /// <param name="baseArguments" type="Array" optional="true" mayBeNull="true" elementMayBeNull="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "instance"},
+ {name: "baseArguments", type: Array, mayBeNull: true, optional: true, elementMayBeNull: true}
+ ]);
+ if (e) throw e;
+ if (!Sys._isInstanceOfType(this, instance)) throw Error.argumentType('instance', Object.getType(instance), this);
+ this.resolveInheritance();
+ if (this.__baseType) {
+ if (!baseArguments) {
+ this.__baseType.apply(instance);
+ }
+ else {
+ this.__baseType.apply(instance, baseArguments);
+ }
+ }
+ return instance;
+}
+Type.prototype.isImplementedBy = function Type$isImplementedBy(instance) {
+ /// <summary locid="M:J#Type.isImplementedBy" />
+ /// <param name="instance" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "instance", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ if (typeof(instance) === "undefined" || instance === null) return false;
+ var instanceType = Object.getType(instance);
+ return !!(instanceType.implementsInterface && instanceType.implementsInterface(this));
+}
+Type.prototype.isInstanceOfType = function Type$isInstanceOfType(instance) {
+ /// <summary locid="M:J#Type.isInstanceOfType" />
+ /// <param name="instance" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "instance", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ return Sys._isInstanceOfType(this, instance);
+}
+Type.prototype.registerClass = function Type$registerClass(typeName, baseType, interfaceTypes) {
+ /// <summary locid="M:J#Type.registerClass" />
+ /// <param name="typeName" type="String"></param>
+ /// <param name="baseType" type="Type" optional="true" mayBeNull="true"></param>
+ /// <param name="interfaceTypes" parameterArray="true" type="Type"></param>
+ /// <returns type="Type"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "typeName", type: String},
+ {name: "baseType", type: Type, mayBeNull: true, optional: true},
+ {name: "interfaceTypes", type: Type, parameterArray: true}
+ ]);
+ if (e) throw e;
+ if (!Type.__fullyQualifiedIdentifierRegExp.test(typeName)) throw Error.argument('typeName', Sys.Res.notATypeName);
+ var parsedName;
+ try {
+ parsedName = eval(typeName);
+ }
+ catch(e) {
+ throw Error.argument('typeName', Sys.Res.argumentTypeName);
+ }
+ if (parsedName !== this) throw Error.argument('typeName', Sys.Res.badTypeName);
+ if (Sys.__registeredTypes[typeName]) throw Error.invalidOperation(String.format(Sys.Res.typeRegisteredTwice, typeName));
+ if ((arguments.length > 1) && (typeof(baseType) === 'undefined')) throw Error.argumentUndefined('baseType');
+ if (baseType && !baseType.__class) throw Error.argument('baseType', Sys.Res.baseNotAClass);
+ this.prototype.constructor = this;
+ this.__typeName = typeName;
+ this.__class = true;
+ if (baseType) {
+ this.__baseType = baseType;
+ this.__basePrototypePending = true;
+ }
+ Sys.__upperCaseTypes[typeName.toUpperCase()] = this;
+ if (interfaceTypes) {
+ this.__interfaces = [];
+ this.resolveInheritance();
+ for (var i = 2, l = arguments.length; i < l; i++) {
+ var interfaceType = arguments[i];
+ if (!interfaceType.__interface) throw Error.argument('interfaceTypes[' + (i - 2) + ']', Sys.Res.notAnInterface);
+ for (var methodName in interfaceType.prototype) {
+ var method = interfaceType.prototype[methodName];
+ if (!this.prototype[methodName]) {
+ this.prototype[methodName] = method;
+ }
+ }
+ this.__interfaces.push(interfaceType);
+ }
+ }
+ Sys.__registeredTypes[typeName] = true;
+ return this;
+}
+Type.prototype.registerInterface = function Type$registerInterface(typeName) {
+ /// <summary locid="M:J#Type.registerInterface" />
+ /// <param name="typeName" type="String"></param>
+ /// <returns type="Type"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "typeName", type: String}
+ ]);
+ if (e) throw e;
+ if (!Type.__fullyQualifiedIdentifierRegExp.test(typeName)) throw Error.argument('typeName', Sys.Res.notATypeName);
+ var parsedName;
+ try {
+ parsedName = eval(typeName);
+ }
+ catch(e) {
+ throw Error.argument('typeName', Sys.Res.argumentTypeName);
+ }
+ if (parsedName !== this) throw Error.argument('typeName', Sys.Res.badTypeName);
+ if (Sys.__registeredTypes[typeName]) throw Error.invalidOperation(String.format(Sys.Res.typeRegisteredTwice, typeName));
+ Sys.__upperCaseTypes[typeName.toUpperCase()] = this;
+ this.prototype.constructor = this;
+ this.__typeName = typeName;
+ this.__interface = true;
+ Sys.__registeredTypes[typeName] = true;
+ return this;
+}
+Type.prototype.resolveInheritance = function Type$resolveInheritance() {
+ /// <summary locid="M:J#Type.resolveInheritance" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this.__basePrototypePending) {
+ var baseType = this.__baseType;
+ baseType.resolveInheritance();
+ for (var memberName in baseType.prototype) {
+ var memberValue = baseType.prototype[memberName];
+ if (!this.prototype[memberName]) {
+ this.prototype[memberName] = memberValue;
+ }
+ }
+ delete this.__basePrototypePending;
+ }
+}
+Type.getRootNamespaces = function Type$getRootNamespaces() {
+ /// <summary locid="M:J#Type.getRootNamespaces" />
+ /// <returns type="Array"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return Array.clone(Sys.__rootNamespaces);
+}
+Type.isClass = function Type$isClass(type) {
+ /// <summary locid="M:J#Type.isClass" />
+ /// <param name="type" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "type", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ if ((typeof(type) === 'undefined') || (type === null)) return false;
+ return !!type.__class;
+}
+Type.isInterface = function Type$isInterface(type) {
+ /// <summary locid="M:J#Type.isInterface" />
+ /// <param name="type" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "type", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ if ((typeof(type) === 'undefined') || (type === null)) return false;
+ return !!type.__interface;
+}
+Type.isNamespace = function Type$isNamespace(object) {
+ /// <summary locid="M:J#Type.isNamespace" />
+ /// <param name="object" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "object", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ if ((typeof(object) === 'undefined') || (object === null)) return false;
+ return !!object.__namespace;
+}
+Type.parse = function Type$parse(typeName, ns) {
+ /// <summary locid="M:J#Type.parse" />
+ /// <param name="typeName" type="String" mayBeNull="true"></param>
+ /// <param name="ns" optional="true" mayBeNull="true"></param>
+ /// <returns type="Type" mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "typeName", type: String, mayBeNull: true},
+ {name: "ns", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var fn;
+ if (ns) {
+ fn = Sys.__upperCaseTypes[ns.getName().toUpperCase() + '.' + typeName.toUpperCase()];
+ return fn || null;
+ }
+ if (!typeName) return null;
+ if (!Type.__htClasses) {
+ Type.__htClasses = {};
+ }
+ fn = Type.__htClasses[typeName];
+ if (!fn) {
+ fn = eval(typeName);
+ if (typeof(fn) !== 'function') throw Error.argument('typeName', Sys.Res.notATypeName);
+ Type.__htClasses[typeName] = fn;
+ }
+ return fn;
+}
+Type.registerNamespace = function Type$registerNamespace(namespacePath) {
+ /// <summary locid="M:J#Type.registerNamespace" />
+ /// <param name="namespacePath" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "namespacePath", type: String}
+ ]);
+ if (e) throw e;
+ Type._registerNamespace(namespacePath);
+}
+Type._registerNamespace = function Type$_registerNamespace(namespacePath) {
+ if (!Type.__fullyQualifiedIdentifierRegExp.test(namespacePath)) throw Error.argument('namespacePath', Sys.Res.invalidNameSpace);
+ var rootObject = window;
+ var namespaceParts = namespacePath.split('.');
+ for (var i = 0; i < namespaceParts.length; i++) {
+ var currentPart = namespaceParts[i];
+ var ns = rootObject[currentPart];
+ var nsType = typeof(ns);
+ if ((nsType !== "undefined") && (ns !== null)) {
+ if (nsType === "function") {
+ throw Error.invalidOperation(String.format(Sys.Res.namespaceContainsClass, namespaceParts.splice(0, i + 1).join('.')));
+ }
+ if ((typeof(ns) !== "object") || (ns instanceof Array)) {
+ throw Error.invalidOperation(String.format(Sys.Res.namespaceContainsNonObject, namespaceParts.splice(0, i + 1).join('.')));
+ }
+ }
+ if (!ns) {
+ ns = rootObject[currentPart] = {};
+ }
+ if (!ns.__namespace) {
+ if ((i === 0) && (namespacePath !== "Sys")) {
+ Sys.__rootNamespaces[Sys.__rootNamespaces.length] = ns;
+ }
+ ns.__namespace = true;
+ ns.__typeName = namespaceParts.slice(0, i + 1).join('.');
+ var parsedName;
+ try {
+ parsedName = eval(ns.__typeName);
+ }
+ catch(e) {
+ parsedName = null;
+ }
+ if (parsedName !== ns) {
+ delete rootObject[currentPart];
+ throw Error.argument('namespacePath', Sys.Res.invalidNameSpace);
+ }
+ ns.getName = function ns$getName() {return this.__typeName;}
+ }
+ rootObject = ns;
+ }
+}
+Type._checkDependency = function Type$_checkDependency(dependency, featureName) {
+ var scripts = Type._registerScript._scripts, isDependent = (scripts ? (!!scripts[dependency]) : false);
+ if ((typeof(featureName) !== 'undefined') && !isDependent) {
+ throw Error.invalidOperation(String.format(Sys.Res.requiredScriptReferenceNotIncluded,
+ featureName, dependency));
+ }
+ return isDependent;
+}
+Type._registerScript = function Type$_registerScript(scriptName, dependencies) {
+ var scripts = Type._registerScript._scripts;
+ if (!scripts) {
+ Type._registerScript._scripts = scripts = {};
+ }
+ if (scripts[scriptName]) {
+ throw Error.invalidOperation(String.format(Sys.Res.scriptAlreadyLoaded, scriptName));
+ }
+ scripts[scriptName] = true;
+ if (dependencies) {
+ for (var i = 0, l = dependencies.length; i < l; i++) {
+ var dependency = dependencies[i];
+ if (!Type._checkDependency(dependency)) {
+ throw Error.invalidOperation(String.format(Sys.Res.scriptDependencyNotFound, scriptName, dependency));
+ }
+ }
+ }
+}
+Type._registerNamespace("Sys");
+Sys.__upperCaseTypes = {};
+Sys.__rootNamespaces = [Sys];
+Sys.__registeredTypes = {};
+Sys._isInstanceOfType = function Sys$_isInstanceOfType(type, instance) {
+ if (typeof(instance) === "undefined" || instance === null) return false;
+ if (instance instanceof type) return true;
+ var instanceType = Object.getType(instance);
+ return !!(instanceType === type) ||
+ (instanceType.inheritsFrom && instanceType.inheritsFrom(type)) ||
+ (instanceType.implementsInterface && instanceType.implementsInterface(type));
+}
+Sys._getBaseMethod = function Sys$_getBaseMethod(type, instance, name) {
+ if (!Sys._isInstanceOfType(type, instance)) throw Error.argumentType('instance', Object.getType(instance), type);
+ var baseType = type.getBaseType();
+ if (baseType) {
+ var baseMethod = baseType.prototype[name];
+ return (baseMethod instanceof Function) ? baseMethod : null;
+ }
+ return null;
+}
+Sys._isDomElement = function Sys$_isDomElement(obj) {
+ var val = false;
+ if (typeof (obj.nodeType) !== 'number') {
+ var doc = obj.ownerDocument || obj.document || obj;
+ if (doc != obj) {
+ var w = doc.defaultView || doc.parentWindow;
+ val = (w != obj);
+ }
+ else {
+ val = (typeof (doc.body) === 'undefined');
+ }
+ }
+ return !val;
+}
+
+Array.__typeName = 'Array';
+Array.__class = true;
+Array.add = Array.enqueue = function Array$enqueue(array, item) {
+ /// <summary locid="M:J#Array.enqueue" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <param name="item" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true},
+ {name: "item", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ array[array.length] = item;
+}
+Array.addRange = function Array$addRange(array, items) {
+ /// <summary locid="M:J#Array.addRange" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <param name="items" type="Array" elementMayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true},
+ {name: "items", type: Array, elementMayBeNull: true}
+ ]);
+ if (e) throw e;
+ array.push.apply(array, items);
+}
+Array.clear = function Array$clear(array) {
+ /// <summary locid="M:J#Array.clear" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true}
+ ]);
+ if (e) throw e;
+ array.length = 0;
+}
+Array.clone = function Array$clone(array) {
+ /// <summary locid="M:J#Array.clone" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <returns type="Array" elementMayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true}
+ ]);
+ if (e) throw e;
+ if (array.length === 1) {
+ return [array[0]];
+ }
+ else {
+ return Array.apply(null, array);
+ }
+}
+Array.contains = function Array$contains(array, item) {
+ /// <summary locid="M:J#Array.contains" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <param name="item" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true},
+ {name: "item", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ return (Sys._indexOf(array, item) >= 0);
+}
+Array.dequeue = function Array$dequeue(array) {
+ /// <summary locid="M:J#Array.dequeue" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <returns mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true}
+ ]);
+ if (e) throw e;
+ return array.shift();
+}
+Array.forEach = function Array$forEach(array, method, instance) {
+ /// <summary locid="M:J#Array.forEach" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <param name="method" type="Function"></param>
+ /// <param name="instance" optional="true" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true},
+ {name: "method", type: Function},
+ {name: "instance", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ for (var i = 0, l = array.length; i < l; i++) {
+ var elt = array[i];
+ if (typeof(elt) !== 'undefined') method.call(instance, elt, i, array);
+ }
+}
+Array.indexOf = function Array$indexOf(array, item, start) {
+ /// <summary locid="M:J#Array.indexOf" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <param name="item" optional="true" mayBeNull="true"></param>
+ /// <param name="start" optional="true" mayBeNull="true"></param>
+ /// <returns type="Number"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true},
+ {name: "item", mayBeNull: true, optional: true},
+ {name: "start", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ return Sys._indexOf(array, item, start);
+}
+Array.insert = function Array$insert(array, index, item) {
+ /// <summary locid="M:J#Array.insert" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <param name="index" mayBeNull="true"></param>
+ /// <param name="item" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true},
+ {name: "index", mayBeNull: true},
+ {name: "item", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ array.splice(index, 0, item);
+}
+Array.parse = function Array$parse(value) {
+ /// <summary locid="M:J#Array.parse" />
+ /// <param name="value" type="String" mayBeNull="true"></param>
+ /// <returns type="Array" elementMayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "value", type: String, mayBeNull: true}
+ ]);
+ if (e) throw e;
+ if (!value) return [];
+ var v = eval(value);
+ if (!Array.isInstanceOfType(v)) throw Error.argument('value', Sys.Res.arrayParseBadFormat);
+ return v;
+}
+Array.remove = function Array$remove(array, item) {
+ /// <summary locid="M:J#Array.remove" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <param name="item" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true},
+ {name: "item", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ var index = Sys._indexOf(array, item);
+ if (index >= 0) {
+ array.splice(index, 1);
+ }
+ return (index >= 0);
+}
+Array.removeAt = function Array$removeAt(array, index) {
+ /// <summary locid="M:J#Array.removeAt" />
+ /// <param name="array" type="Array" elementMayBeNull="true"></param>
+ /// <param name="index" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "array", type: Array, elementMayBeNull: true},
+ {name: "index", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ array.splice(index, 1);
+}
+Sys._indexOf = function Sys$_indexOf(array, item, start) {
+ if (typeof(item) === "undefined") return -1;
+ var length = array.length;
+ if (length !== 0) {
+ start = start - 0;
+ if (isNaN(start)) {
+ start = 0;
+ }
+ else {
+ if (isFinite(start)) {
+ start = start - (start % 1);
+ }
+ if (start < 0) {
+ start = Math.max(0, length + start);
+ }
+ }
+ for (var i = start; i < length; i++) {
+ if ((typeof(array[i]) !== "undefined") && (array[i] === item)) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+Type._registerScript._scripts = {
+ "MicrosoftAjaxCore.js": true,
+ "MicrosoftAjaxGlobalization.js": true,
+ "MicrosoftAjaxSerialization.js": true,
+ "MicrosoftAjaxComponentModel.js": true,
+ "MicrosoftAjaxHistory.js": true,
+ "MicrosoftAjaxNetwork.js" : true,
+ "MicrosoftAjaxWebServices.js": true };
+
+Sys.IDisposable = function Sys$IDisposable() {
+ throw Error.notImplemented();
+}
+ function Sys$IDisposable$dispose() {
+ throw Error.notImplemented();
+ }
+Sys.IDisposable.prototype = {
+ dispose: Sys$IDisposable$dispose
+}
+Sys.IDisposable.registerInterface('Sys.IDisposable');
+
+Sys.StringBuilder = function Sys$StringBuilder(initialText) {
+ /// <summary locid="M:J#Sys.StringBuilder.#ctor" />
+ /// <param name="initialText" optional="true" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "initialText", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ this._parts = (typeof(initialText) !== 'undefined' && initialText !== null && initialText !== '') ?
+ [initialText.toString()] : [];
+ this._value = {};
+ this._len = 0;
+}
+ function Sys$StringBuilder$append(text) {
+ /// <summary locid="M:J#Sys.StringBuilder.append" />
+ /// <param name="text" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "text", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ this._parts[this._parts.length] = text;
+ }
+ function Sys$StringBuilder$appendLine(text) {
+ /// <summary locid="M:J#Sys.StringBuilder.appendLine" />
+ /// <param name="text" optional="true" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "text", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ this._parts[this._parts.length] =
+ ((typeof(text) === 'undefined') || (text === null) || (text === '')) ?
+ '\r\n' : text + '\r\n';
+ }
+ function Sys$StringBuilder$clear() {
+ /// <summary locid="M:J#Sys.StringBuilder.clear" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ this._parts = [];
+ this._value = {};
+ this._len = 0;
+ }
+ function Sys$StringBuilder$isEmpty() {
+ /// <summary locid="M:J#Sys.StringBuilder.isEmpty" />
+ /// <returns type="Boolean"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this._parts.length === 0) return true;
+ return this.toString() === '';
+ }
+ function Sys$StringBuilder$toString(separator) {
+ /// <summary locid="M:J#Sys.StringBuilder.toString" />
+ /// <param name="separator" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "separator", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ separator = separator || '';
+ var parts = this._parts;
+ if (this._len !== parts.length) {
+ this._value = {};
+ this._len = parts.length;
+ }
+ var val = this._value;
+ if (typeof(val[separator]) === 'undefined') {
+ if (separator !== '') {
+ for (var i = 0; i < parts.length;) {
+ if ((typeof(parts[i]) === 'undefined') || (parts[i] === '') || (parts[i] === null)) {
+ parts.splice(i, 1);
+ }
+ else {
+ i++;
+ }
+ }
+ }
+ val[separator] = this._parts.join(separator);
+ }
+ return val[separator];
+ }
+Sys.StringBuilder.prototype = {
+ append: Sys$StringBuilder$append,
+ appendLine: Sys$StringBuilder$appendLine,
+ clear: Sys$StringBuilder$clear,
+ isEmpty: Sys$StringBuilder$isEmpty,
+ toString: Sys$StringBuilder$toString
+}
+Sys.StringBuilder.registerClass('Sys.StringBuilder');
+
+Sys.Browser = {};
+Sys.Browser.InternetExplorer = {};
+Sys.Browser.Firefox = {};
+Sys.Browser.Safari = {};
+Sys.Browser.Opera = {};
+Sys.Browser.agent = null;
+Sys.Browser.hasDebuggerStatement = false;
+Sys.Browser.name = navigator.appName;
+Sys.Browser.version = parseFloat(navigator.appVersion);
+Sys.Browser.documentMode = 0;
+if (navigator.userAgent.indexOf(' MSIE ') > -1) {
+ Sys.Browser.agent = Sys.Browser.InternetExplorer;
+ Sys.Browser.version = parseFloat(navigator.userAgent.match(/MSIE (\d+\.\d+)/)[1]);
+ if (Sys.Browser.version >= 8) {
+ if (document.documentMode >= 7) {
+ Sys.Browser.documentMode = document.documentMode;
+ }
+ }
+ Sys.Browser.hasDebuggerStatement = true;
+}
+else if (navigator.userAgent.indexOf(' Firefox/') > -1) {
+ Sys.Browser.agent = Sys.Browser.Firefox;
+ Sys.Browser.version = parseFloat(navigator.userAgent.match(/ Firefox\/(\d+\.\d+)/)[1]);
+ Sys.Browser.name = 'Firefox';
+ Sys.Browser.hasDebuggerStatement = true;
+}
+else if (navigator.userAgent.indexOf(' AppleWebKit/') > -1) {
+ Sys.Browser.agent = Sys.Browser.Safari;
+ Sys.Browser.version = parseFloat(navigator.userAgent.match(/ AppleWebKit\/(\d+(\.\d+)?)/)[1]);
+ Sys.Browser.name = 'Safari';
+}
+else if (navigator.userAgent.indexOf('Opera/') > -1) {
+ Sys.Browser.agent = Sys.Browser.Opera;
+}
+
+Sys.EventArgs = function Sys$EventArgs() {
+ /// <summary locid="M:J#Sys.EventArgs.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+}
+Sys.EventArgs.registerClass('Sys.EventArgs');
+Sys.EventArgs.Empty = new Sys.EventArgs();
+
+Sys.CancelEventArgs = function Sys$CancelEventArgs() {
+ /// <summary locid="M:J#Sys.CancelEventArgs.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ Sys.CancelEventArgs.initializeBase(this);
+ this._cancel = false;
+}
+ function Sys$CancelEventArgs$get_cancel() {
+ /// <value type="Boolean" locid="P:J#Sys.CancelEventArgs.cancel"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._cancel;
+ }
+ function Sys$CancelEventArgs$set_cancel(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Boolean}]);
+ if (e) throw e;
+ this._cancel = value;
+ }
+Sys.CancelEventArgs.prototype = {
+ get_cancel: Sys$CancelEventArgs$get_cancel,
+ set_cancel: Sys$CancelEventArgs$set_cancel
+}
+Sys.CancelEventArgs.registerClass('Sys.CancelEventArgs', Sys.EventArgs);
+Type.registerNamespace('Sys.UI');
+
+Sys._Debug = function Sys$_Debug() {
+ /// <summary locid="M:J#Sys.Debug.#ctor" />
+ /// <field name="isDebug" type="Boolean" locid="F:J#Sys.Debug.isDebug"></field>
+ if (arguments.length !== 0) throw Error.parameterCount();
+}
+ function Sys$_Debug$_appendConsole(text) {
+ if ((typeof(Debug) !== 'undefined') && Debug.writeln) {
+ Debug.writeln(text);
+ }
+ if (window.console && window.console.log) {
+ window.console.log(text);
+ }
+ if (window.opera) {
+ window.opera.postError(text);
+ }
+ if (window.debugService) {
+ window.debugService.trace(text);
+ }
+ }
+ function Sys$_Debug$_appendTrace(text) {
+ var traceElement = document.getElementById('TraceConsole');
+ if (traceElement && (traceElement.tagName.toUpperCase() === 'TEXTAREA')) {
+ traceElement.value += text + '\n';
+ }
+ }
+ function Sys$_Debug$assert(condition, message, displayCaller) {
+ /// <summary locid="M:J#Sys.Debug.assert" />
+ /// <param name="condition" type="Boolean"></param>
+ /// <param name="message" type="String" optional="true" mayBeNull="true"></param>
+ /// <param name="displayCaller" type="Boolean" optional="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "condition", type: Boolean},
+ {name: "message", type: String, mayBeNull: true, optional: true},
+ {name: "displayCaller", type: Boolean, optional: true}
+ ]);
+ if (e) throw e;
+ if (!condition) {
+ message = (displayCaller && this.assert.caller) ?
+ String.format(Sys.Res.assertFailedCaller, message, this.assert.caller) :
+ String.format(Sys.Res.assertFailed, message);
+ if (confirm(String.format(Sys.Res.breakIntoDebugger, message))) {
+ this.fail(message);
+ }
+ }
+ }
+ function Sys$_Debug$clearTrace() {
+ /// <summary locid="M:J#Sys.Debug.clearTrace" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ var traceElement = document.getElementById('TraceConsole');
+ if (traceElement && (traceElement.tagName.toUpperCase() === 'TEXTAREA')) {
+ traceElement.value = '';
+ }
+ }
+ function Sys$_Debug$fail(message) {
+ /// <summary locid="M:J#Sys.Debug.fail" />
+ /// <param name="message" type="String" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "message", type: String, mayBeNull: true}
+ ]);
+ if (e) throw e;
+ this._appendConsole(message);
+ if (Sys.Browser.hasDebuggerStatement) {
+ eval('debugger');
+ }
+ }
+ function Sys$_Debug$trace(text) {
+ /// <summary locid="M:J#Sys.Debug.trace" />
+ /// <param name="text"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "text"}
+ ]);
+ if (e) throw e;
+ this._appendConsole(text);
+ this._appendTrace(text);
+ }
+ function Sys$_Debug$traceDump(object, name) {
+ /// <summary locid="M:J#Sys.Debug.traceDump" />
+ /// <param name="object" mayBeNull="true"></param>
+ /// <param name="name" type="String" mayBeNull="true" optional="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "object", mayBeNull: true},
+ {name: "name", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var text = this._traceDump(object, name, true);
+ }
+ function Sys$_Debug$_traceDump(object, name, recursive, indentationPadding, loopArray) {
+ name = name? name : 'traceDump';
+ indentationPadding = indentationPadding? indentationPadding : '';
+ if (object === null) {
+ this.trace(indentationPadding + name + ': null');
+ return;
+ }
+ switch(typeof(object)) {
+ case 'undefined':
+ this.trace(indentationPadding + name + ': Undefined');
+ break;
+ case 'number': case 'string': case 'boolean':
+ this.trace(indentationPadding + name + ': ' + object);
+ break;
+ default:
+ if (Date.isInstanceOfType(object) || RegExp.isInstanceOfType(object)) {
+ this.trace(indentationPadding + name + ': ' + object.toString());
+ break;
+ }
+ if (!loopArray) {
+ loopArray = [];
+ }
+ else if (Array.contains(loopArray, object)) {
+ this.trace(indentationPadding + name + ': ...');
+ return;
+ }
+ Array.add(loopArray, object);
+ if ((object == window) || (object === document) ||
+ (window.HTMLElement && (object instanceof HTMLElement)) ||
+ (typeof(object.nodeName) === 'string')) {
+ var tag = object.tagName? object.tagName : 'DomElement';
+ if (object.id) {
+ tag += ' - ' + object.id;
+ }
+ this.trace(indentationPadding + name + ' {' + tag + '}');
+ }
+ else {
+ var typeName = Object.getTypeName(object);
+ this.trace(indentationPadding + name + (typeof(typeName) === 'string' ? ' {' + typeName + '}' : ''));
+ if ((indentationPadding === '') || recursive) {
+ indentationPadding += " ";
+ var i, length, properties, p, v;
+ if (Array.isInstanceOfType(object)) {
+ length = object.length;
+ for (i = 0; i < length; i++) {
+ this._traceDump(object[i], '[' + i + ']', recursive, indentationPadding, loopArray);
+ }
+ }
+ else {
+ for (p in object) {
+ v = object[p];
+ if (!Function.isInstanceOfType(v)) {
+ this._traceDump(v, p, recursive, indentationPadding, loopArray);
+ }
+ }
+ }
+ }
+ }
+ Array.remove(loopArray, object);
+ }
+ }
+Sys._Debug.prototype = {
+ _appendConsole: Sys$_Debug$_appendConsole,
+ _appendTrace: Sys$_Debug$_appendTrace,
+ assert: Sys$_Debug$assert,
+ clearTrace: Sys$_Debug$clearTrace,
+ fail: Sys$_Debug$fail,
+ trace: Sys$_Debug$trace,
+ traceDump: Sys$_Debug$traceDump,
+ _traceDump: Sys$_Debug$_traceDump
+}
+Sys._Debug.registerClass('Sys._Debug');
+Sys.Debug = new Sys._Debug();
+ Sys.Debug.isDebug = true;
+
+function Sys$Enum$parse(value, ignoreCase) {
+ /// <summary locid="M:J#Sys.Enum.parse" />
+ /// <param name="value" type="String"></param>
+ /// <param name="ignoreCase" type="Boolean" optional="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "value", type: String},
+ {name: "ignoreCase", type: Boolean, optional: true}
+ ]);
+ if (e) throw e;
+ var values, parsed, val;
+ if (ignoreCase) {
+ values = this.__lowerCaseValues;
+ if (!values) {
+ this.__lowerCaseValues = values = {};
+ var prototype = this.prototype;
+ for (var name in prototype) {
+ values[name.toLowerCase()] = prototype[name];
+ }
+ }
+ }
+ else {
+ values = this.prototype;
+ }
+ if (!this.__flags) {
+ val = (ignoreCase ? value.toLowerCase() : value);
+ parsed = values[val.trim()];
+ if (typeof(parsed) !== 'number') throw Error.argument('value', String.format(Sys.Res.enumInvalidValue, value, this.__typeName));
+ return parsed;
+ }
+ else {
+ var parts = (ignoreCase ? value.toLowerCase() : value).split(',');
+ var v = 0;
+ for (var i = parts.length - 1; i >= 0; i--) {
+ var part = parts[i].trim();
+ parsed = values[part];
+ if (typeof(parsed) !== 'number') throw Error.argument('value', String.format(Sys.Res.enumInvalidValue, value.split(',')[i].trim(), this.__typeName));
+ v |= parsed;
+ }
+ return v;
+ }
+}
+function Sys$Enum$toString(value) {
+ /// <summary locid="M:J#Sys.Enum.toString" />
+ /// <param name="value" optional="true" mayBeNull="true"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "value", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ if ((typeof(value) === 'undefined') || (value === null)) return this.__string;
+ if ((typeof(value) != 'number') || ((value % 1) !== 0)) throw Error.argumentType('value', Object.getType(value), this);
+ var values = this.prototype;
+ var i;
+ if (!this.__flags || (value === 0)) {
+ for (i in values) {
+ if (values[i] === value) {
+ return i;
+ }
+ }
+ }
+ else {
+ var sorted = this.__sortedValues;
+ if (!sorted) {
+ sorted = [];
+ for (i in values) {
+ sorted[sorted.length] = {key: i, value: values[i]};
+ }
+ sorted.sort(function(a, b) {
+ return a.value - b.value;
+ });
+ this.__sortedValues = sorted;
+ }
+ var parts = [];
+ var v = value;
+ for (i = sorted.length - 1; i >= 0; i--) {
+ var kvp = sorted[i];
+ var vali = kvp.value;
+ if (vali === 0) continue;
+ if ((vali & value) === vali) {
+ parts[parts.length] = kvp.key;
+ v -= vali;
+ if (v === 0) break;
+ }
+ }
+ if (parts.length && v === 0) return parts.reverse().join(', ');
+ }
+ throw Error.argumentOutOfRange('value', value, String.format(Sys.Res.enumInvalidValue, value, this.__typeName));
+}
+Type.prototype.registerEnum = function Type$registerEnum(name, flags) {
+ /// <summary locid="M:J#Sys.UI.LineType.#ctor" />
+ /// <param name="name" type="String"></param>
+ /// <param name="flags" type="Boolean" optional="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "name", type: String},
+ {name: "flags", type: Boolean, optional: true}
+ ]);
+ if (e) throw e;
+ if (!Type.__fullyQualifiedIdentifierRegExp.test(name)) throw Error.argument('name', Sys.Res.notATypeName);
+ var parsedName;
+ try {
+ parsedName = eval(name);
+ }
+ catch(e) {
+ throw Error.argument('name', Sys.Res.argumentTypeName);
+ }
+ if (parsedName !== this) throw Error.argument('name', Sys.Res.badTypeName);
+ if (Sys.__registeredTypes[name]) throw Error.invalidOperation(String.format(Sys.Res.typeRegisteredTwice, name));
+ for (var j in this.prototype) {
+ var val = this.prototype[j];
+ if (!Type.__identifierRegExp.test(j)) throw Error.invalidOperation(String.format(Sys.Res.enumInvalidValueName, j));
+ if (typeof(val) !== 'number' || (val % 1) !== 0) throw Error.invalidOperation(Sys.Res.enumValueNotInteger);
+ if (typeof(this[j]) !== 'undefined') throw Error.invalidOperation(String.format(Sys.Res.enumReservedName, j));
+ }
+ Sys.__upperCaseTypes[name.toUpperCase()] = this;
+ for (var i in this.prototype) {
+ this[i] = this.prototype[i];
+ }
+ this.__typeName = name;
+ this.parse = Sys$Enum$parse;
+ this.__string = this.toString();
+ this.toString = Sys$Enum$toString;
+ this.__flags = flags;
+ this.__enum = true;
+ Sys.__registeredTypes[name] = true;
+}
+Type.isEnum = function Type$isEnum(type) {
+ /// <summary locid="M:J#Type.isEnum" />
+ /// <param name="type" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "type", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ if ((typeof(type) === 'undefined') || (type === null)) return false;
+ return !!type.__enum;
+}
+Type.isFlags = function Type$isFlags(type) {
+ /// <summary locid="M:J#Type.isFlags" />
+ /// <param name="type" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "type", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ if ((typeof(type) === 'undefined') || (type === null)) return false;
+ return !!type.__flags;
+}
+Sys.CollectionChange = function Sys$CollectionChange(action, newItems, newStartingIndex, oldItems, oldStartingIndex) {
+ /// <summary locid="M:J#Sys.CollectionChange.#ctor" />
+ /// <param name="action" type="Sys.NotifyCollectionChangedAction"></param>
+ /// <param name="newItems" optional="true" mayBeNull="true"></param>
+ /// <param name="newStartingIndex" type="Number" integer="true" optional="true" mayBeNull="true"></param>
+ /// <param name="oldItems" optional="true" mayBeNull="true"></param>
+ /// <param name="oldStartingIndex" type="Number" integer="true" optional="true" mayBeNull="true"></param>
+ /// <field name="action" type="Sys.NotifyCollectionChangedAction" locid="F:J#Sys.CollectionChange.action"></field>
+ /// <field name="newItems" type="Array" mayBeNull="true" elementMayBeNull="true" locid="F:J#Sys.CollectionChange.newItems"></field>
+ /// <field name="newStartingIndex" type="Number" integer="true" locid="F:J#Sys.CollectionChange.newStartingIndex"></field>
+ /// <field name="oldItems" type="Array" mayBeNull="true" elementMayBeNull="true" locid="F:J#Sys.CollectionChange.oldItems"></field>
+ /// <field name="oldStartingIndex" type="Number" integer="true" locid="F:J#Sys.CollectionChange.oldStartingIndex"></field>
+ var e = Function._validateParams(arguments, [
+ {name: "action", type: Sys.NotifyCollectionChangedAction},
+ {name: "newItems", mayBeNull: true, optional: true},
+ {name: "newStartingIndex", type: Number, mayBeNull: true, integer: true, optional: true},
+ {name: "oldItems", mayBeNull: true, optional: true},
+ {name: "oldStartingIndex", type: Number, mayBeNull: true, integer: true, optional: true}
+ ]);
+ if (e) throw e;
+ this.action = action;
+ if (newItems) {
+ if (!(newItems instanceof Array)) {
+ newItems = [newItems];
+ }
+ }
+ this.newItems = newItems || null;
+ if (typeof newStartingIndex !== "number") {
+ newStartingIndex = -1;
+ }
+ this.newStartingIndex = newStartingIndex;
+ if (oldItems) {
+ if (!(oldItems instanceof Array)) {
+ oldItems = [oldItems];
+ }
+ }
+ this.oldItems = oldItems || null;
+ if (typeof oldStartingIndex !== "number") {
+ oldStartingIndex = -1;
+ }
+ this.oldStartingIndex = oldStartingIndex;
+}
+Sys.CollectionChange.registerClass("Sys.CollectionChange");
+Sys.NotifyCollectionChangedAction = function Sys$NotifyCollectionChangedAction() {
+ /// <summary locid="M:J#Sys.NotifyCollectionChangedAction.#ctor" />
+ /// <field name="add" type="Number" integer="true" static="true" locid="F:J#Sys.NotifyCollectionChangedAction.add"></field>
+ /// <field name="remove" type="Number" integer="true" static="true" locid="F:J#Sys.NotifyCollectionChangedAction.remove"></field>
+ /// <field name="reset" type="Number" integer="true" static="true" locid="F:J#Sys.NotifyCollectionChangedAction.reset"></field>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+}
+Sys.NotifyCollectionChangedAction.prototype = {
+ add: 0,
+ remove: 1,
+ reset: 2
+}
+Sys.NotifyCollectionChangedAction.registerEnum('Sys.NotifyCollectionChangedAction');
+Sys.NotifyCollectionChangedEventArgs = function Sys$NotifyCollectionChangedEventArgs(changes) {
+ /// <summary locid="M:J#Sys.NotifyCollectionChangedEventArgs.#ctor" />
+ /// <param name="changes" type="Array" elementType="Sys.CollectionChange"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "changes", type: Array, elementType: Sys.CollectionChange}
+ ]);
+ if (e) throw e;
+ this._changes = changes;
+ Sys.NotifyCollectionChangedEventArgs.initializeBase(this);
+}
+ function Sys$NotifyCollectionChangedEventArgs$get_changes() {
+ /// <value type="Array" elementType="Sys.CollectionChange" locid="P:J#Sys.NotifyCollectionChangedEventArgs.changes"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._changes || [];
+ }
+Sys.NotifyCollectionChangedEventArgs.prototype = {
+ get_changes: Sys$NotifyCollectionChangedEventArgs$get_changes
+}
+Sys.NotifyCollectionChangedEventArgs.registerClass("Sys.NotifyCollectionChangedEventArgs", Sys.EventArgs);
+Sys.Observer = function Sys$Observer() {
+ throw Error.invalidOperation();
+}
+Sys.Observer.registerClass("Sys.Observer");
+Sys.Observer.makeObservable = function Sys$Observer$makeObservable(target) {
+ /// <summary locid="M:J#Sys.Observer.makeObservable" />
+ /// <param name="target" mayBeNull="false"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "target"}
+ ]);
+ if (e) throw e;
+ var isArray = target instanceof Array,
+ o = Sys.Observer;
+ Sys.Observer._ensureObservable(target);
+ if (target.setValue === o._observeMethods.setValue) return target;
+ o._addMethods(target, o._observeMethods);
+ if (isArray) {
+ o._addMethods(target, o._arrayMethods);
+ }
+ return target;
+}
+Sys.Observer._ensureObservable = function Sys$Observer$_ensureObservable(target) {
+ var type = typeof target;
+ if ((type === "string") || (type === "number") || (type === "boolean") || (type === "date")) {
+ throw Error.invalidOperation(String.format(Sys.Res.notObservable, type));
+ }
+}
+Sys.Observer._addMethods = function Sys$Observer$_addMethods(target, methods) {
+ for (var m in methods) {
+ if (target[m] && (target[m] !== methods[m])) {
+ throw Error.invalidOperation(String.format(Sys.Res.observableConflict, m));
+ }
+ target[m] = methods[m];
+ }
+}
+Sys.Observer._addEventHandler = function Sys$Observer$_addEventHandler(target, eventName, handler) {
+ Sys.Observer._getContext(target, true).events._addHandler(eventName, handler);
+}
+Sys.Observer.addEventHandler = function Sys$Observer$addEventHandler(target, eventName, handler) {
+ /// <summary locid="M:J#Sys.Observer.addEventHandler" />
+ /// <param name="target"></param>
+ /// <param name="eventName" type="String"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"},
+ {name: "eventName", type: String},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ Sys.Observer._addEventHandler(target, eventName, handler);
+}
+Sys.Observer._removeEventHandler = function Sys$Observer$_removeEventHandler(target, eventName, handler) {
+ Sys.Observer._getContext(target, true).events._removeHandler(eventName, handler);
+}
+Sys.Observer.removeEventHandler = function Sys$Observer$removeEventHandler(target, eventName, handler) {
+ /// <summary locid="M:J#Sys.Observer.removeEventHandler" />
+ /// <param name="target"></param>
+ /// <param name="eventName" type="String"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"},
+ {name: "eventName", type: String},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ Sys.Observer._removeEventHandler(target, eventName, handler);
+}
+Sys.Observer.raiseEvent = function Sys$Observer$raiseEvent(target, eventName, eventArgs) {
+ /// <summary locid="M:J#Sys.Observer.raiseEvent" />
+ /// <param name="target"></param>
+ /// <param name="eventName" type="String"></param>
+ /// <param name="eventArgs" type="Sys.EventArgs"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"},
+ {name: "eventName", type: String},
+ {name: "eventArgs", type: Sys.EventArgs}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ var ctx = Sys.Observer._getContext(target);
+ if (!ctx) return;
+ var handler = ctx.events.getHandler(eventName);
+ if (handler) {
+ handler(target, eventArgs);
+ }
+}
+Sys.Observer.addPropertyChanged = function Sys$Observer$addPropertyChanged(target, handler) {
+ /// <summary locid="M:J#Sys.Observer.addPropertyChanged" />
+ /// <param name="target" mayBeNull="false"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ Sys.Observer._addEventHandler(target, "propertyChanged", handler);
+}
+Sys.Observer.removePropertyChanged = function Sys$Observer$removePropertyChanged(target, handler) {
+ /// <summary locid="M:J#Sys.Observer.removePropertyChanged" />
+ /// <param name="target" mayBeNull="false"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ Sys.Observer._removeEventHandler(target, "propertyChanged", handler);
+}
+Sys.Observer.beginUpdate = function Sys$Observer$beginUpdate(target) {
+ /// <summary locid="M:J#Sys.Observer.beginUpdate" />
+ /// <param name="target" mayBeNull="false"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ Sys.Observer._getContext(target, true).updating = true;
+}
+Sys.Observer.endUpdate = function Sys$Observer$endUpdate(target) {
+ /// <summary locid="M:J#Sys.Observer.endUpdate" />
+ /// <param name="target" mayBeNull="false"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ var ctx = Sys.Observer._getContext(target);
+ if (!ctx || !ctx.updating) return;
+ ctx.updating = false;
+ var dirty = ctx.dirty;
+ ctx.dirty = false;
+ if (dirty) {
+ if (target instanceof Array) {
+ var changes = ctx.changes;
+ ctx.changes = null;
+ Sys.Observer.raiseCollectionChanged(target, changes);
+ }
+ Sys.Observer.raisePropertyChanged(target, "");
+ }
+}
+Sys.Observer.isUpdating = function Sys$Observer$isUpdating(target) {
+ /// <summary locid="M:J#Sys.Observer.isUpdating" />
+ /// <param name="target" mayBeNull="false"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "target"}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ var ctx = Sys.Observer._getContext(target);
+ return ctx ? ctx.updating : false;
+}
+Sys.Observer._setValue = function Sys$Observer$_setValue(target, propertyName, value) {
+ var getter, setter, mainTarget = target, path = propertyName.split('.');
+ for (var i = 0, l = (path.length - 1); i < l ; i++) {
+ var name = path[i];
+ getter = target["get_" + name];
+ if (typeof (getter) === "function") {
+ target = getter.call(target);
+ }
+ else {
+ target = target[name];
+ }
+ var type = typeof (target);
+ if ((target === null) || (type === "undefined")) {
+ throw Error.invalidOperation(String.format(Sys.Res.nullReferenceInPath, propertyName));
+ }
+ }
+ var currentValue, lastPath = path[l];
+ getter = target["get_" + lastPath];
+ setter = target["set_" + lastPath];
+ if (typeof(getter) === 'function') {
+ currentValue = getter.call(target);
+ }
+ else {
+ currentValue = target[lastPath];
+ }
+ if (typeof(setter) === 'function') {
+ setter.call(target, value);
+ }
+ else {
+ target[lastPath] = value;
+ }
+ if (currentValue !== value) {
+ var ctx = Sys.Observer._getContext(mainTarget);
+ if (ctx && ctx.updating) {
+ ctx.dirty = true;
+ return;
+ };
+ Sys.Observer.raisePropertyChanged(mainTarget, path[0]);
+ }
+}
+Sys.Observer.setValue = function Sys$Observer$setValue(target, propertyName, value) {
+ /// <summary locid="M:J#Sys.Observer.setValue" />
+ /// <param name="target" mayBeNull="false"></param>
+ /// <param name="propertyName" type="String"></param>
+ /// <param name="value" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"},
+ {name: "propertyName", type: String},
+ {name: "value", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ Sys.Observer._ensureObservable(target);
+ Sys.Observer._setValue(target, propertyName, value);
+}
+Sys.Observer.raisePropertyChanged = function Sys$Observer$raisePropertyChanged(target, propertyName) {
+ /// <summary locid="M:J#Sys.Observer.raisePropertyChanged" />
+ /// <param name="target" mayBeNull="false"></param>
+ /// <param name="propertyName" type="String"></param>
+ Sys.Observer.raiseEvent(target, "propertyChanged", new Sys.PropertyChangedEventArgs(propertyName));
+}
+Sys.Observer.addCollectionChanged = function Sys$Observer$addCollectionChanged(target, handler) {
+ /// <summary locid="M:J#Sys.Observer.addCollectionChanged" />
+ /// <param name="target" type="Array" elementMayBeNull="true"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target", type: Array, elementMayBeNull: true},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.Observer._addEventHandler(target, "collectionChanged", handler);
+}
+Sys.Observer.removeCollectionChanged = function Sys$Observer$removeCollectionChanged(target, handler) {
+ /// <summary locid="M:J#Sys.Observer.removeCollectionChanged" />
+ /// <param name="target" type="Array" elementMayBeNull="true"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target", type: Array, elementMayBeNull: true},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.Observer._removeEventHandler(target, "collectionChanged", handler);
+}
+Sys.Observer._collectionChange = function Sys$Observer$_collectionChange(target, change) {
+ var ctx = Sys.Observer._getContext(target);
+ if (ctx && ctx.updating) {
+ ctx.dirty = true;
+ var changes = ctx.changes;
+ if (!changes) {
+ ctx.changes = changes = [change];
+ }
+ else {
+ changes.push(change);
+ }
+ }
+ else {
+ Sys.Observer.raiseCollectionChanged(target, [change]);
+ Sys.Observer.raisePropertyChanged(target, 'length');
+ }
+}
+Sys.Observer.add = function Sys$Observer$add(target, item) {
+ /// <summary locid="M:J#Sys.Observer.add" />
+ /// <param name="target" type="Array" elementMayBeNull="true"></param>
+ /// <param name="item" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target", type: Array, elementMayBeNull: true},
+ {name: "item", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ var change = new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.add, [item], target.length);
+ Array.add(target, item);
+ Sys.Observer._collectionChange(target, change);
+}
+Sys.Observer.addRange = function Sys$Observer$addRange(target, items) {
+ /// <summary locid="M:J#Sys.Observer.addRange" />
+ /// <param name="target" type="Array" elementMayBeNull="true"></param>
+ /// <param name="items" type="Array" elementMayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target", type: Array, elementMayBeNull: true},
+ {name: "items", type: Array, elementMayBeNull: true}
+ ]);
+ if (e) throw e;
+ var change = new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.add, items, target.length);
+ Array.addRange(target, items);
+ Sys.Observer._collectionChange(target, change);
+}
+Sys.Observer.clear = function Sys$Observer$clear(target) {
+ /// <summary locid="M:J#Sys.Observer.clear" />
+ /// <param name="target" type="Array" elementMayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target", type: Array, elementMayBeNull: true}
+ ]);
+ if (e) throw e;
+ var oldItems = Array.clone(target);
+ Array.clear(target);
+ Sys.Observer._collectionChange(target, new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.reset, null, -1, oldItems, 0));
+}
+Sys.Observer.insert = function Sys$Observer$insert(target, index, item) {
+ /// <summary locid="M:J#Sys.Observer.insert" />
+ /// <param name="target" type="Array" elementMayBeNull="true"></param>
+ /// <param name="index" type="Number" integer="true"></param>
+ /// <param name="item" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target", type: Array, elementMayBeNull: true},
+ {name: "index", type: Number, integer: true},
+ {name: "item", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ Array.insert(target, index, item);
+ Sys.Observer._collectionChange(target, new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.add, [item], index));
+}
+Sys.Observer.remove = function Sys$Observer$remove(target, item) {
+ /// <summary locid="M:J#Sys.Observer.remove" />
+ /// <param name="target" type="Array" elementMayBeNull="true"></param>
+ /// <param name="item" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "target", type: Array, elementMayBeNull: true},
+ {name: "item", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ var index = Array.indexOf(target, item);
+ if (index !== -1) {
+ Array.remove(target, item);
+ Sys.Observer._collectionChange(target, new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.remove, null, -1, [item], index));
+ return true;
+ }
+ return false;
+}
+Sys.Observer.removeAt = function Sys$Observer$removeAt(target, index) {
+ /// <summary locid="M:J#Sys.Observer.removeAt" />
+ /// <param name="target" type="Array" elementMayBeNull="true"></param>
+ /// <param name="index" type="Number" integer="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target", type: Array, elementMayBeNull: true},
+ {name: "index", type: Number, integer: true}
+ ]);
+ if (e) throw e;
+ if ((index > -1) && (index < target.length)) {
+ var item = target[index];
+ Array.removeAt(target, index);
+ Sys.Observer._collectionChange(target, new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.remove, null, -1, [item], index));
+ }
+}
+Sys.Observer.raiseCollectionChanged = function Sys$Observer$raiseCollectionChanged(target, changes) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="target"></param>
+ /// <param name="changes" type="Array" elementType="Sys.CollectionChange"></param>
+ Sys.Observer.raiseEvent(target, "collectionChanged", new Sys.NotifyCollectionChangedEventArgs(changes));
+}
+Sys.Observer._observeMethods = {
+ add_propertyChanged: function(handler) {
+ Sys.Observer._addEventHandler(this, "propertyChanged", handler);
+ },
+ remove_propertyChanged: function(handler) {
+ Sys.Observer._removeEventHandler(this, "propertyChanged", handler);
+ },
+ addEventHandler: function(eventName, handler) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="eventName" type="String"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "eventName", type: String},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.Observer._addEventHandler(this, eventName, handler);
+ },
+ removeEventHandler: function(eventName, handler) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="eventName" type="String"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "eventName", type: String},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.Observer._removeEventHandler(this, eventName, handler);
+ },
+ get_isUpdating: function() {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <returns type="Boolean"></returns>
+ return Sys.Observer.isUpdating(this);
+ },
+ beginUpdate: function() {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ Sys.Observer.beginUpdate(this);
+ },
+ endUpdate: function() {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ Sys.Observer.endUpdate(this);
+ },
+ setValue: function(name, value) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="name" type="String"></param>
+ /// <param name="value" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "name", type: String},
+ {name: "value", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ Sys.Observer._setValue(this, name, value);
+ },
+ raiseEvent: function(eventName, eventArgs) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="eventName" type="String"></param>
+ /// <param name="eventArgs" type="Sys.EventArgs"></param>
+ Sys.Observer.raiseEvent(this, eventName, eventArgs);
+ },
+ raisePropertyChanged: function(name) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="name" type="String"></param>
+ Sys.Observer.raiseEvent(this, "propertyChanged", new Sys.PropertyChangedEventArgs(name));
+ }
+}
+Sys.Observer._arrayMethods = {
+ add_collectionChanged: function(handler) {
+ Sys.Observer._addEventHandler(this, "collectionChanged", handler);
+ },
+ remove_collectionChanged: function(handler) {
+ Sys.Observer._removeEventHandler(this, "collectionChanged", handler);
+ },
+ add: function(item) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="item" mayBeNull="true"></param>
+ Sys.Observer.add(this, item);
+ },
+ addRange: function(items) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="items" type="Array" elementMayBeNull="true"></param>
+ Sys.Observer.addRange(this, items);
+ },
+ clear: function() {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ Sys.Observer.clear(this);
+ },
+ insert: function(index, item) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="index" type="Number" integer="true"></param>
+ /// <param name="item" mayBeNull="true"></param>
+ Sys.Observer.insert(this, index, item);
+ },
+ remove: function(item) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="item" mayBeNull="true"></param>
+ /// <returns type="Boolean"></returns>
+ return Sys.Observer.remove(this, item);
+ },
+ removeAt: function(index) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="index" type="Number" integer="true"></param>
+ Sys.Observer.removeAt(this, index);
+ },
+ raiseCollectionChanged: function(changes) {
+ /// <summary locid="M:J#Sys.Observer.raiseCollectionChanged" />
+ /// <param name="changes" type="Array" elementType="Sys.CollectionChange"></param>
+ Sys.Observer.raiseEvent(this, "collectionChanged", new Sys.NotifyCollectionChangedEventArgs(changes));
+ }
+}
+Sys.Observer._getContext = function Sys$Observer$_getContext(obj, create) {
+ var ctx = obj._observerContext;
+ if (ctx) return ctx();
+ if (create) {
+ return (obj._observerContext = Sys.Observer._createContext())();
+ }
+ return null;
+}
+Sys.Observer._createContext = function Sys$Observer$_createContext() {
+ var ctx = {
+ events: new Sys.EventHandlerList()
+ };
+ return function() {
+ return ctx;
+ }
+}
+Date._appendPreOrPostMatch = function Date$_appendPreOrPostMatch(preMatch, strBuilder) {
+ var quoteCount = 0;
+ var escaped = false;
+ for (var i = 0, il = preMatch.length; i < il; i++) {
+ var c = preMatch.charAt(i);
+ switch (c) {
+ case '\'':
+ if (escaped) strBuilder.append("'");
+ else quoteCount++;
+ escaped = false;
+ break;
+ case '\\':
+ if (escaped) strBuilder.append("\\");
+ escaped = !escaped;
+ break;
+ default:
+ strBuilder.append(c);
+ escaped = false;
+ break;
+ }
+ }
+ return quoteCount;
+}
+Date._expandFormat = function Date$_expandFormat(dtf, format) {
+ if (!format) {
+ format = "F";
+ }
+ var len = format.length;
+ if (len === 1) {
+ switch (format) {
+ case "d":
+ return dtf.ShortDatePattern;
+ case "D":
+ return dtf.LongDatePattern;
+ case "t":
+ return dtf.ShortTimePattern;
+ case "T":
+ return dtf.LongTimePattern;
+ case "f":
+ return dtf.LongDatePattern + " " + dtf.ShortTimePattern;
+ case "F":
+ return dtf.FullDateTimePattern;
+ case "M": case "m":
+ return dtf.MonthDayPattern;
+ case "s":
+ return dtf.SortableDateTimePattern;
+ case "Y": case "y":
+ return dtf.YearMonthPattern;
+ default:
+ throw Error.format(Sys.Res.formatInvalidString);
+ }
+ }
+ else if ((len === 2) && (format.charAt(0) === "%")) {
+ format = format.charAt(1);
+ }
+ return format;
+}
+Date._expandYear = function Date$_expandYear(dtf, year) {
+ var now = new Date(),
+ era = Date._getEra(now);
+ if (year < 100) {
+ var curr = Date._getEraYear(now, dtf, era);
+ year += curr - (curr % 100);
+ if (year > dtf.Calendar.TwoDigitYearMax) {
+ year -= 100;
+ }
+ }
+ return year;
+}
+Date._getEra = function Date$_getEra(date, eras) {
+ if (!eras) return 0;
+ var start, ticks = date.getTime();
+ for (var i = 0, l = eras.length; i < l; i += 4) {
+ start = eras[i+2];
+ if ((start === null) || (ticks >= start)) {
+ return i;
+ }
+ }
+ return 0;
+}
+Date._getEraYear = function Date$_getEraYear(date, dtf, era, sortable) {
+ var year = date.getFullYear();
+ if (!sortable && dtf.eras) {
+ year -= dtf.eras[era + 3];
+ }
+ return year;
+}
+Date._getParseRegExp = function Date$_getParseRegExp(dtf, format) {
+ if (!dtf._parseRegExp) {
+ dtf._parseRegExp = {};
+ }
+ else if (dtf._parseRegExp[format]) {
+ return dtf._parseRegExp[format];
+ }
+ var expFormat = Date._expandFormat(dtf, format);
+ expFormat = expFormat.replace(/([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g, "\\\\$1");
+ var regexp = new Sys.StringBuilder("^");
+ var groups = [];
+ var index = 0;
+ var quoteCount = 0;
+ var tokenRegExp = Date._getTokenRegExp();
+ var match;
+ while ((match = tokenRegExp.exec(expFormat)) !== null) {
+ var preMatch = expFormat.slice(index, match.index);
+ index = tokenRegExp.lastIndex;
+ quoteCount += Date._appendPreOrPostMatch(preMatch, regexp);
+ if ((quoteCount%2) === 1) {
+ regexp.append(match[0]);
+ continue;
+ }
+ switch (match[0]) {
+ case 'dddd': case 'ddd':
+ case 'MMMM': case 'MMM':
+ case 'gg': case 'g':
+ regexp.append("(\\D+)");
+ break;
+ case 'tt': case 't':
+ regexp.append("(\\D*)");
+ break;
+ case 'yyyy':
+ regexp.append("(\\d{4})");
+ break;
+ case 'fff':
+ regexp.append("(\\d{3})");
+ break;
+ case 'ff':
+ regexp.append("(\\d{2})");
+ break;
+ case 'f':
+ regexp.append("(\\d)");
+ break;
+ case 'dd': case 'd':
+ case 'MM': case 'M':
+ case 'yy': case 'y':
+ case 'HH': case 'H':
+ case 'hh': case 'h':
+ case 'mm': case 'm':
+ case 'ss': case 's':
+ regexp.append("(\\d\\d?)");
+ break;
+ case 'zzz':
+ regexp.append("([+-]?\\d\\d?:\\d{2})");
+ break;
+ case 'zz': case 'z':
+ regexp.append("([+-]?\\d\\d?)");
+ break;
+ case '/':
+ regexp.append("(\\" + dtf.DateSeparator + ")");
+ break;
+ default:
+ Sys.Debug.fail("Invalid date format pattern");
+ }
+ Array.add(groups, match[0]);
+ }
+ Date._appendPreOrPostMatch(expFormat.slice(index), regexp);
+ regexp.append("$");
+ var regexpStr = regexp.toString().replace(/\s+/g, "\\s+");
+ var parseRegExp = {'regExp': regexpStr, 'groups': groups};
+ dtf._parseRegExp[format] = parseRegExp;
+ return parseRegExp;
+}
+Date._getTokenRegExp = function Date$_getTokenRegExp() {
+ return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g;
+}
+Date.parseLocale = function Date$parseLocale(value, formats) {
+ /// <summary locid="M:J#Date.parseLocale" />
+ /// <param name="value" type="String"></param>
+ /// <param name="formats" parameterArray="true" optional="true" mayBeNull="true"></param>
+ /// <returns type="Date"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "value", type: String},
+ {name: "formats", mayBeNull: true, optional: true, parameterArray: true}
+ ]);
+ if (e) throw e;
+ return Date._parse(value, Sys.CultureInfo.CurrentCulture, arguments);
+}
+Date.parseInvariant = function Date$parseInvariant(value, formats) {
+ /// <summary locid="M:J#Date.parseInvariant" />
+ /// <param name="value" type="String"></param>
+ /// <param name="formats" parameterArray="true" optional="true" mayBeNull="true"></param>
+ /// <returns type="Date"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "value", type: String},
+ {name: "formats", mayBeNull: true, optional: true, parameterArray: true}
+ ]);
+ if (e) throw e;
+ return Date._parse(value, Sys.CultureInfo.InvariantCulture, arguments);
+}
+Date._parse = function Date$_parse(value, cultureInfo, args) {
+ var i, l, date, format, formats, custom = false;
+ for (i = 1, l = args.length; i < l; i++) {
+ format = args[i];
+ if (format) {
+ custom = true;
+ date = Date._parseExact(value, format, cultureInfo);
+ if (date) return date;
+ }
+ }
+ if (! custom) {
+ formats = cultureInfo._getDateTimeFormats();
+ for (i = 0, l = formats.length; i < l; i++) {
+ date = Date._parseExact(value, formats[i], cultureInfo);
+ if (date) return date;
+ }
+ }
+ return null;
+}
+Date._parseExact = function Date$_parseExact(value, format, cultureInfo) {
+ value = value.trim();
+ var dtf = cultureInfo.dateTimeFormat,
+ parseInfo = Date._getParseRegExp(dtf, format),
+ match = new RegExp(parseInfo.regExp).exec(value);
+ if (match === null) return null;
+
+ var groups = parseInfo.groups,
+ era = null, year = null, month = null, date = null, weekDay = null,
+ hour = 0, hourOffset, min = 0, sec = 0, msec = 0, tzMinOffset = null,
+ pmHour = false;
+ for (var j = 0, jl = groups.length; j < jl; j++) {
+ var matchGroup = match[j+1];
+ if (matchGroup) {
+ switch (groups[j]) {
+ case 'dd': case 'd':
+ date = parseInt(matchGroup, 10);
+ if ((date < 1) || (date > 31)) return null;
+ break;
+ case 'MMMM':
+ month = cultureInfo._getMonthIndex(matchGroup);
+ if ((month < 0) || (month > 11)) return null;
+ break;
+ case 'MMM':
+ month = cultureInfo._getAbbrMonthIndex(matchGroup);
+ if ((month < 0) || (month > 11)) return null;
+ break;
+ case 'M': case 'MM':
+ month = parseInt(matchGroup, 10) - 1;
+ if ((month < 0) || (month > 11)) return null;
+ break;
+ case 'y': case 'yy':
+ year = Date._expandYear(dtf,parseInt(matchGroup, 10));
+ if ((year < 0) || (year > 9999)) return null;
+ break;
+ case 'yyyy':
+ year = parseInt(matchGroup, 10);
+ if ((year < 0) || (year > 9999)) return null;
+ break;
+ case 'h': case 'hh':
+ hour = parseInt(matchGroup, 10);
+ if (hour === 12) hour = 0;
+ if ((hour < 0) || (hour > 11)) return null;
+ break;
+ case 'H': case 'HH':
+ hour = parseInt(matchGroup, 10);
+ if ((hour < 0) || (hour > 23)) return null;
+ break;
+ case 'm': case 'mm':
+ min = parseInt(matchGroup, 10);
+ if ((min < 0) || (min > 59)) return null;
+ break;
+ case 's': case 'ss':
+ sec = parseInt(matchGroup, 10);
+ if ((sec < 0) || (sec > 59)) return null;
+ break;
+ case 'tt': case 't':
+ var upperToken = matchGroup.toUpperCase();
+ pmHour = (upperToken === dtf.PMDesignator.toUpperCase());
+ if (!pmHour && (upperToken !== dtf.AMDesignator.toUpperCase())) return null;
+ break;
+ case 'f':
+ msec = parseInt(matchGroup, 10) * 100;
+ if ((msec < 0) || (msec > 999)) return null;
+ break;
+ case 'ff':
+ msec = parseInt(matchGroup, 10) * 10;
+ if ((msec < 0) || (msec > 999)) return null;
+ break;
+ case 'fff':
+ msec = parseInt(matchGroup, 10);
+ if ((msec < 0) || (msec > 999)) return null;
+ break;
+ case 'dddd':
+ weekDay = cultureInfo._getDayIndex(matchGroup);
+ if ((weekDay < 0) || (weekDay > 6)) return null;
+ break;
+ case 'ddd':
+ weekDay = cultureInfo._getAbbrDayIndex(matchGroup);
+ if ((weekDay < 0) || (weekDay > 6)) return null;
+ break;
+ case 'zzz':
+ var offsets = matchGroup.split(/:/);
+ if (offsets.length !== 2) return null;
+ hourOffset = parseInt(offsets[0], 10);
+ if ((hourOffset < -12) || (hourOffset > 13)) return null;
+ var minOffset = parseInt(offsets[1], 10);
+ if ((minOffset < 0) || (minOffset > 59)) return null;
+ tzMinOffset = (hourOffset * 60) + (matchGroup.startsWith('-')? -minOffset : minOffset);
+ break;
+ case 'z': case 'zz':
+ hourOffset = parseInt(matchGroup, 10);
+ if ((hourOffset < -12) || (hourOffset > 13)) return null;
+ tzMinOffset = hourOffset * 60;
+ break;
+ case 'g': case 'gg':
+ var eraName = matchGroup;
+ if (!eraName || !dtf.eras) return null;
+ eraName = eraName.toLowerCase().trim();
+ for (var i = 0, l = dtf.eras.length; i < l; i += 4) {
+ if (eraName === dtf.eras[i + 1].toLowerCase()) {
+ era = i;
+ break;
+ }
+ }
+ if (era === null) return null;
+ break;
+ }
+ }
+ }
+ var result = new Date(), defaults, convert = dtf.Calendar.convert;
+ if (convert) {
+ defaults = convert.fromGregorian(result);
+ }
+ if (!convert) {
+ defaults = [result.getFullYear(), result.getMonth(), result.getDate()];
+ }
+ if (year === null) {
+ year = defaults[0];
+ }
+ else if (dtf.eras) {
+ year += dtf.eras[(era || 0) + 3];
+ }
+ if (month === null) {
+ month = defaults[1];
+ }
+ if (date === null) {
+ date = defaults[2];
+ }
+ if (convert) {
+ result = convert.toGregorian(year, month, date);
+ if (result === null) return null;
+ }
+ else {
+ result.setFullYear(year, month, date);
+ if (result.getDate() !== date) return null;
+ if ((weekDay !== null) && (result.getDay() !== weekDay)) {
+ return null;
+ }
+ }
+ if (pmHour && (hour < 12)) {
+ hour += 12;
+ }
+ result.setHours(hour, min, sec, msec);
+ if (tzMinOffset !== null) {
+ var adjustedMin = result.getMinutes() - (tzMinOffset + result.getTimezoneOffset());
+ result.setHours(result.getHours() + parseInt(adjustedMin/60, 10), adjustedMin%60);
+ }
+ return result;
+}
+Date.prototype.format = function Date$format(format) {
+ /// <summary locid="M:J#Date.format" />
+ /// <param name="format" type="String"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "format", type: String}
+ ]);
+ if (e) throw e;
+ return this._toFormattedString(format, Sys.CultureInfo.InvariantCulture);
+}
+Date.prototype.localeFormat = function Date$localeFormat(format) {
+ /// <summary locid="M:J#Date.localeFormat" />
+ /// <param name="format" type="String"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "format", type: String}
+ ]);
+ if (e) throw e;
+ return this._toFormattedString(format, Sys.CultureInfo.CurrentCulture);
+}
+Date.prototype._toFormattedString = function Date$_toFormattedString(format, cultureInfo) {
+ var dtf = cultureInfo.dateTimeFormat,
+ convert = dtf.Calendar.convert;
+ if (!format || !format.length || (format === 'i')) {
+ if (cultureInfo && cultureInfo.name.length) {
+ if (convert) {
+ return this._toFormattedString(dtf.FullDateTimePattern, cultureInfo);
+ }
+ else {
+ var eraDate = new Date(this.getTime());
+ var era = Date._getEra(this, dtf.eras);
+ eraDate.setFullYear(Date._getEraYear(this, dtf, era));
+ return eraDate.toLocaleString();
+ }
+ }
+ else {
+ return this.toString();
+ }
+ }
+ var eras = dtf.eras,
+ sortable = (format === "s");
+ format = Date._expandFormat(dtf, format);
+ var ret = new Sys.StringBuilder();
+ var hour;
+ function addLeadingZero(num) {
+ if (num < 10) {
+ return '0' + num;
+ }
+ return num.toString();
+ }
+ function addLeadingZeros(num) {
+ if (num < 10) {
+ return '00' + num;
+ }
+ if (num < 100) {
+ return '0' + num;
+ }
+ return num.toString();
+ }
+ function padYear(year) {
+ if (year < 10) {
+ return '000' + year;
+ }
+ else if (year < 100) {
+ return '00' + year;
+ }
+ else if (year < 1000) {
+ return '0' + year;
+ }
+ return year.toString();
+ }
+
+ var foundDay, checkedDay, dayPartRegExp = /([^d]|^)(d|dd)([^d]|$)/g;
+ function hasDay() {
+ if (foundDay || checkedDay) {
+ return foundDay;
+ }
+ foundDay = dayPartRegExp.test(format);
+ checkedDay = true;
+ return foundDay;
+ }
+
+ var quoteCount = 0,
+ tokenRegExp = Date._getTokenRegExp(),
+ converted;
+ if (!sortable && convert) {
+ converted = convert.fromGregorian(this);
+ }
+ for (;;) {
+ var index = tokenRegExp.lastIndex;
+ var ar = tokenRegExp.exec(format);
+ var preMatch = format.slice(index, ar ? ar.index : format.length);
+ quoteCount += Date._appendPreOrPostMatch(preMatch, ret);
+ if (!ar) break;
+ if ((quoteCount%2) === 1) {
+ ret.append(ar[0]);
+ continue;
+ }
+
+ function getPart(date, part) {
+ if (converted) {
+ return converted[part];
+ }
+ switch (part) {
+ case 0: return date.getFullYear();
+ case 1: return date.getMonth();
+ case 2: return date.getDate();
+ }
+ }
+ switch (ar[0]) {
+ case "dddd":
+ ret.append(dtf.DayNames[this.getDay()]);
+ break;
+ case "ddd":
+ ret.append(dtf.AbbreviatedDayNames[this.getDay()]);
+ break;
+ case "dd":
+ foundDay = true;
+ ret.append(addLeadingZero(getPart(this, 2)));
+ break;
+ case "d":
+ foundDay = true;
+ ret.append(getPart(this, 2));
+ break;
+ case "MMMM":
+ ret.append((dtf.MonthGenitiveNames && hasDay())
+ ? dtf.MonthGenitiveNames[getPart(this, 1)]
+ : dtf.MonthNames[getPart(this, 1)]);
+ break;
+ case "MMM":
+ ret.append((dtf.AbbreviatedMonthGenitiveNames && hasDay())
+ ? dtf.AbbreviatedMonthGenitiveNames[getPart(this, 1)]
+ : dtf.AbbreviatedMonthNames[getPart(this, 1)]);
+ break;
+ case "MM":
+ ret.append(addLeadingZero(getPart(this, 1) + 1));
+ break;
+ case "M":
+ ret.append(getPart(this, 1) + 1);
+ break;
+ case "yyyy":
+ ret.append(padYear(converted ? converted[0] : Date._getEraYear(this, dtf, Date._getEra(this, eras), sortable)));
+ break;
+ case "yy":
+ ret.append(addLeadingZero((converted ? converted[0] : Date._getEraYear(this, dtf, Date._getEra(this, eras), sortable)) % 100));
+ break;
+ case "y":
+ ret.append((converted ? converted[0] : Date._getEraYear(this, dtf, Date._getEra(this, eras), sortable)) % 100);
+ break;
+ case "hh":
+ hour = this.getHours() % 12;
+ if (hour === 0) hour = 12;
+ ret.append(addLeadingZero(hour));
+ break;
+ case "h":
+ hour = this.getHours() % 12;
+ if (hour === 0) hour = 12;
+ ret.append(hour);
+ break;
+ case "HH":
+ ret.append(addLeadingZero(this.getHours()));
+ break;
+ case "H":
+ ret.append(this.getHours());
+ break;
+ case "mm":
+ ret.append(addLeadingZero(this.getMinutes()));
+ break;
+ case "m":
+ ret.append(this.getMinutes());
+ break;
+ case "ss":
+ ret.append(addLeadingZero(this.getSeconds()));
+ break;
+ case "s":
+ ret.append(this.getSeconds());
+ break;
+ case "tt":
+ ret.append((this.getHours() < 12) ? dtf.AMDesignator : dtf.PMDesignator);
+ break;
+ case "t":
+ ret.append(((this.getHours() < 12) ? dtf.AMDesignator : dtf.PMDesignator).charAt(0));
+ break;
+ case "f":
+ ret.append(addLeadingZeros(this.getMilliseconds()).charAt(0));
+ break;
+ case "ff":
+ ret.append(addLeadingZeros(this.getMilliseconds()).substr(0, 2));
+ break;
+ case "fff":
+ ret.append(addLeadingZeros(this.getMilliseconds()));
+ break;
+ case "z":
+ hour = this.getTimezoneOffset() / 60;
+ ret.append(((hour <= 0) ? '+' : '-') + Math.floor(Math.abs(hour)));
+ break;
+ case "zz":
+ hour = this.getTimezoneOffset() / 60;
+ ret.append(((hour <= 0) ? '+' : '-') + addLeadingZero(Math.floor(Math.abs(hour))));
+ break;
+ case "zzz":
+ hour = this.getTimezoneOffset() / 60;
+ ret.append(((hour <= 0) ? '+' : '-') + addLeadingZero(Math.floor(Math.abs(hour))) +
+ ":" + addLeadingZero(Math.abs(this.getTimezoneOffset() % 60)));
+ break;
+ case "g":
+ case "gg":
+ if (dtf.eras) {
+ ret.append(dtf.eras[Date._getEra(this, eras) + 1]);
+ }
+ break;
+ case "/":
+ ret.append(dtf.DateSeparator);
+ break;
+ default:
+ Sys.Debug.fail("Invalid date format pattern");
+ }
+ }
+ return ret.toString();
+}
+String.localeFormat = function String$localeFormat(format, args) {
+ /// <summary locid="M:J#String.localeFormat" />
+ /// <param name="format" type="String"></param>
+ /// <param name="args" parameterArray="true" mayBeNull="true"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "format", type: String},
+ {name: "args", mayBeNull: true, parameterArray: true}
+ ]);
+ if (e) throw e;
+ return String._toFormattedString(true, arguments);
+}
+Number.parseLocale = function Number$parseLocale(value) {
+ /// <summary locid="M:J#Number.parseLocale" />
+ /// <param name="value" type="String"></param>
+ /// <returns type="Number"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "value", type: String}
+ ], false);
+ if (e) throw e;
+ return Number._parse(value, Sys.CultureInfo.CurrentCulture);
+}
+Number.parseInvariant = function Number$parseInvariant(value) {
+ /// <summary locid="M:J#Number.parseInvariant" />
+ /// <param name="value" type="String"></param>
+ /// <returns type="Number"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "value", type: String}
+ ], false);
+ if (e) throw e;
+ return Number._parse(value, Sys.CultureInfo.InvariantCulture);
+}
+Number._parse = function Number$_parse(value, cultureInfo) {
+ value = value.trim();
+
+ if (value.match(/^[+-]?infinity$/i)) {
+ return parseFloat(value);
+ }
+ if (value.match(/^0x[a-f0-9]+$/i)) {
+ return parseInt(value);
+ }
+ var numFormat = cultureInfo.numberFormat;
+ var signInfo = Number._parseNumberNegativePattern(value, numFormat, numFormat.NumberNegativePattern);
+ var sign = signInfo[0];
+ var num = signInfo[1];
+
+ if ((sign === '') && (numFormat.NumberNegativePattern !== 1)) {
+ signInfo = Number._parseNumberNegativePattern(value, numFormat, 1);
+ sign = signInfo[0];
+ num = signInfo[1];
+ }
+ if (sign === '') sign = '+';
+
+ var exponent;
+ var intAndFraction;
+ var exponentPos = num.indexOf('e');
+ if (exponentPos < 0) exponentPos = num.indexOf('E');
+ if (exponentPos < 0) {
+ intAndFraction = num;
+ exponent = null;
+ }
+ else {
+ intAndFraction = num.substr(0, exponentPos);
+ exponent = num.substr(exponentPos + 1);
+ }
+
+ var integer;
+ var fraction;
+ var decimalPos = intAndFraction.indexOf(numFormat.NumberDecimalSeparator);
+ if (decimalPos < 0) {
+ integer = intAndFraction;
+ fraction = null;
+ }
+ else {
+ integer = intAndFraction.substr(0, decimalPos);
+ fraction = intAndFraction.substr(decimalPos + numFormat.NumberDecimalSeparator.length);
+ }
+
+ integer = integer.split(numFormat.NumberGroupSeparator).join('');
+ var altNumGroupSeparator = numFormat.NumberGroupSeparator.replace(/\u00A0/g, " ");
+ if (numFormat.NumberGroupSeparator !== altNumGroupSeparator) {
+ integer = integer.split(altNumGroupSeparator).join('');
+ }
+
+ var p = sign + integer;
+ if (fraction !== null) {
+ p += '.' + fraction;
+ }
+ if (exponent !== null) {
+ var expSignInfo = Number._parseNumberNegativePattern(exponent, numFormat, 1);
+ if (expSignInfo[0] === '') {
+ expSignInfo[0] = '+';
+ }
+ p += 'e' + expSignInfo[0] + expSignInfo[1];
+ }
+ if (p.match(/^[+-]?\d*\.?\d*(e[+-]?\d+)?$/)) {
+ return parseFloat(p);
+ }
+ return Number.NaN;
+}
+Number._parseNumberNegativePattern = function Number$_parseNumberNegativePattern(value, numFormat, numberNegativePattern) {
+ var neg = numFormat.NegativeSign;
+ var pos = numFormat.PositiveSign;
+ switch (numberNegativePattern) {
+ case 4:
+ neg = ' ' + neg;
+ pos = ' ' + pos;
+ case 3:
+ if (value.endsWith(neg)) {
+ return ['-', value.substr(0, value.length - neg.length)];
+ }
+ else if (value.endsWith(pos)) {
+ return ['+', value.substr(0, value.length - pos.length)];
+ }
+ break;
+ case 2:
+ neg += ' ';
+ pos += ' ';
+ case 1:
+ if (value.startsWith(neg)) {
+ return ['-', value.substr(neg.length)];
+ }
+ else if (value.startsWith(pos)) {
+ return ['+', value.substr(pos.length)];
+ }
+ break;
+ case 0:
+ if (value.startsWith('(') && value.endsWith(')')) {
+ return ['-', value.substr(1, value.length - 2)];
+ }
+ break;
+ default:
+ Sys.Debug.fail("");
+ }
+ return ['', value];
+}
+Number.prototype.format = function Number$format(format) {
+ /// <summary locid="M:J#Number.format" />
+ /// <param name="format" type="String"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "format", type: String}
+ ]);
+ if (e) throw e;
+ return this._toFormattedString(format, Sys.CultureInfo.InvariantCulture);
+}
+Number.prototype.localeFormat = function Number$localeFormat(format) {
+ /// <summary locid="M:J#Number.localeFormat" />
+ /// <param name="format" type="String"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "format", type: String}
+ ]);
+ if (e) throw e;
+ return this._toFormattedString(format, Sys.CultureInfo.CurrentCulture);
+}
+Number.prototype._toFormattedString = function Number$_toFormattedString(format, cultureInfo) {
+ if (!format || (format.length === 0) || (format === 'i')) {
+ if (cultureInfo && (cultureInfo.name.length > 0)) {
+ return this.toLocaleString();
+ }
+ else {
+ return this.toString();
+ }
+ }
+
+ var _percentPositivePattern = ["n %", "n%", "%n" ];
+ var _percentNegativePattern = ["-n %", "-n%", "-%n"];
+ var _numberNegativePattern = ["(n)","-n","- n","n-","n -"];
+ var _currencyPositivePattern = ["$n","n$","$ n","n $"];
+ var _currencyNegativePattern = ["($n)","-$n","$-n","$n-","(n$)","-n$","n-$","n$-","-n $","-$ n","n $-","$ n-","$ -n","n- $","($ n)","(n $)"];
+ function zeroPad(str, count, left) {
+ for (var l=str.length; l < count; l++) {
+ str = (left ? ('0' + str) : (str + '0'));
+ }
+ return str;
+ }
+
+ function expandNumber(number, precision, groupSizes, sep, decimalChar) {
+ Sys.Debug.assert(groupSizes.length > 0, "groupSizes must be an array of at least 1");
+ var curSize = groupSizes[0];
+ var curGroupIndex = 1;
+ var factor = Math.pow(10, precision);
+ var rounded = (Math.round(number * factor) / factor);
+ if (!isFinite(rounded)) {
+ rounded = number;
+ }
+ number = rounded;
+
+ var numberString = number.toString();
+ var right = "";
+ var exponent;
+
+
+ var split = numberString.split(/e/i);
+ numberString = split[0];
+ exponent = (split.length > 1 ? parseInt(split[1]) : 0);
+ split = numberString.split('.');
+ numberString = split[0];
+ right = split.length > 1 ? split[1] : "";
+
+ var l;
+ if (exponent > 0) {
+ right = zeroPad(right, exponent, false);
+ numberString += right.slice(0, exponent);
+ right = right.substr(exponent);
+ }
+ else if (exponent < 0) {
+ exponent = -exponent;
+ numberString = zeroPad(numberString, exponent+1, true);
+ right = numberString.slice(-exponent, numberString.length) + right;
+ numberString = numberString.slice(0, -exponent);
+ }
+ if (precision > 0) {
+ if (right.length > precision) {
+ right = right.slice(0, precision);
+ }
+ else {
+ right = zeroPad(right, precision, false);
+ }
+ right = decimalChar + right;
+ }
+ else {
+ right = "";
+ }
+ var stringIndex = numberString.length-1;
+ var ret = "";
+ while (stringIndex >= 0) {
+ if (curSize === 0 || curSize > stringIndex) {
+ if (ret.length > 0)
+ return numberString.slice(0, stringIndex + 1) + sep + ret + right;
+ else
+ return numberString.slice(0, stringIndex + 1) + right;
+ }
+ if (ret.length > 0)
+ ret = numberString.slice(stringIndex - curSize + 1, stringIndex+1) + sep + ret;
+ else
+ ret = numberString.slice(stringIndex - curSize + 1, stringIndex+1);
+ stringIndex -= curSize;
+ if (curGroupIndex < groupSizes.length) {
+ curSize = groupSizes[curGroupIndex];
+ curGroupIndex++;
+ }
+ }
+ return numberString.slice(0, stringIndex + 1) + sep + ret + right;
+ }
+ var nf = cultureInfo.numberFormat;
+ var number = Math.abs(this);
+ if (!format)
+ format = "D";
+ var precision = -1;
+ if (format.length > 1) precision = parseInt(format.slice(1), 10);
+ var pattern;
+ switch (format.charAt(0)) {
+ case "d":
+ case "D":
+ pattern = 'n';
+ if (precision !== -1) {
+ number = zeroPad(""+number, precision, true);
+ }
+ if (this < 0) number = -number;
+ break;
+ case "c":
+ case "C":
+ if (this < 0) pattern = _currencyNegativePattern[nf.CurrencyNegativePattern];
+ else pattern = _currencyPositivePattern[nf.CurrencyPositivePattern];
+ if (precision === -1) precision = nf.CurrencyDecimalDigits;
+ number = expandNumber(Math.abs(this), precision, nf.CurrencyGroupSizes, nf.CurrencyGroupSeparator, nf.CurrencyDecimalSeparator);
+ break;
+ case "n":
+ case "N":
+ if (this < 0) pattern = _numberNegativePattern[nf.NumberNegativePattern];
+ else pattern = 'n';
+ if (precision === -1) precision = nf.NumberDecimalDigits;
+ number = expandNumber(Math.abs(this), precision, nf.NumberGroupSizes, nf.NumberGroupSeparator, nf.NumberDecimalSeparator);
+ break;
+ case "p":
+ case "P":
+ if (this < 0) pattern = _percentNegativePattern[nf.PercentNegativePattern];
+ else pattern = _percentPositivePattern[nf.PercentPositivePattern];
+ if (precision === -1) precision = nf.PercentDecimalDigits;
+ number = expandNumber(Math.abs(this) * 100, precision, nf.PercentGroupSizes, nf.PercentGroupSeparator, nf.PercentDecimalSeparator);
+ break;
+ default:
+ throw Error.format(Sys.Res.formatBadFormatSpecifier);
+ }
+ var regex = /n|\$|-|%/g;
+ var ret = "";
+ for (;;) {
+ var index = regex.lastIndex;
+ var ar = regex.exec(pattern);
+ ret += pattern.slice(index, ar ? ar.index : pattern.length);
+ if (!ar)
+ break;
+ switch (ar[0]) {
+ case "n":
+ ret += number;
+ break;
+ case "$":
+ ret += nf.CurrencySymbol;
+ break;
+ case "-":
+ if (/[1-9]/.test(number)) {
+ ret += nf.NegativeSign;
+ }
+ break;
+ case "%":
+ ret += nf.PercentSymbol;
+ break;
+ default:
+ Sys.Debug.fail("Invalid number format pattern");
+ }
+ }
+ return ret;
+}
+
+Sys.CultureInfo = function Sys$CultureInfo(name, numberFormat, dateTimeFormat) {
+ /// <summary locid="M:J#Sys.CultureInfo.#ctor" />
+ /// <param name="name" type="String"></param>
+ /// <param name="numberFormat" type="Object"></param>
+ /// <param name="dateTimeFormat" type="Object"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "name", type: String},
+ {name: "numberFormat", type: Object},
+ {name: "dateTimeFormat", type: Object}
+ ]);
+ if (e) throw e;
+ this.name = name;
+ this.numberFormat = numberFormat;
+ this.dateTimeFormat = dateTimeFormat;
+}
+ function Sys$CultureInfo$_getDateTimeFormats() {
+ if (! this._dateTimeFormats) {
+ var dtf = this.dateTimeFormat;
+ this._dateTimeFormats =
+ [ dtf.MonthDayPattern,
+ dtf.YearMonthPattern,
+ dtf.ShortDatePattern,
+ dtf.ShortTimePattern,
+ dtf.LongDatePattern,
+ dtf.LongTimePattern,
+ dtf.FullDateTimePattern,
+ dtf.RFC1123Pattern,
+ dtf.SortableDateTimePattern,
+ dtf.UniversalSortableDateTimePattern ];
+ }
+ return this._dateTimeFormats;
+ }
+ function Sys$CultureInfo$_getIndex(value, a1, a2) {
+ var upper = this._toUpper(value),
+ i = Array.indexOf(a1, upper);
+ if (i === -1) {
+ i = Array.indexOf(a2, upper);
+ }
+ return i;
+ }
+ function Sys$CultureInfo$_getMonthIndex(value) {
+ if (!this._upperMonths) {
+ this._upperMonths = this._toUpperArray(this.dateTimeFormat.MonthNames);
+ this._upperMonthsGenitive = this._toUpperArray(this.dateTimeFormat.MonthGenitiveNames);
+ }
+ return this._getIndex(value, this._upperMonths, this._upperMonthsGenitive);
+ }
+ function Sys$CultureInfo$_getAbbrMonthIndex(value) {
+ if (!this._upperAbbrMonths) {
+ this._upperAbbrMonths = this._toUpperArray(this.dateTimeFormat.AbbreviatedMonthNames);
+ this._upperAbbrMonthsGenitive = this._toUpperArray(this.dateTimeFormat.AbbreviatedMonthGenitiveNames);
+ }
+ return this._getIndex(value, this._upperAbbrMonths, this._upperAbbrMonthsGenitive);
+ }
+ function Sys$CultureInfo$_getDayIndex(value) {
+ if (!this._upperDays) {
+ this._upperDays = this._toUpperArray(this.dateTimeFormat.DayNames);
+ }
+ return Array.indexOf(this._upperDays, this._toUpper(value));
+ }
+ function Sys$CultureInfo$_getAbbrDayIndex(value) {
+ if (!this._upperAbbrDays) {
+ this._upperAbbrDays = this._toUpperArray(this.dateTimeFormat.AbbreviatedDayNames);
+ }
+ return Array.indexOf(this._upperAbbrDays, this._toUpper(value));
+ }
+ function Sys$CultureInfo$_toUpperArray(arr) {
+ var result = [];
+ for (var i = 0, il = arr.length; i < il; i++) {
+ result[i] = this._toUpper(arr[i]);
+ }
+ return result;
+ }
+ function Sys$CultureInfo$_toUpper(value) {
+ return value.split("\u00A0").join(' ').toUpperCase();
+ }
+Sys.CultureInfo.prototype = {
+ _getDateTimeFormats: Sys$CultureInfo$_getDateTimeFormats,
+ _getIndex: Sys$CultureInfo$_getIndex,
+ _getMonthIndex: Sys$CultureInfo$_getMonthIndex,
+ _getAbbrMonthIndex: Sys$CultureInfo$_getAbbrMonthIndex,
+ _getDayIndex: Sys$CultureInfo$_getDayIndex,
+ _getAbbrDayIndex: Sys$CultureInfo$_getAbbrDayIndex,
+ _toUpperArray: Sys$CultureInfo$_toUpperArray,
+ _toUpper: Sys$CultureInfo$_toUpper
+}
+Sys.CultureInfo.registerClass('Sys.CultureInfo');
+Sys.CultureInfo._parse = function Sys$CultureInfo$_parse(value) {
+ var dtf = value.dateTimeFormat;
+ if (dtf && !dtf.eras) {
+ dtf.eras = value.eras;
+ }
+ return new Sys.CultureInfo(value.name, value.numberFormat, dtf);
+}
+Sys.CultureInfo.InvariantCulture = Sys.CultureInfo._parse({"name":"","numberFormat":{"CurrencyDecimalDigits":2,"CurrencyDecimalSeparator":".","IsReadOnly":true,"CurrencyGroupSizes":[3],"NumberGroupSizes":[3],"PercentGroupSizes":[3],"CurrencyGroupSeparator":",","CurrencySymbol":"\u00A4","NaNSymbol":"NaN","CurrencyNegativePattern":0,"NumberNegativePattern":1,"PercentPositivePattern":0,"PercentNegativePattern":0,"NegativeInfinitySymbol":"-Infinity","NegativeSign":"-","NumberDecimalDigits":2,"NumberDecimalSeparator":".","NumberGroupSeparator":",","CurrencyPositivePattern":0,"PositiveInfinitySymbol":"Infinity","PositiveSign":"+","PercentDecimalDigits":2,"PercentDecimalSeparator":".","PercentGroupSeparator":",","PercentSymbol":"%","PerMilleSymbol":"\u2030","NativeDigits":["0","1","2","3","4","5","6","7","8","9"],"DigitSubstitution":1},"dateTimeFormat":{"AMDesignator":"AM","Calendar":{"MinSupportedDateTime":"@-62135568000000@","MaxSupportedDateTime":"@253402300799999@","AlgorithmType":1,"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2029,"IsReadOnly":true},"DateSeparator":"/","FirstDayOfWeek":0,"CalendarWeekRule":0,"FullDateTimePattern":"dddd, dd MMMM yyyy HH:mm:ss","LongDatePattern":"dddd, dd MMMM yyyy","LongTimePattern":"HH:mm:ss","MonthDayPattern":"MMMM dd","PMDesignator":"PM","RFC1123Pattern":"ddd, dd MMM yyyy HH\':\'mm\':\'ss \'GMT\'","ShortDatePattern":"MM/dd/yyyy","ShortTimePattern":"HH:mm","SortableDateTimePattern":"yyyy\'-\'MM\'-\'dd\'T\'HH\':\'mm\':\'ss","TimeSeparator":":","UniversalSortableDateTimePattern":"yyyy\'-\'MM\'-\'dd HH\':\'mm\':\'ss\'Z\'","YearMonthPattern":"yyyy MMMM","AbbreviatedDayNames":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"ShortestDayNames":["Su","Mo","Tu","We","Th","Fr","Sa"],"DayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"AbbreviatedMonthNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"IsReadOnly":true,"NativeCalendarName":"Gregorian Calendar","AbbreviatedMonthGenitiveNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthGenitiveNames":["January","February","March","April","May","June","July","August","September","October","November","December",""]},"eras":[1,"A.D.",null,0]});
+if (typeof(__cultureInfo) === "object") {
+ Sys.CultureInfo.CurrentCulture = Sys.CultureInfo._parse(__cultureInfo);
+ delete __cultureInfo;
+}
+else {
+ Sys.CultureInfo.CurrentCulture = Sys.CultureInfo._parse({"name":"en-US","numberFormat":{"CurrencyDecimalDigits":2,"CurrencyDecimalSeparator":".","IsReadOnly":false,"CurrencyGroupSizes":[3],"NumberGroupSizes":[3],"PercentGroupSizes":[3],"CurrencyGroupSeparator":",","CurrencySymbol":"$","NaNSymbol":"NaN","CurrencyNegativePattern":0,"NumberNegativePattern":1,"PercentPositivePattern":0,"PercentNegativePattern":0,"NegativeInfinitySymbol":"-Infinity","NegativeSign":"-","NumberDecimalDigits":2,"NumberDecimalSeparator":".","NumberGroupSeparator":",","CurrencyPositivePattern":0,"PositiveInfinitySymbol":"Infinity","PositiveSign":"+","PercentDecimalDigits":2,"PercentDecimalSeparator":".","PercentGroupSeparator":",","PercentSymbol":"%","PerMilleSymbol":"\u2030","NativeDigits":["0","1","2","3","4","5","6","7","8","9"],"DigitSubstitution":1},"dateTimeFormat":{"AMDesignator":"AM","Calendar":{"MinSupportedDateTime":"@-62135568000000@","MaxSupportedDateTime":"@253402300799999@","AlgorithmType":1,"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2029,"IsReadOnly":false},"DateSeparator":"/","FirstDayOfWeek":0,"CalendarWeekRule":0,"FullDateTimePattern":"dddd, MMMM dd, yyyy h:mm:ss tt","LongDatePattern":"dddd, MMMM dd, yyyy","LongTimePattern":"h:mm:ss tt","MonthDayPattern":"MMMM dd","PMDesignator":"PM","RFC1123Pattern":"ddd, dd MMM yyyy HH\':\'mm\':\'ss \'GMT\'","ShortDatePattern":"M/d/yyyy","ShortTimePattern":"h:mm tt","SortableDateTimePattern":"yyyy\'-\'MM\'-\'dd\'T\'HH\':\'mm\':\'ss","TimeSeparator":":","UniversalSortableDateTimePattern":"yyyy\'-\'MM\'-\'dd HH\':\'mm\':\'ss\'Z\'","YearMonthPattern":"MMMM, yyyy","AbbreviatedDayNames":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"ShortestDayNames":["Su","Mo","Tu","We","Th","Fr","Sa"],"DayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"AbbreviatedMonthNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"IsReadOnly":false,"NativeCalendarName":"Gregorian Calendar","AbbreviatedMonthGenitiveNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthGenitiveNames":["January","February","March","April","May","June","July","August","September","October","November","December",""]},"eras":[1,"A.D.",null,0]});
+}
+Type.registerNamespace('Sys.Serialization');
+Sys.Serialization.JavaScriptSerializer = function Sys$Serialization$JavaScriptSerializer() {
+ /// <summary locid="M:J#Sys.Serialization.JavaScriptSerializer.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+}
+Sys.Serialization.JavaScriptSerializer.registerClass('Sys.Serialization.JavaScriptSerializer');
+Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs = [];
+Sys.Serialization.JavaScriptSerializer._charsToEscape = [];
+Sys.Serialization.JavaScriptSerializer._dateRegEx = new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)(?:[a-zA-Z]|(?:\\+|-)[0-9]{4})?\\)\\\\/\\"', 'g');
+Sys.Serialization.JavaScriptSerializer._escapeChars = {};
+Sys.Serialization.JavaScriptSerializer._escapeRegEx = new RegExp('["\\\\\\x00-\\x1F]', 'i');
+Sys.Serialization.JavaScriptSerializer._escapeRegExGlobal = new RegExp('["\\\\\\x00-\\x1F]', 'g');
+Sys.Serialization.JavaScriptSerializer._jsonRegEx = new RegExp('[^,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t]', 'g');
+Sys.Serialization.JavaScriptSerializer._jsonStringRegEx = new RegExp('"(\\\\.|[^"\\\\])*"', 'g');
+Sys.Serialization.JavaScriptSerializer._serverTypeFieldName = '__type';
+Sys.Serialization.JavaScriptSerializer._init = function Sys$Serialization$JavaScriptSerializer$_init() {
+ var replaceChars = ['\\u0000','\\u0001','\\u0002','\\u0003','\\u0004','\\u0005','\\u0006','\\u0007',
+ '\\b','\\t','\\n','\\u000b','\\f','\\r','\\u000e','\\u000f','\\u0010','\\u0011',
+ '\\u0012','\\u0013','\\u0014','\\u0015','\\u0016','\\u0017','\\u0018','\\u0019',
+ '\\u001a','\\u001b','\\u001c','\\u001d','\\u001e','\\u001f'];
+ Sys.Serialization.JavaScriptSerializer._charsToEscape[0] = '\\';
+ Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs['\\'] = new RegExp('\\\\', 'g');
+ Sys.Serialization.JavaScriptSerializer._escapeChars['\\'] = '\\\\';
+ Sys.Serialization.JavaScriptSerializer._charsToEscape[1] = '"';
+ Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs['"'] = new RegExp('"', 'g');
+ Sys.Serialization.JavaScriptSerializer._escapeChars['"'] = '\\"';
+ for (var i = 0; i < 32; i++) {
+ var c = String.fromCharCode(i);
+ Sys.Serialization.JavaScriptSerializer._charsToEscape[i+2] = c;
+ Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs[c] = new RegExp(c, 'g');
+ Sys.Serialization.JavaScriptSerializer._escapeChars[c] = replaceChars[i];
+ }
+}
+Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder = function Sys$Serialization$JavaScriptSerializer$_serializeBooleanWithBuilder(object, stringBuilder) {
+ stringBuilder.append(object.toString());
+}
+Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder = function Sys$Serialization$JavaScriptSerializer$_serializeNumberWithBuilder(object, stringBuilder) {
+ if (isFinite(object)) {
+ stringBuilder.append(String(object));
+ }
+ else {
+ throw Error.invalidOperation(Sys.Res.cannotSerializeNonFiniteNumbers);
+ }
+}
+Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder = function Sys$Serialization$JavaScriptSerializer$_serializeStringWithBuilder(string, stringBuilder) {
+ stringBuilder.append('"');
+ if (Sys.Serialization.JavaScriptSerializer._escapeRegEx.test(string)) {
+ if (Sys.Serialization.JavaScriptSerializer._charsToEscape.length === 0) {
+ Sys.Serialization.JavaScriptSerializer._init();
+ }
+ if (string.length < 128) {
+ string = string.replace(Sys.Serialization.JavaScriptSerializer._escapeRegExGlobal,
+ function(x) { return Sys.Serialization.JavaScriptSerializer._escapeChars[x]; });
+ }
+ else {
+ for (var i = 0; i < 34; i++) {
+ var c = Sys.Serialization.JavaScriptSerializer._charsToEscape[i];
+ if (string.indexOf(c) !== -1) {
+ if (Sys.Browser.agent === Sys.Browser.Opera || Sys.Browser.agent === Sys.Browser.FireFox) {
+ string = string.split(c).join(Sys.Serialization.JavaScriptSerializer._escapeChars[c]);
+ }
+ else {
+ string = string.replace(Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs[c],
+ Sys.Serialization.JavaScriptSerializer._escapeChars[c]);
+ }
+ }
+ }
+ }
+ }
+ stringBuilder.append(string);
+ stringBuilder.append('"');
+}
+Sys.Serialization.JavaScriptSerializer._serializeWithBuilder = function Sys$Serialization$JavaScriptSerializer$_serializeWithBuilder(object, stringBuilder, sort, prevObjects) {
+ var i;
+ switch (typeof object) {
+ case 'object':
+ if (object) {
+ if (prevObjects){
+ for( var j = 0; j < prevObjects.length; j++) {
+ if (prevObjects[j] === object) {
+ throw Error.invalidOperation(Sys.Res.cannotSerializeObjectWithCycle);
+ }
+ }
+ }
+ else {
+ prevObjects = new Array();
+ }
+ try {
+ Array.add(prevObjects, object);
+
+ if (Number.isInstanceOfType(object)){
+ Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder(object, stringBuilder);
+ }
+ else if (Boolean.isInstanceOfType(object)){
+ Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder(object, stringBuilder);
+ }
+ else if (String.isInstanceOfType(object)){
+ Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder(object, stringBuilder);
+ }
+
+ else if (Array.isInstanceOfType(object)) {
+ stringBuilder.append('[');
+
+ for (i = 0; i < object.length; ++i) {
+ if (i > 0) {
+ stringBuilder.append(',');
+ }
+ Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(object[i], stringBuilder,false,prevObjects);
+ }
+ stringBuilder.append(']');
+ }
+ else {
+ if (Date.isInstanceOfType(object)) {
+ stringBuilder.append('"\\/Date(');
+ stringBuilder.append(object.getTime());
+ stringBuilder.append(')\\/"');
+ break;
+ }
+ var properties = [];
+ var propertyCount = 0;
+ for (var name in object) {
+ if (name.startsWith('$')) {
+ continue;
+ }
+ if (name === Sys.Serialization.JavaScriptSerializer._serverTypeFieldName && propertyCount !== 0){
+ properties[propertyCount++] = properties[0];
+ properties[0] = name;
+ }
+ else{
+ properties[propertyCount++] = name;
+ }
+ }
+ if (sort) properties.sort();
+ stringBuilder.append('{');
+ var needComma = false;
+
+ for (i=0; i<propertyCount; i++) {
+ var value = object[properties[i]];
+ if (typeof value !== 'undefined' && typeof value !== 'function') {
+ if (needComma) {
+ stringBuilder.append(',');
+ }
+ else {
+ needComma = true;
+ }
+
+ Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(properties[i], stringBuilder, sort, prevObjects);
+ stringBuilder.append(':');
+ Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(value, stringBuilder, sort, prevObjects);
+
+ }
+ }
+ stringBuilder.append('}');
+ }
+ }
+ finally {
+ Array.removeAt(prevObjects, prevObjects.length - 1);
+ }
+ }
+ else {
+ stringBuilder.append('null');
+ }
+ break;
+ case 'number':
+ Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder(object, stringBuilder);
+ break;
+ case 'string':
+ Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder(object, stringBuilder);
+ break;
+ case 'boolean':
+ Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder(object, stringBuilder);
+ break;
+ default:
+ stringBuilder.append('null');
+ break;
+ }
+}
+Sys.Serialization.JavaScriptSerializer.serialize = function Sys$Serialization$JavaScriptSerializer$serialize(object) {
+ /// <summary locid="M:J#Sys.Serialization.JavaScriptSerializer.serialize" />
+ /// <param name="object" mayBeNull="true"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "object", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ var stringBuilder = new Sys.StringBuilder();
+ Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(object, stringBuilder, false);
+ return stringBuilder.toString();
+}
+Sys.Serialization.JavaScriptSerializer.deserialize = function Sys$Serialization$JavaScriptSerializer$deserialize(data, secure) {
+ /// <summary locid="M:J#Sys.Serialization.JavaScriptSerializer.deserialize" />
+ /// <param name="data" type="String"></param>
+ /// <param name="secure" type="Boolean" optional="true"></param>
+ /// <returns></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "data", type: String},
+ {name: "secure", type: Boolean, optional: true}
+ ]);
+ if (e) throw e;
+
+ if (data.length === 0) throw Error.argument('data', Sys.Res.cannotDeserializeEmptyString);
+ try {
+ var exp = data.replace(Sys.Serialization.JavaScriptSerializer._dateRegEx, "$1new Date($2)");
+
+ if (secure && Sys.Serialization.JavaScriptSerializer._jsonRegEx.test(
+ exp.replace(Sys.Serialization.JavaScriptSerializer._jsonStringRegEx, ''))) throw null;
+ return eval('(' + exp + ')');
+ }
+ catch (e) {
+ throw Error.argument('data', Sys.Res.cannotDeserializeInvalidJson);
+ }
+}
+Type.registerNamespace('Sys.UI');
+
+Sys.EventHandlerList = function Sys$EventHandlerList() {
+ /// <summary locid="M:J#Sys.EventHandlerList.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ this._list = {};
+}
+ function Sys$EventHandlerList$_addHandler(id, handler) {
+ Array.add(this._getEvent(id, true), handler);
+ }
+ function Sys$EventHandlerList$addHandler(id, handler) {
+ /// <summary locid="M:J#Sys.EventHandlerList.addHandler" />
+ /// <param name="id" type="String"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "id", type: String},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ this._addHandler(id, handler);
+ }
+ function Sys$EventHandlerList$_removeHandler(id, handler) {
+ var evt = this._getEvent(id);
+ if (!evt) return;
+ Array.remove(evt, handler);
+ }
+ function Sys$EventHandlerList$removeHandler(id, handler) {
+ /// <summary locid="M:J#Sys.EventHandlerList.removeHandler" />
+ /// <param name="id" type="String"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "id", type: String},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ this._removeHandler(id, handler);
+ }
+ function Sys$EventHandlerList$getHandler(id) {
+ /// <summary locid="M:J#Sys.EventHandlerList.getHandler" />
+ /// <param name="id" type="String"></param>
+ /// <returns type="Function"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "id", type: String}
+ ]);
+ if (e) throw e;
+ var evt = this._getEvent(id);
+ if (!evt || (evt.length === 0)) return null;
+ evt = Array.clone(evt);
+ return function(source, args) {
+ for (var i = 0, l = evt.length; i < l; i++) {
+ evt[i](source, args);
+ }
+ };
+ }
+ function Sys$EventHandlerList$_getEvent(id, create) {
+ if (!this._list[id]) {
+ if (!create) return null;
+ this._list[id] = [];
+ }
+ return this._list[id];
+ }
+Sys.EventHandlerList.prototype = {
+ _addHandler: Sys$EventHandlerList$_addHandler,
+ addHandler: Sys$EventHandlerList$addHandler,
+ _removeHandler: Sys$EventHandlerList$_removeHandler,
+ removeHandler: Sys$EventHandlerList$removeHandler,
+ getHandler: Sys$EventHandlerList$getHandler,
+ _getEvent: Sys$EventHandlerList$_getEvent
+}
+Sys.EventHandlerList.registerClass('Sys.EventHandlerList');
+Sys.CommandEventArgs = function Sys$CommandEventArgs(commandName, commandArgument, commandSource) {
+ /// <summary locid="M:J#Sys.CommandEventArgs.#ctor" />
+ /// <param name="commandName" type="String"></param>
+ /// <param name="commandArgument" mayBeNull="true"></param>
+ /// <param name="commandSource" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "commandName", type: String},
+ {name: "commandArgument", mayBeNull: true},
+ {name: "commandSource", mayBeNull: true}
+ ]);
+ if (e) throw e;
+ Sys.CommandEventArgs.initializeBase(this);
+ this._commandName = commandName;
+ this._commandArgument = commandArgument;
+ this._commandSource = commandSource;
+}
+ function Sys$CommandEventArgs$get_commandName() {
+ /// <value type="String" locid="P:J#Sys.CommandEventArgs.commandName"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._commandName;
+ }
+ function Sys$CommandEventArgs$get_commandArgument() {
+ /// <value mayBeNull="true" locid="P:J#Sys.CommandEventArgs.commandArgument"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._commandArgument;
+ }
+ function Sys$CommandEventArgs$get_commandSource() {
+ /// <value mayBeNull="true" locid="P:J#Sys.CommandEventArgs.commandSource"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._commandSource;
+ }
+Sys.CommandEventArgs.prototype = {
+ _commandName: null,
+ _commandArgument: null,
+ _commandSource: null,
+ get_commandName: Sys$CommandEventArgs$get_commandName,
+ get_commandArgument: Sys$CommandEventArgs$get_commandArgument,
+ get_commandSource: Sys$CommandEventArgs$get_commandSource
+}
+Sys.CommandEventArgs.registerClass("Sys.CommandEventArgs", Sys.CancelEventArgs);
+
+Sys.INotifyPropertyChange = function Sys$INotifyPropertyChange() {
+ /// <summary locid="M:J#Sys.INotifyPropertyChange.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+}
+ function Sys$INotifyPropertyChange$add_propertyChanged(handler) {
+ /// <summary locid="E:J#Sys.INotifyPropertyChange.propertyChanged" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ throw Error.notImplemented();
+ }
+ function Sys$INotifyPropertyChange$remove_propertyChanged(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ throw Error.notImplemented();
+ }
+Sys.INotifyPropertyChange.prototype = {
+ add_propertyChanged: Sys$INotifyPropertyChange$add_propertyChanged,
+ remove_propertyChanged: Sys$INotifyPropertyChange$remove_propertyChanged
+}
+Sys.INotifyPropertyChange.registerInterface('Sys.INotifyPropertyChange');
+
+Sys.PropertyChangedEventArgs = function Sys$PropertyChangedEventArgs(propertyName) {
+ /// <summary locid="M:J#Sys.PropertyChangedEventArgs.#ctor" />
+ /// <param name="propertyName" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "propertyName", type: String}
+ ]);
+ if (e) throw e;
+ Sys.PropertyChangedEventArgs.initializeBase(this);
+ this._propertyName = propertyName;
+}
+
+ function Sys$PropertyChangedEventArgs$get_propertyName() {
+ /// <value type="String" locid="P:J#Sys.PropertyChangedEventArgs.propertyName"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._propertyName;
+ }
+Sys.PropertyChangedEventArgs.prototype = {
+ get_propertyName: Sys$PropertyChangedEventArgs$get_propertyName
+}
+Sys.PropertyChangedEventArgs.registerClass('Sys.PropertyChangedEventArgs', Sys.EventArgs);
+
+Sys.INotifyDisposing = function Sys$INotifyDisposing() {
+ /// <summary locid="M:J#Sys.INotifyDisposing.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+}
+ function Sys$INotifyDisposing$add_disposing(handler) {
+ /// <summary locid="E:J#Sys.INotifyDisposing.disposing" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ throw Error.notImplemented();
+ }
+ function Sys$INotifyDisposing$remove_disposing(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ throw Error.notImplemented();
+ }
+Sys.INotifyDisposing.prototype = {
+ add_disposing: Sys$INotifyDisposing$add_disposing,
+ remove_disposing: Sys$INotifyDisposing$remove_disposing
+}
+Sys.INotifyDisposing.registerInterface("Sys.INotifyDisposing");
+
+Sys.Component = function Sys$Component() {
+ /// <summary locid="M:J#Sys.Component.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (Sys.Application) Sys.Application.registerDisposableObject(this);
+}
+ function Sys$Component$get_events() {
+ /// <value type="Sys.EventHandlerList" locid="P:J#Sys.Component.events"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._events) {
+ this._events = new Sys.EventHandlerList();
+ }
+ return this._events;
+ }
+ function Sys$Component$get_id() {
+ /// <value type="String" locid="P:J#Sys.Component.id"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._id;
+ }
+ function Sys$Component$set_id(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: String}]);
+ if (e) throw e;
+ if (this._idSet) throw Error.invalidOperation(Sys.Res.componentCantSetIdTwice);
+ this._idSet = true;
+ var oldId = this.get_id();
+ if (oldId && Sys.Application.findComponent(oldId)) throw Error.invalidOperation(Sys.Res.componentCantSetIdAfterAddedToApp);
+ this._id = value;
+ }
+ function Sys$Component$get_isInitialized() {
+ /// <value type="Boolean" locid="P:J#Sys.Component.isInitialized"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._initialized;
+ }
+ function Sys$Component$get_isUpdating() {
+ /// <value type="Boolean" locid="P:J#Sys.Component.isUpdating"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._updating;
+ }
+ function Sys$Component$add_disposing(handler) {
+ /// <summary locid="E:J#Sys.Component.disposing" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().addHandler("disposing", handler);
+ }
+ function Sys$Component$remove_disposing(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().removeHandler("disposing", handler);
+ }
+ function Sys$Component$add_propertyChanged(handler) {
+ /// <summary locid="E:J#Sys.Component.propertyChanged" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().addHandler("propertyChanged", handler);
+ }
+ function Sys$Component$remove_propertyChanged(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().removeHandler("propertyChanged", handler);
+ }
+ function Sys$Component$beginUpdate() {
+ this._updating = true;
+ }
+ function Sys$Component$dispose() {
+ if (this._events) {
+ var handler = this._events.getHandler("disposing");
+ if (handler) {
+ handler(this, Sys.EventArgs.Empty);
+ }
+ }
+ delete this._events;
+ Sys.Application.unregisterDisposableObject(this);
+ Sys.Application.removeComponent(this);
+ }
+ function Sys$Component$endUpdate() {
+ this._updating = false;
+ if (!this._initialized) this.initialize();
+ this.updated();
+ }
+ function Sys$Component$initialize() {
+ this._initialized = true;
+ }
+ function Sys$Component$raisePropertyChanged(propertyName) {
+ /// <summary locid="M:J#Sys.Component.raisePropertyChanged" />
+ /// <param name="propertyName" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "propertyName", type: String}
+ ]);
+ if (e) throw e;
+ if (!this._events) return;
+ var handler = this._events.getHandler("propertyChanged");
+ if (handler) {
+ handler(this, new Sys.PropertyChangedEventArgs(propertyName));
+ }
+ }
+ function Sys$Component$updated() {
+ }
+Sys.Component.prototype = {
+ _id: null,
+ _idSet: false,
+ _initialized: false,
+ _updating: false,
+ get_events: Sys$Component$get_events,
+ get_id: Sys$Component$get_id,
+ set_id: Sys$Component$set_id,
+ get_isInitialized: Sys$Component$get_isInitialized,
+ get_isUpdating: Sys$Component$get_isUpdating,
+ add_disposing: Sys$Component$add_disposing,
+ remove_disposing: Sys$Component$remove_disposing,
+ add_propertyChanged: Sys$Component$add_propertyChanged,
+ remove_propertyChanged: Sys$Component$remove_propertyChanged,
+ beginUpdate: Sys$Component$beginUpdate,
+ dispose: Sys$Component$dispose,
+ endUpdate: Sys$Component$endUpdate,
+ initialize: Sys$Component$initialize,
+ raisePropertyChanged: Sys$Component$raisePropertyChanged,
+ updated: Sys$Component$updated
+}
+Sys.Component.registerClass('Sys.Component', null, Sys.IDisposable, Sys.INotifyPropertyChange, Sys.INotifyDisposing);
+function Sys$Component$_setProperties(target, properties) {
+ /// <summary locid="M:J#Sys.Component._setProperties" />
+ /// <param name="target"></param>
+ /// <param name="properties"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "target"},
+ {name: "properties"}
+ ]);
+ if (e) throw e;
+ var current;
+ var targetType = Object.getType(target);
+ var isObject = (targetType === Object) || (targetType === Sys.UI.DomElement);
+ var isComponent = Sys.Component.isInstanceOfType(target) && !target.get_isUpdating();
+ if (isComponent) target.beginUpdate();
+ for (var name in properties) {
+ var val = properties[name];
+ var getter = isObject ? null : target["get_" + name];
+ if (isObject || typeof(getter) !== 'function') {
+ var targetVal = target[name];
+ if (!isObject && typeof(targetVal) === 'undefined') throw Error.invalidOperation(String.format(Sys.Res.propertyUndefined, name));
+ if (!val || (typeof(val) !== 'object') || (isObject && !targetVal)) {
+ target[name] = val;
+ }
+ else {
+ Sys$Component$_setProperties(targetVal, val);
+ }
+ }
+ else {
+ var setter = target["set_" + name];
+ if (typeof(setter) === 'function') {
+ setter.apply(target, [val]);
+ }
+ else if (val instanceof Array) {
+ current = getter.apply(target);
+ if (!(current instanceof Array)) throw new Error.invalidOperation(String.format(Sys.Res.propertyNotAnArray, name));
+ for (var i = 0, j = current.length, l= val.length; i < l; i++, j++) {
+ current[j] = val[i];
+ }
+ }
+ else if ((typeof(val) === 'object') && (Object.getType(val) === Object)) {
+ current = getter.apply(target);
+ if ((typeof(current) === 'undefined') || (current === null)) throw new Error.invalidOperation(String.format(Sys.Res.propertyNullOrUndefined, name));
+ Sys$Component$_setProperties(current, val);
+ }
+ else {
+ throw new Error.invalidOperation(String.format(Sys.Res.propertyNotWritable, name));
+ }
+ }
+ }
+ if (isComponent) target.endUpdate();
+}
+function Sys$Component$_setReferences(component, references) {
+ for (var name in references) {
+ var setter = component["set_" + name];
+ var reference = $find(references[name]);
+ if (typeof(setter) !== 'function') throw new Error.invalidOperation(String.format(Sys.Res.propertyNotWritable, name));
+ if (!reference) throw Error.invalidOperation(String.format(Sys.Res.referenceNotFound, references[name]));
+ setter.apply(component, [reference]);
+ }
+}
+var $create = Sys.Component.create = function Sys$Component$create(type, properties, events, references, element) {
+ /// <summary locid="M:J#Sys.Component.create" />
+ /// <param name="type" type="Type"></param>
+ /// <param name="properties" optional="true" mayBeNull="true"></param>
+ /// <param name="events" optional="true" mayBeNull="true"></param>
+ /// <param name="references" optional="true" mayBeNull="true"></param>
+ /// <param name="element" domElement="true" optional="true" mayBeNull="true"></param>
+ /// <returns type="Sys.UI.Component"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "type", type: Type},
+ {name: "properties", mayBeNull: true, optional: true},
+ {name: "events", mayBeNull: true, optional: true},
+ {name: "references", mayBeNull: true, optional: true},
+ {name: "element", mayBeNull: true, domElement: true, optional: true}
+ ]);
+ if (e) throw e;
+ if (!type.inheritsFrom(Sys.Component)) {
+ throw Error.argument('type', String.format(Sys.Res.createNotComponent, type.getName()));
+ }
+ if (type.inheritsFrom(Sys.UI.Behavior) || type.inheritsFrom(Sys.UI.Control)) {
+ if (!element) throw Error.argument('element', Sys.Res.createNoDom);
+ }
+ else if (element) throw Error.argument('element', Sys.Res.createComponentOnDom);
+ var component = (element ? new type(element): new type());
+ var app = Sys.Application;
+ var creatingComponents = app.get_isCreatingComponents();
+ component.beginUpdate();
+ if (properties) {
+ Sys$Component$_setProperties(component, properties);
+ }
+ if (events) {
+ for (var name in events) {
+ if (!(component["add_" + name] instanceof Function)) throw new Error.invalidOperation(String.format(Sys.Res.undefinedEvent, name));
+ if (!(events[name] instanceof Function)) throw new Error.invalidOperation(Sys.Res.eventHandlerNotFunction);
+ component["add_" + name](events[name]);
+ }
+ }
+ if (component.get_id()) {
+ app.addComponent(component);
+ }
+ if (creatingComponents) {
+ app._createdComponents[app._createdComponents.length] = component;
+ if (references) {
+ app._addComponentToSecondPass(component, references);
+ }
+ else {
+ component.endUpdate();
+ }
+ }
+ else {
+ if (references) {
+ Sys$Component$_setReferences(component, references);
+ }
+ component.endUpdate();
+ }
+ return component;
+}
+
+Sys.UI.MouseButton = function Sys$UI$MouseButton() {
+ /// <summary locid="M:J#Sys.UI.MouseButton.#ctor" />
+ /// <field name="leftButton" type="Number" integer="true" static="true" locid="F:J#Sys.UI.MouseButton.leftButton"></field>
+ /// <field name="middleButton" type="Number" integer="true" static="true" locid="F:J#Sys.UI.MouseButton.middleButton"></field>
+ /// <field name="rightButton" type="Number" integer="true" static="true" locid="F:J#Sys.UI.MouseButton.rightButton"></field>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+}
+Sys.UI.MouseButton.prototype = {
+ leftButton: 0,
+ middleButton: 1,
+ rightButton: 2
+}
+Sys.UI.MouseButton.registerEnum("Sys.UI.MouseButton");
+
+Sys.UI.Key = function Sys$UI$Key() {
+ /// <summary locid="M:J#Sys.UI.Key.#ctor" />
+ /// <field name="backspace" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.backspace"></field>
+ /// <field name="tab" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.tab"></field>
+ /// <field name="enter" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.enter"></field>
+ /// <field name="esc" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.esc"></field>
+ /// <field name="space" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.space"></field>
+ /// <field name="pageUp" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.pageUp"></field>
+ /// <field name="pageDown" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.pageDown"></field>
+ /// <field name="end" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.end"></field>
+ /// <field name="home" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.home"></field>
+ /// <field name="left" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.left"></field>
+ /// <field name="up" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.up"></field>
+ /// <field name="right" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.right"></field>
+ /// <field name="down" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.down"></field>
+ /// <field name="del" type="Number" integer="true" static="true" locid="F:J#Sys.UI.Key.del"></field>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+}
+Sys.UI.Key.prototype = {
+ backspace: 8,
+ tab: 9,
+ enter: 13,
+ esc: 27,
+ space: 32,
+ pageUp: 33,
+ pageDown: 34,
+ end: 35,
+ home: 36,
+ left: 37,
+ up: 38,
+ right: 39,
+ down: 40,
+ del: 127
+}
+Sys.UI.Key.registerEnum("Sys.UI.Key");
+
+Sys.UI.Point = function Sys$UI$Point(x, y) {
+ /// <summary locid="M:J#Sys.UI.Point.#ctor" />
+ /// <param name="x" type="Number" integer="true"></param>
+ /// <param name="y" type="Number" integer="true"></param>
+ /// <field name="x" type="Number" integer="true" locid="F:J#Sys.UI.Point.x"></field>
+ /// <field name="y" type="Number" integer="true" locid="F:J#Sys.UI.Point.y"></field>
+ var e = Function._validateParams(arguments, [
+ {name: "x", type: Number, integer: true},
+ {name: "y", type: Number, integer: true}
+ ]);
+ if (e) throw e;
+ this.x = x;
+ this.y = y;
+}
+Sys.UI.Point.registerClass('Sys.UI.Point');
+
+Sys.UI.Bounds = function Sys$UI$Bounds(x, y, width, height) {
+ /// <summary locid="M:J#Sys.UI.Bounds.#ctor" />
+ /// <param name="x" type="Number" integer="true"></param>
+ /// <param name="y" type="Number" integer="true"></param>
+ /// <param name="width" type="Number" integer="true"></param>
+ /// <param name="height" type="Number" integer="true"></param>
+ /// <field name="x" type="Number" integer="true" locid="F:J#Sys.UI.Bounds.x"></field>
+ /// <field name="y" type="Number" integer="true" locid="F:J#Sys.UI.Bounds.y"></field>
+ /// <field name="width" type="Number" integer="true" locid="F:J#Sys.UI.Bounds.width"></field>
+ /// <field name="height" type="Number" integer="true" locid="F:J#Sys.UI.Bounds.height"></field>
+ var e = Function._validateParams(arguments, [
+ {name: "x", type: Number, integer: true},
+ {name: "y", type: Number, integer: true},
+ {name: "width", type: Number, integer: true},
+ {name: "height", type: Number, integer: true}
+ ]);
+ if (e) throw e;
+ this.x = x;
+ this.y = y;
+ this.height = height;
+ this.width = width;
+}
+Sys.UI.Bounds.registerClass('Sys.UI.Bounds');
+
+Sys.UI.DomEvent = function Sys$UI$DomEvent(eventObject) {
+ /// <summary locid="M:J#Sys.UI.DomEvent.#ctor" />
+ /// <param name="eventObject"></param>
+ /// <field name="altKey" type="Boolean" locid="F:J#Sys.UI.DomEvent.altKey"></field>
+ /// <field name="button" type="Sys.UI.MouseButton" locid="F:J#Sys.UI.DomEvent.button"></field>
+ /// <field name="charCode" type="Number" integer="true" locid="F:J#Sys.UI.DomEvent.charCode"></field>
+ /// <field name="clientX" type="Number" integer="true" locid="F:J#Sys.UI.DomEvent.clientX"></field>
+ /// <field name="clientY" type="Number" integer="true" locid="F:J#Sys.UI.DomEvent.clientY"></field>
+ /// <field name="ctrlKey" type="Boolean" locid="F:J#Sys.UI.DomEvent.ctrlKey"></field>
+ /// <field name="keyCode" type="Number" integer="true" locid="F:J#Sys.UI.DomEvent.keyCode"></field>
+ /// <field name="offsetX" type="Number" integer="true" locid="F:J#Sys.UI.DomEvent.offsetX"></field>
+ /// <field name="offsetY" type="Number" integer="true" locid="F:J#Sys.UI.DomEvent.offsetY"></field>
+ /// <field name="screenX" type="Number" integer="true" locid="F:J#Sys.UI.DomEvent.screenX"></field>
+ /// <field name="screenY" type="Number" integer="true" locid="F:J#Sys.UI.DomEvent.screenY"></field>
+ /// <field name="shiftKey" type="Boolean" locid="F:J#Sys.UI.DomEvent.shiftKey"></field>
+ /// <field name="target" locid="F:J#Sys.UI.DomEvent.target"></field>
+ /// <field name="type" type="String" locid="F:J#Sys.UI.DomEvent.type"></field>
+ var e = Function._validateParams(arguments, [
+ {name: "eventObject"}
+ ]);
+ if (e) throw e;
+ var ev = eventObject;
+ var etype = this.type = ev.type.toLowerCase();
+ this.rawEvent = ev;
+ this.altKey = ev.altKey;
+ if (typeof(ev.button) !== 'undefined') {
+ this.button = (typeof(ev.which) !== 'undefined') ? ev.button :
+ (ev.button === 4) ? Sys.UI.MouseButton.middleButton :
+ (ev.button === 2) ? Sys.UI.MouseButton.rightButton :
+ Sys.UI.MouseButton.leftButton;
+ }
+ if (etype === 'keypress') {
+ this.charCode = ev.charCode || ev.keyCode;
+ }
+ else if (ev.keyCode && (ev.keyCode === 46)) {
+ this.keyCode = 127;
+ }
+ else {
+ this.keyCode = ev.keyCode;
+ }
+ this.clientX = ev.clientX;
+ this.clientY = ev.clientY;
+ this.ctrlKey = ev.ctrlKey;
+ this.target = ev.target ? ev.target : ev.srcElement;
+ if (!etype.startsWith('key')) {
+ if ((typeof(ev.offsetX) !== 'undefined') && (typeof(ev.offsetY) !== 'undefined')) {
+ this.offsetX = ev.offsetX;
+ this.offsetY = ev.offsetY;
+ }
+ else if (this.target && (this.target.nodeType !== 3) && (typeof(ev.clientX) === 'number')) {
+ var loc = Sys.UI.DomElement.getLocation(this.target);
+ var w = Sys.UI.DomElement._getWindow(this.target);
+ this.offsetX = (w.pageXOffset || 0) + ev.clientX - loc.x;
+ this.offsetY = (w.pageYOffset || 0) + ev.clientY - loc.y;
+ }
+ }
+ this.screenX = ev.screenX;
+ this.screenY = ev.screenY;
+ this.shiftKey = ev.shiftKey;
+}
+ function Sys$UI$DomEvent$preventDefault() {
+ /// <summary locid="M:J#Sys.UI.DomEvent.preventDefault" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this.rawEvent.preventDefault) {
+ this.rawEvent.preventDefault();
+ }
+ else if (window.event) {
+ this.rawEvent.returnValue = false;
+ }
+ }
+ function Sys$UI$DomEvent$stopPropagation() {
+ /// <summary locid="M:J#Sys.UI.DomEvent.stopPropagation" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this.rawEvent.stopPropagation) {
+ this.rawEvent.stopPropagation();
+ }
+ else if (window.event) {
+ this.rawEvent.cancelBubble = true;
+ }
+ }
+Sys.UI.DomEvent.prototype = {
+ preventDefault: Sys$UI$DomEvent$preventDefault,
+ stopPropagation: Sys$UI$DomEvent$stopPropagation
+}
+Sys.UI.DomEvent.registerClass('Sys.UI.DomEvent');
+var $addHandler = Sys.UI.DomEvent.addHandler = function Sys$UI$DomEvent$addHandler(element, eventName, handler, autoRemove) {
+ /// <summary locid="M:J#Sys.UI.DomEvent.addHandler" />
+ /// <param name="element"></param>
+ /// <param name="eventName" type="String"></param>
+ /// <param name="handler" type="Function"></param>
+ /// <param name="autoRemove" type="Boolean" optional="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element"},
+ {name: "eventName", type: String},
+ {name: "handler", type: Function},
+ {name: "autoRemove", type: Boolean, optional: true}
+ ]);
+ if (e) throw e;
+ Sys.UI.DomEvent._ensureDomNode(element);
+ if (eventName === "error") throw Error.invalidOperation(Sys.Res.addHandlerCantBeUsedForError);
+ if (!element._events) {
+ element._events = {};
+ }
+ var eventCache = element._events[eventName];
+ if (!eventCache) {
+ element._events[eventName] = eventCache = [];
+ }
+ var browserHandler;
+ if (element.addEventListener) {
+ browserHandler = function(e) {
+ return handler.call(element, new Sys.UI.DomEvent(e));
+ }
+ element.addEventListener(eventName, browserHandler, false);
+ }
+ else if (element.attachEvent) {
+ browserHandler = function() {
+ var e = {};
+ try {e = Sys.UI.DomElement._getWindow(element).event} catch(ex) {}
+ return handler.call(element, new Sys.UI.DomEvent(e));
+ }
+ element.attachEvent('on' + eventName, browserHandler);
+ }
+ eventCache[eventCache.length] = {handler: handler, browserHandler: browserHandler, autoRemove: autoRemove };
+ if (autoRemove) {
+ var d = element.dispose;
+ if (d !== Sys.UI.DomEvent._disposeHandlers) {
+ element.dispose = Sys.UI.DomEvent._disposeHandlers;
+ if (typeof(d) !== "undefined") {
+ element._chainDispose = d;
+ }
+ }
+ }
+}
+var $addHandlers = Sys.UI.DomEvent.addHandlers = function Sys$UI$DomEvent$addHandlers(element, events, handlerOwner, autoRemove) {
+ /// <summary locid="M:J#Sys.UI.DomEvent.addHandlers" />
+ /// <param name="element"></param>
+ /// <param name="events" type="Object"></param>
+ /// <param name="handlerOwner" optional="true"></param>
+ /// <param name="autoRemove" type="Boolean" optional="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element"},
+ {name: "events", type: Object},
+ {name: "handlerOwner", optional: true},
+ {name: "autoRemove", type: Boolean, optional: true}
+ ]);
+ if (e) throw e;
+ Sys.UI.DomEvent._ensureDomNode(element);
+ for (var name in events) {
+ var handler = events[name];
+ if (typeof(handler) !== 'function') throw Error.invalidOperation(Sys.Res.cantAddNonFunctionhandler);
+ if (handlerOwner) {
+ handler = Function.createDelegate(handlerOwner, handler);
+ }
+ $addHandler(element, name, handler, autoRemove || false);
+ }
+}
+var $clearHandlers = Sys.UI.DomEvent.clearHandlers = function Sys$UI$DomEvent$clearHandlers(element) {
+ /// <summary locid="M:J#Sys.UI.DomEvent.clearHandlers" />
+ /// <param name="element"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element"}
+ ]);
+ if (e) throw e;
+ Sys.UI.DomEvent._ensureDomNode(element);
+ Sys.UI.DomEvent._clearHandlers(element, false);
+}
+Sys.UI.DomEvent._clearHandlers = function Sys$UI$DomEvent$_clearHandlers(element, autoRemoving) {
+ if (element._events) {
+ var cache = element._events;
+ for (var name in cache) {
+ var handlers = cache[name];
+ for (var i = handlers.length - 1; i >= 0; i--) {
+ var entry = handlers[i];
+ if (!autoRemoving || entry.autoRemove) {
+ $removeHandler(element, name, entry.handler);
+ }
+ }
+ }
+ element._events = null;
+ }
+}
+Sys.UI.DomEvent._disposeHandlers = function Sys$UI$DomEvent$_disposeHandlers() {
+ Sys.UI.DomEvent._clearHandlers(this, true);
+ var d = this._chainDispose, type = typeof(d);
+ if (type !== "undefined") {
+ this.dispose = d;
+ this._chainDispose = null;
+ if (type === "function") {
+ this.dispose();
+ }
+ }
+}
+var $removeHandler = Sys.UI.DomEvent.removeHandler = function Sys$UI$DomEvent$removeHandler(element, eventName, handler) {
+ /// <summary locid="M:J#Sys.UI.DomEvent.removeHandler" />
+ /// <param name="element"></param>
+ /// <param name="eventName" type="String"></param>
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element"},
+ {name: "eventName", type: String},
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ Sys.UI.DomEvent._removeHandler(element, eventName, handler);
+}
+Sys.UI.DomEvent._removeHandler = function Sys$UI$DomEvent$_removeHandler(element, eventName, handler) {
+ Sys.UI.DomEvent._ensureDomNode(element);
+ var browserHandler = null;
+ if ((typeof(element._events) !== 'object') || !element._events) throw Error.invalidOperation(Sys.Res.eventHandlerInvalid);
+ var cache = element._events[eventName];
+ if (!(cache instanceof Array)) throw Error.invalidOperation(Sys.Res.eventHandlerInvalid);
+ for (var i = 0, l = cache.length; i < l; i++) {
+ if (cache[i].handler === handler) {
+ browserHandler = cache[i].browserHandler;
+ break;
+ }
+ }
+ if (typeof(browserHandler) !== 'function') throw Error.invalidOperation(Sys.Res.eventHandlerInvalid);
+ if (element.removeEventListener) {
+ element.removeEventListener(eventName, browserHandler, false);
+ }
+ else if (element.detachEvent) {
+ element.detachEvent('on' + eventName, browserHandler);
+ }
+ cache.splice(i, 1);
+}
+Sys.UI.DomEvent._ensureDomNode = function Sys$UI$DomEvent$_ensureDomNode(element) {
+ if (element.tagName && (element.tagName.toUpperCase() === "SCRIPT")) return;
+
+ var doc = element.ownerDocument || element.document || element;
+ if ((typeof(element.document) !== 'object') && (element != doc) && (typeof(element.nodeType) !== 'number')) {
+ throw Error.argument("element", Sys.Res.argumentDomNode);
+ }
+}
+
+Sys.UI.DomElement = function Sys$UI$DomElement() {
+ /// <summary locid="M:J#Sys.UI.DomElement.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+}
+Sys.UI.DomElement.registerClass('Sys.UI.DomElement');
+Sys.UI.DomElement.addCssClass = function Sys$UI$DomElement$addCssClass(element, className) {
+ /// <summary locid="M:J#Sys.UI.DomElement.addCssClass" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="className" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "className", type: String}
+ ]);
+ if (e) throw e;
+ if (!Sys.UI.DomElement.containsCssClass(element, className)) {
+ if (element.className === '') {
+ element.className = className;
+ }
+ else {
+ element.className += ' ' + className;
+ }
+ }
+}
+Sys.UI.DomElement.containsCssClass = function Sys$UI$DomElement$containsCssClass(element, className) {
+ /// <summary locid="M:J#Sys.UI.DomElement.containsCssClass" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="className" type="String"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "className", type: String}
+ ]);
+ if (e) throw e;
+ return Array.contains(element.className.split(' '), className);
+}
+Sys.UI.DomElement.getBounds = function Sys$UI$DomElement$getBounds(element) {
+ /// <summary locid="M:J#Sys.UI.DomElement.getBounds" />
+ /// <param name="element" domElement="true"></param>
+ /// <returns type="Sys.UI.Bounds"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ var offset = Sys.UI.DomElement.getLocation(element);
+ return new Sys.UI.Bounds(offset.x, offset.y, element.offsetWidth || 0, element.offsetHeight || 0);
+}
+var $get = Sys.UI.DomElement.getElementById = function Sys$UI$DomElement$getElementById(id, element) {
+ /// <summary locid="M:J#Sys.UI.DomElement.getElementById" />
+ /// <param name="id" type="String"></param>
+ /// <param name="element" domElement="true" optional="true" mayBeNull="true"></param>
+ /// <returns domElement="true" mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "id", type: String},
+ {name: "element", mayBeNull: true, domElement: true, optional: true}
+ ]);
+ if (e) throw e;
+ if (!element) return document.getElementById(id);
+ if (element.getElementById) return element.getElementById(id);
+ var nodeQueue = [];
+ var childNodes = element.childNodes;
+ for (var i = 0; i < childNodes.length; i++) {
+ var node = childNodes[i];
+ if (node.nodeType == 1) {
+ nodeQueue[nodeQueue.length] = node;
+ }
+ }
+ while (nodeQueue.length) {
+ node = nodeQueue.shift();
+ if (node.id == id) {
+ return node;
+ }
+ childNodes = node.childNodes;
+ for (i = 0; i < childNodes.length; i++) {
+ node = childNodes[i];
+ if (node.nodeType == 1) {
+ nodeQueue[nodeQueue.length] = node;
+ }
+ }
+ }
+ return null;
+}
+if (document.documentElement.getBoundingClientRect) {
+ Sys.UI.DomElement.getLocation = function Sys$UI$DomElement$getLocation(element) {
+ /// <summary locid="M:J#Sys.UI.DomElement.getLocation" />
+ /// <param name="element" domElement="true"></param>
+ /// <returns type="Sys.UI.Point"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ if (element.self || element.nodeType === 9) return new Sys.UI.Point(0,0);
+ var clientRect = element.getBoundingClientRect();
+ if (!clientRect) {
+ return new Sys.UI.Point(0,0);
+ }
+ var documentElement = element.ownerDocument.documentElement,
+ offsetX = Math.floor(clientRect.left + 0.5) + documentElement.scrollLeft,
+ offsetY = Math.floor(clientRect.top + 0.5) + documentElement.scrollTop;
+ if (Sys.Browser.agent === Sys.Browser.InternetExplorer) {
+ try {
+ var f = element.ownerDocument.parentWindow.frameElement || null;
+ if (f) {
+ var offset = (f.frameBorder === "0" || f.frameBorder === "no") ? 2 : 0;
+ offsetX += offset;
+ offsetY += offset;
+ }
+ }
+ catch(ex) {
+ }
+ if (Sys.Browser.version <= 7) {
+
+ var multiplier, before, rect, d = document.createElement("div");
+ d.style.cssText = "position:absolute !important;left:0px !important;right:0px !important;height:0px !important;width:1px !important;display:hidden !important";
+ try {
+ before = document.body.childNodes[0];
+ document.body.insertBefore(d, before);
+ rect = d.getBoundingClientRect();
+ document.body.removeChild(d);
+ multiplier = (rect.right - rect.left);
+ }
+ catch (e) {
+ }
+ if (multiplier && (multiplier !== 1)) {
+ offsetX = Math.floor(offsetX / multiplier);
+ offsetY = Math.floor(offsetY / multiplier);
+ }
+ }
+ if ((document.documentMode || 0) < 8) {
+ offsetX -= 2;
+ offsetY -= 2;
+ }
+ }
+ return new Sys.UI.Point(offsetX, offsetY);
+ }
+}
+else if (Sys.Browser.agent === Sys.Browser.Safari) {
+ Sys.UI.DomElement.getLocation = function Sys$UI$DomElement$getLocation(element) {
+ /// <summary locid="M:J#Sys.UI.DomElement.getLocation" />
+ /// <param name="element" domElement="true"></param>
+ /// <returns type="Sys.UI.Point"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ if ((element.window && (element.window === element)) || element.nodeType === 9) return new Sys.UI.Point(0,0);
+ var offsetX = 0, offsetY = 0,
+ parent,
+ previous = null,
+ previousStyle = null,
+ currentStyle;
+ for (parent = element; parent; previous = parent, previousStyle = currentStyle, parent = parent.offsetParent) {
+ currentStyle = Sys.UI.DomElement._getCurrentStyle(parent);
+ var tagName = parent.tagName ? parent.tagName.toUpperCase() : null;
+ if ((parent.offsetLeft || parent.offsetTop) &&
+ ((tagName !== "BODY") || (!previousStyle || previousStyle.position !== "absolute"))) {
+ offsetX += parent.offsetLeft;
+ offsetY += parent.offsetTop;
+ }
+ if (previous && Sys.Browser.version >= 3) {
+ offsetX += parseInt(currentStyle.borderLeftWidth);
+ offsetY += parseInt(currentStyle.borderTopWidth);
+ }
+ }
+ currentStyle = Sys.UI.DomElement._getCurrentStyle(element);
+ var elementPosition = currentStyle ? currentStyle.position : null;
+ if (!elementPosition || (elementPosition !== "absolute")) {
+ for (parent = element.parentNode; parent; parent = parent.parentNode) {
+ tagName = parent.tagName ? parent.tagName.toUpperCase() : null;
+ if ((tagName !== "BODY") && (tagName !== "HTML") && (parent.scrollLeft || parent.scrollTop)) {
+ offsetX -= (parent.scrollLeft || 0);
+ offsetY -= (parent.scrollTop || 0);
+ }
+ currentStyle = Sys.UI.DomElement._getCurrentStyle(parent);
+ var parentPosition = currentStyle ? currentStyle.position : null;
+ if (parentPosition && (parentPosition === "absolute")) break;
+ }
+ }
+ return new Sys.UI.Point(offsetX, offsetY);
+ }
+}
+else {
+ Sys.UI.DomElement.getLocation = function Sys$UI$DomElement$getLocation(element) {
+ /// <summary locid="M:J#Sys.UI.DomElement.getLocation" />
+ /// <param name="element" domElement="true"></param>
+ /// <returns type="Sys.UI.Point"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ if ((element.window && (element.window === element)) || element.nodeType === 9) return new Sys.UI.Point(0,0);
+ var offsetX = 0, offsetY = 0,
+ parent,
+ previous = null,
+ previousStyle = null,
+ currentStyle = null;
+ for (parent = element; parent; previous = parent, previousStyle = currentStyle, parent = parent.offsetParent) {
+ var tagName = parent.tagName ? parent.tagName.toUpperCase() : null;
+ currentStyle = Sys.UI.DomElement._getCurrentStyle(parent);
+ if ((parent.offsetLeft || parent.offsetTop) &&
+ !((tagName === "BODY") &&
+ (!previousStyle || previousStyle.position !== "absolute"))) {
+ offsetX += parent.offsetLeft;
+ offsetY += parent.offsetTop;
+ }
+ if (previous !== null && currentStyle) {
+ if ((tagName !== "TABLE") && (tagName !== "TD") && (tagName !== "HTML")) {
+ offsetX += parseInt(currentStyle.borderLeftWidth) || 0;
+ offsetY += parseInt(currentStyle.borderTopWidth) || 0;
+ }
+ if (tagName === "TABLE" &&
+ (currentStyle.position === "relative" || currentStyle.position === "absolute")) {
+ offsetX += parseInt(currentStyle.marginLeft) || 0;
+ offsetY += parseInt(currentStyle.marginTop) || 0;
+ }
+ }
+ }
+ currentStyle = Sys.UI.DomElement._getCurrentStyle(element);
+ var elementPosition = currentStyle ? currentStyle.position : null;
+ if (!elementPosition || (elementPosition !== "absolute")) {
+ for (parent = element.parentNode; parent; parent = parent.parentNode) {
+ tagName = parent.tagName ? parent.tagName.toUpperCase() : null;
+ if ((tagName !== "BODY") && (tagName !== "HTML") && (parent.scrollLeft || parent.scrollTop)) {
+ offsetX -= (parent.scrollLeft || 0);
+ offsetY -= (parent.scrollTop || 0);
+ currentStyle = Sys.UI.DomElement._getCurrentStyle(parent);
+ if (currentStyle) {
+ offsetX += parseInt(currentStyle.borderLeftWidth) || 0;
+ offsetY += parseInt(currentStyle.borderTopWidth) || 0;
+ }
+ }
+ }
+ }
+ return new Sys.UI.Point(offsetX, offsetY);
+ }
+}
+Sys.UI.DomElement.isDomElement = function Sys$UI$DomElement$isDomElement(obj) {
+ /// <summary locid="M:J#Sys.UI.DomElement.isDomElement" />
+ /// <param name="obj"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "obj"}
+ ]);
+ if (e) throw e;
+ return Sys._isDomElement(obj);
+}
+Sys.UI.DomElement.removeCssClass = function Sys$UI$DomElement$removeCssClass(element, className) {
+ /// <summary locid="M:J#Sys.UI.DomElement.removeCssClass" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="className" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "className", type: String}
+ ]);
+ if (e) throw e;
+ var currentClassName = ' ' + element.className + ' ';
+ var index = currentClassName.indexOf(' ' + className + ' ');
+ if (index >= 0) {
+ element.className = (currentClassName.substr(0, index) + ' ' +
+ currentClassName.substring(index + className.length + 1, currentClassName.length)).trim();
+ }
+}
+Sys.UI.DomElement.resolveElement = function Sys$UI$DomElement$resolveElement(elementOrElementId, containerElement) {
+ /// <summary locid="M:J#Sys.UI.DomElement.resolveElement" />
+ /// <param name="elementOrElementId" mayBeNull="true"></param>
+ /// <param name="containerElement" domElement="true" optional="true" mayBeNull="true"></param>
+ /// <returns domElement="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "elementOrElementId", mayBeNull: true},
+ {name: "containerElement", mayBeNull: true, domElement: true, optional: true}
+ ]);
+ if (e) throw e;
+ var el = elementOrElementId;
+ if (!el) return null;
+ if (typeof(el) === "string") {
+ el = Sys.UI.DomElement.getElementById(el, containerElement);
+ if (!el) {
+ throw Error.argument("elementOrElementId", String.format(Sys.Res.elementNotFound, elementOrElementId));
+ }
+ }
+ else if(!Sys.UI.DomElement.isDomElement(el)) {
+ throw Error.argument("elementOrElementId", Sys.Res.expectedElementOrId);
+ }
+ return el;
+}
+Sys.UI.DomElement.raiseBubbleEvent = function Sys$UI$DomElement$raiseBubbleEvent(source, args) {
+ /// <summary locid="M:J#Sys.UI.DomElement.raiseBubbleEvent" />
+ /// <param name="source" domElement="true"></param>
+ /// <param name="args" type="Sys.EventArgs"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "source", domElement: true},
+ {name: "args", type: Sys.EventArgs}
+ ]);
+ if (e) throw e;
+ var target = source;
+ while (target) {
+ var control = target.control;
+ if (control && control.onBubbleEvent && control.raiseBubbleEvent) {
+ Sys.UI.DomElement._raiseBubbleEventFromControl(control, source, args);
+ return;
+ }
+ target = target.parentNode;
+ }
+}
+Sys.UI.DomElement._raiseBubbleEventFromControl = function Sys$UI$DomElement$_raiseBubbleEventFromControl(control, source, args) {
+ if (!control.onBubbleEvent(source, args)) {
+ control._raiseBubbleEvent(source, args);
+ }
+}
+Sys.UI.DomElement.setLocation = function Sys$UI$DomElement$setLocation(element, x, y) {
+ /// <summary locid="M:J#Sys.UI.DomElement.setLocation" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="x" type="Number" integer="true"></param>
+ /// <param name="y" type="Number" integer="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "x", type: Number, integer: true},
+ {name: "y", type: Number, integer: true}
+ ]);
+ if (e) throw e;
+ var style = element.style;
+ style.position = 'absolute';
+ style.left = x + "px";
+ style.top = y + "px";
+}
+Sys.UI.DomElement.toggleCssClass = function Sys$UI$DomElement$toggleCssClass(element, className) {
+ /// <summary locid="M:J#Sys.UI.DomElement.toggleCssClass" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="className" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "className", type: String}
+ ]);
+ if (e) throw e;
+ if (Sys.UI.DomElement.containsCssClass(element, className)) {
+ Sys.UI.DomElement.removeCssClass(element, className);
+ }
+ else {
+ Sys.UI.DomElement.addCssClass(element, className);
+ }
+}
+Sys.UI.DomElement.getVisibilityMode = function Sys$UI$DomElement$getVisibilityMode(element) {
+ /// <summary locid="M:J#Sys.UI.DomElement.getVisibilityMode" />
+ /// <param name="element" domElement="true"></param>
+ /// <returns type="Sys.UI.VisibilityMode"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ return (element._visibilityMode === Sys.UI.VisibilityMode.hide) ?
+ Sys.UI.VisibilityMode.hide :
+ Sys.UI.VisibilityMode.collapse;
+}
+Sys.UI.DomElement.setVisibilityMode = function Sys$UI$DomElement$setVisibilityMode(element, value) {
+ /// <summary locid="M:J#Sys.UI.DomElement.setVisibilityMode" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="value" type="Sys.UI.VisibilityMode"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "value", type: Sys.UI.VisibilityMode}
+ ]);
+ if (e) throw e;
+ Sys.UI.DomElement._ensureOldDisplayMode(element);
+ if (element._visibilityMode !== value) {
+ element._visibilityMode = value;
+ if (Sys.UI.DomElement.getVisible(element) === false) {
+ if (element._visibilityMode === Sys.UI.VisibilityMode.hide) {
+ element.style.display = element._oldDisplayMode;
+ }
+ else {
+ element.style.display = 'none';
+ }
+ }
+ element._visibilityMode = value;
+ }
+}
+Sys.UI.DomElement.getVisible = function Sys$UI$DomElement$getVisible(element) {
+ /// <summary locid="M:J#Sys.UI.DomElement.getVisible" />
+ /// <param name="element" domElement="true"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ var style = element.currentStyle || Sys.UI.DomElement._getCurrentStyle(element);
+ if (!style) return true;
+ return (style.visibility !== 'hidden') && (style.display !== 'none');
+}
+Sys.UI.DomElement.setVisible = function Sys$UI$DomElement$setVisible(element, value) {
+ /// <summary locid="M:J#Sys.UI.DomElement.setVisible" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="value" type="Boolean"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "value", type: Boolean}
+ ]);
+ if (e) throw e;
+ if (value !== Sys.UI.DomElement.getVisible(element)) {
+ Sys.UI.DomElement._ensureOldDisplayMode(element);
+ element.style.visibility = value ? 'visible' : 'hidden';
+ if (value || (element._visibilityMode === Sys.UI.VisibilityMode.hide)) {
+ element.style.display = element._oldDisplayMode;
+ }
+ else {
+ element.style.display = 'none';
+ }
+ }
+}
+Sys.UI.DomElement._ensureOldDisplayMode = function Sys$UI$DomElement$_ensureOldDisplayMode(element) {
+ if (!element._oldDisplayMode) {
+ var style = element.currentStyle || Sys.UI.DomElement._getCurrentStyle(element);
+ element._oldDisplayMode = style ? style.display : null;
+ if (!element._oldDisplayMode || element._oldDisplayMode === 'none') {
+ switch(element.tagName.toUpperCase()) {
+ case 'DIV': case 'P': case 'ADDRESS': case 'BLOCKQUOTE': case 'BODY': case 'COL':
+ case 'COLGROUP': case 'DD': case 'DL': case 'DT': case 'FIELDSET': case 'FORM':
+ case 'H1': case 'H2': case 'H3': case 'H4': case 'H5': case 'H6': case 'HR':
+ case 'IFRAME': case 'LEGEND': case 'OL': case 'PRE': case 'TABLE': case 'TD':
+ case 'TH': case 'TR': case 'UL':
+ element._oldDisplayMode = 'block';
+ break;
+ case 'LI':
+ element._oldDisplayMode = 'list-item';
+ break;
+ default:
+ element._oldDisplayMode = 'inline';
+ }
+ }
+ }
+}
+Sys.UI.DomElement._getWindow = function Sys$UI$DomElement$_getWindow(element) {
+ var doc = element.ownerDocument || element.document || element;
+ return doc.defaultView || doc.parentWindow;
+}
+Sys.UI.DomElement._getCurrentStyle = function Sys$UI$DomElement$_getCurrentStyle(element) {
+ if (element.nodeType === 3) return null;
+ var w = Sys.UI.DomElement._getWindow(element);
+ if (element.documentElement) element = element.documentElement;
+ var computedStyle = (w && (element !== w) && w.getComputedStyle) ?
+ w.getComputedStyle(element, null) :
+ element.currentStyle || element.style;
+ if (!computedStyle && (Sys.Browser.agent === Sys.Browser.Safari) && element.style) {
+ var oldDisplay = element.style.display;
+ var oldPosition = element.style.position;
+ element.style.position = 'absolute';
+ element.style.display = 'block';
+ var style = w.getComputedStyle(element, null);
+ element.style.display = oldDisplay;
+ element.style.position = oldPosition;
+ computedStyle = {};
+ for (var n in style) {
+ computedStyle[n] = style[n];
+ }
+ computedStyle.display = 'none';
+ }
+ return computedStyle;
+}
+
+Sys.IContainer = function Sys$IContainer() {
+ throw Error.notImplemented();
+}
+ function Sys$IContainer$addComponent(component) {
+ /// <summary locid="M:J#Sys.IContainer.addComponent" />
+ /// <param name="component" type="Sys.Component"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "component", type: Sys.Component}
+ ]);
+ if (e) throw e;
+ throw Error.notImplemented();
+ }
+ function Sys$IContainer$removeComponent(component) {
+ /// <summary locid="M:J#Sys.IContainer.removeComponent" />
+ /// <param name="component" type="Sys.Component"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "component", type: Sys.Component}
+ ]);
+ if (e) throw e;
+ throw Error.notImplemented();
+ }
+ function Sys$IContainer$findComponent(id) {
+ /// <summary locid="M:J#Sys.IContainer.findComponent" />
+ /// <param name="id" type="String"></param>
+ /// <returns type="Sys.Component"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "id", type: String}
+ ]);
+ if (e) throw e;
+ throw Error.notImplemented();
+ }
+ function Sys$IContainer$getComponents() {
+ /// <summary locid="M:J#Sys.IContainer.getComponents" />
+ /// <returns type="Array" elementType="Sys.Component"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+Sys.IContainer.prototype = {
+ addComponent: Sys$IContainer$addComponent,
+ removeComponent: Sys$IContainer$removeComponent,
+ findComponent: Sys$IContainer$findComponent,
+ getComponents: Sys$IContainer$getComponents
+}
+Sys.IContainer.registerInterface("Sys.IContainer");
+
+Sys.ApplicationLoadEventArgs = function Sys$ApplicationLoadEventArgs(components, isPartialLoad) {
+ /// <summary locid="M:J#Sys.ApplicationLoadEventArgs.#ctor" />
+ /// <param name="components" type="Array" elementType="Sys.Component"></param>
+ /// <param name="isPartialLoad" type="Boolean"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "components", type: Array, elementType: Sys.Component},
+ {name: "isPartialLoad", type: Boolean}
+ ]);
+ if (e) throw e;
+ Sys.ApplicationLoadEventArgs.initializeBase(this);
+ this._components = components;
+ this._isPartialLoad = isPartialLoad;
+}
+
+ function Sys$ApplicationLoadEventArgs$get_components() {
+ /// <value type="Array" elementType="Sys.Component" locid="P:J#Sys.ApplicationLoadEventArgs.components"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._components;
+ }
+ function Sys$ApplicationLoadEventArgs$get_isPartialLoad() {
+ /// <value type="Boolean" locid="P:J#Sys.ApplicationLoadEventArgs.isPartialLoad"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._isPartialLoad;
+ }
+Sys.ApplicationLoadEventArgs.prototype = {
+ get_components: Sys$ApplicationLoadEventArgs$get_components,
+ get_isPartialLoad: Sys$ApplicationLoadEventArgs$get_isPartialLoad
+}
+Sys.ApplicationLoadEventArgs.registerClass('Sys.ApplicationLoadEventArgs', Sys.EventArgs);
+
+Sys._Application = function Sys$_Application() {
+ /// <summary locid="M:J#Sys.Application.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ Sys._Application.initializeBase(this);
+ this._disposableObjects = [];
+ this._components = {};
+ this._createdComponents = [];
+ this._secondPassComponents = [];
+ this._unloadHandlerDelegate = Function.createDelegate(this, this._unloadHandler);
+ Sys.UI.DomEvent.addHandler(window, "unload", this._unloadHandlerDelegate);
+ this._domReady();
+}
+ function Sys$_Application$get_isCreatingComponents() {
+ /// <value type="Boolean" locid="P:J#Sys.Application.isCreatingComponents"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._creatingComponents;
+ }
+ function Sys$_Application$get_isDisposing() {
+ /// <value type="Boolean" locid="P:J#Sys.Application.isDisposing"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._disposing;
+ }
+ function Sys$_Application$add_init(handler) {
+ /// <summary locid="E:J#Sys.Application.init" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ if (this._initialized) {
+ handler(this, Sys.EventArgs.Empty);
+ }
+ else {
+ this.get_events().addHandler("init", handler);
+ }
+ }
+ function Sys$_Application$remove_init(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().removeHandler("init", handler);
+ }
+ function Sys$_Application$add_load(handler) {
+ /// <summary locid="E:J#Sys.Application.load" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().addHandler("load", handler);
+ }
+ function Sys$_Application$remove_load(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().removeHandler("load", handler);
+ }
+ function Sys$_Application$add_unload(handler) {
+ /// <summary locid="E:J#Sys.Application.unload" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().addHandler("unload", handler);
+ }
+ function Sys$_Application$remove_unload(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this.get_events().removeHandler("unload", handler);
+ }
+ function Sys$_Application$addComponent(component) {
+ /// <summary locid="M:J#Sys.Application.addComponent" />
+ /// <param name="component" type="Sys.Component"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "component", type: Sys.Component}
+ ]);
+ if (e) throw e;
+ var id = component.get_id();
+ if (!id) throw Error.invalidOperation(Sys.Res.cantAddWithoutId);
+ if (typeof(this._components[id]) !== 'undefined') throw Error.invalidOperation(String.format(Sys.Res.appDuplicateComponent, id));
+ this._components[id] = component;
+ }
+ function Sys$_Application$beginCreateComponents() {
+ /// <summary locid="M:J#Sys.Application.beginCreateComponents" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ this._creatingComponents = true;
+ }
+ function Sys$_Application$dispose() {
+ /// <summary locid="M:J#Sys.Application.dispose" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._disposing) {
+ this._disposing = true;
+ if (this._timerCookie) {
+ window.clearTimeout(this._timerCookie);
+ delete this._timerCookie;
+ }
+ if (this._endRequestHandler) {
+ Sys.WebForms.PageRequestManager.getInstance().remove_endRequest(this._endRequestHandler);
+ delete this._endRequestHandler;
+ }
+ if (this._beginRequestHandler) {
+ Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(this._beginRequestHandler);
+ delete this._beginRequestHandler;
+ }
+ if (window.pageUnload) {
+ window.pageUnload(this, Sys.EventArgs.Empty);
+ }
+ var unloadHandler = this.get_events().getHandler("unload");
+ if (unloadHandler) {
+ unloadHandler(this, Sys.EventArgs.Empty);
+ }
+ var disposableObjects = Array.clone(this._disposableObjects);
+ for (var i = 0, l = disposableObjects.length; i < l; i++) {
+ var object = disposableObjects[i];
+ if (typeof(object) !== "undefined") {
+ object.dispose();
+ }
+ }
+ Array.clear(this._disposableObjects);
+ Sys.UI.DomEvent.removeHandler(window, "unload", this._unloadHandlerDelegate);
+ if (Sys._ScriptLoader) {
+ var sl = Sys._ScriptLoader.getInstance();
+ if(sl) {
+ sl.dispose();
+ }
+ }
+ Sys._Application.callBaseMethod(this, 'dispose');
+ }
+ }
+ function Sys$_Application$disposeElement(element, childNodesOnly) {
+ /// <summary locid="M:J#Sys._Application.disposeElement" />
+ /// <param name="element"></param>
+ /// <param name="childNodesOnly" type="Boolean"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element"},
+ {name: "childNodesOnly", type: Boolean}
+ ]);
+ if (e) throw e;
+ if (element.nodeType === 1) {
+ var children = element.getElementsByTagName("*");
+ for (var i = children.length - 1; i >= 0; i--) {
+ this._disposeElementInternal(children[i]);
+ }
+ if (!childNodesOnly) {
+ this._disposeElementInternal(element);
+ }
+ }
+ }
+ function Sys$_Application$endCreateComponents() {
+ /// <summary locid="M:J#Sys.Application.endCreateComponents" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ var components = this._secondPassComponents;
+ for (var i = 0, l = components.length; i < l; i++) {
+ var component = components[i].component;
+ Sys$Component$_setReferences(component, components[i].references);
+ component.endUpdate();
+ }
+ this._secondPassComponents = [];
+ this._creatingComponents = false;
+ }
+ function Sys$_Application$findComponent(id, parent) {
+ /// <summary locid="M:J#Sys.Application.findComponent" />
+ /// <param name="id" type="String"></param>
+ /// <param name="parent" optional="true" mayBeNull="true"></param>
+ /// <returns type="Sys.Component" mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "id", type: String},
+ {name: "parent", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ return (parent ?
+ ((Sys.IContainer.isInstanceOfType(parent)) ?
+ parent.findComponent(id) :
+ parent[id] || null) :
+ Sys.Application._components[id] || null);
+ }
+ function Sys$_Application$getComponents() {
+ /// <summary locid="M:J#Sys.Application.getComponents" />
+ /// <returns type="Array" elementType="Sys.Component"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ var res = [];
+ var components = this._components;
+ for (var name in components) {
+ res[res.length] = components[name];
+ }
+ return res;
+ }
+ function Sys$_Application$initialize() {
+ /// <summary locid="M:J#Sys.Application.initialize" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if(!this.get_isInitialized() && !this._disposing) {
+ Sys._Application.callBaseMethod(this, 'initialize');
+ this._raiseInit();
+ if (this.get_stateString) {
+ if (Sys.WebForms && Sys.WebForms.PageRequestManager) {
+ this._beginRequestHandler = Function.createDelegate(this, this._onPageRequestManagerBeginRequest);
+ Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(this._beginRequestHandler);
+ this._endRequestHandler = Function.createDelegate(this, this._onPageRequestManagerEndRequest);
+ Sys.WebForms.PageRequestManager.getInstance().add_endRequest(this._endRequestHandler);
+ }
+ var loadedEntry = this.get_stateString();
+ if (loadedEntry !== this._currentEntry) {
+ this._navigate(loadedEntry);
+ }
+ else {
+ this._ensureHistory();
+ }
+ }
+ this.raiseLoad();
+ }
+ }
+ function Sys$_Application$notifyScriptLoaded() {
+ /// <summary locid="M:J#Sys.Application.notifyScriptLoaded" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ }
+ function Sys$_Application$registerDisposableObject(object) {
+ /// <summary locid="M:J#Sys.Application.registerDisposableObject" />
+ /// <param name="object" type="Sys.IDisposable"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "object", type: Sys.IDisposable}
+ ]);
+ if (e) throw e;
+ if (!this._disposing) {
+ var objects = this._disposableObjects,
+ i = objects.length;
+ objects[i] = object;
+ object.__msdisposeindex = i;
+ }
+ }
+ function Sys$_Application$raiseLoad() {
+ /// <summary locid="M:J#Sys.Application.raiseLoad" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ var h = this.get_events().getHandler("load");
+ var args = new Sys.ApplicationLoadEventArgs(Array.clone(this._createdComponents), !!this._loaded);
+ this._loaded = true;
+ if (h) {
+ h(this, args);
+ }
+ if (window.pageLoad) {
+ window.pageLoad(this, args);
+ }
+ this._createdComponents = [];
+ }
+ function Sys$_Application$removeComponent(component) {
+ /// <summary locid="M:J#Sys.Application.removeComponent" />
+ /// <param name="component" type="Sys.Component"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "component", type: Sys.Component}
+ ]);
+ if (e) throw e;
+ var id = component.get_id();
+ if (id) delete this._components[id];
+ }
+ function Sys$_Application$unregisterDisposableObject(object) {
+ /// <summary locid="M:J#Sys.Application.unregisterDisposableObject" />
+ /// <param name="object" type="Sys.IDisposable"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "object", type: Sys.IDisposable}
+ ]);
+ if (e) throw e;
+ if (!this._disposing) {
+ var i = object.__msdisposeindex;
+ if (typeof(i) === "number") {
+ var disposableObjects = this._disposableObjects;
+ delete disposableObjects[i];
+ delete object.__msdisposeindex;
+ if (++this._deleteCount > 1000) {
+ var newArray = [];
+ for (var j = 0, l = disposableObjects.length; j < l; j++) {
+ object = disposableObjects[j];
+ if (typeof(object) !== "undefined") {
+ object.__msdisposeindex = newArray.length;
+ newArray.push(object);
+ }
+ }
+ this._disposableObjects = newArray;
+ this._deleteCount = 0;
+ }
+ }
+ }
+ }
+ function Sys$_Application$_addComponentToSecondPass(component, references) {
+ this._secondPassComponents[this._secondPassComponents.length] = {component: component, references: references};
+ }
+ function Sys$_Application$_disposeComponents(list) {
+ if (list) {
+ for (var i = list.length - 1; i >= 0; i--) {
+ var item = list[i];
+ if (typeof(item.dispose) === "function") {
+ item.dispose();
+ }
+ }
+ }
+ }
+ function Sys$_Application$_disposeElementInternal(element) {
+ var d = element.dispose;
+ if (d && typeof(d) === "function") {
+ element.dispose();
+ }
+ else {
+ var c = element.control;
+ if (c && typeof(c.dispose) === "function") {
+ c.dispose();
+ }
+ }
+ var list = element._behaviors;
+ if (list) {
+ this._disposeComponents(list);
+ }
+ list = element._components;
+ if (list) {
+ this._disposeComponents(list);
+ element._components = null;
+ }
+ }
+ function Sys$_Application$_domReady() {
+ var check, er, app = this;
+ function init() { app.initialize(); }
+ var onload = function() {
+ Sys.UI.DomEvent.removeHandler(window, "load", onload);
+ init();
+ }
+ Sys.UI.DomEvent.addHandler(window, "load", onload);
+
+ if (document.addEventListener) {
+ try {
+ document.addEventListener("DOMContentLoaded", check = function() {
+ document.removeEventListener("DOMContentLoaded", check, false);
+ init();
+ }, false);
+ }
+ catch (er) { }
+ }
+ else if (document.attachEvent) {
+ if ((window == window.top) && document.documentElement.doScroll) {
+ var timeout, el = document.createElement("div");
+ check = function() {
+ try {
+ el.doScroll("left");
+ }
+ catch (er) {
+ timeout = window.setTimeout(check, 0);
+ return;
+ }
+ el = null;
+ init();
+ }
+ check();
+ }
+ else {
+ document.attachEvent("onreadystatechange", check = function() {
+ if (document.readyState === "complete") {
+ document.detachEvent("onreadystatechange", check);
+ init();
+ }
+ });
+ }
+ }
+ }
+ function Sys$_Application$_raiseInit() {
+ var handler = this.get_events().getHandler("init");
+ if (handler) {
+ this.beginCreateComponents();
+ handler(this, Sys.EventArgs.Empty);
+ this.endCreateComponents();
+ }
+ }
+ function Sys$_Application$_unloadHandler(event) {
+ this.dispose();
+ }
+Sys._Application.prototype = {
+ _creatingComponents: false,
+ _disposing: false,
+ _deleteCount: 0,
+ get_isCreatingComponents: Sys$_Application$get_isCreatingComponents,
+ get_isDisposing: Sys$_Application$get_isDisposing,
+ add_init: Sys$_Application$add_init,
+ remove_init: Sys$_Application$remove_init,
+ add_load: Sys$_Application$add_load,
+ remove_load: Sys$_Application$remove_load,
+ add_unload: Sys$_Application$add_unload,
+ remove_unload: Sys$_Application$remove_unload,
+ addComponent: Sys$_Application$addComponent,
+ beginCreateComponents: Sys$_Application$beginCreateComponents,
+ dispose: Sys$_Application$dispose,
+ disposeElement: Sys$_Application$disposeElement,
+ endCreateComponents: Sys$_Application$endCreateComponents,
+ findComponent: Sys$_Application$findComponent,
+ getComponents: Sys$_Application$getComponents,
+ initialize: Sys$_Application$initialize,
+ notifyScriptLoaded: Sys$_Application$notifyScriptLoaded,
+ registerDisposableObject: Sys$_Application$registerDisposableObject,
+ raiseLoad: Sys$_Application$raiseLoad,
+ removeComponent: Sys$_Application$removeComponent,
+ unregisterDisposableObject: Sys$_Application$unregisterDisposableObject,
+ _addComponentToSecondPass: Sys$_Application$_addComponentToSecondPass,
+ _disposeComponents: Sys$_Application$_disposeComponents,
+ _disposeElementInternal: Sys$_Application$_disposeElementInternal,
+ _domReady: Sys$_Application$_domReady,
+ _raiseInit: Sys$_Application$_raiseInit,
+ _unloadHandler: Sys$_Application$_unloadHandler
+}
+Sys._Application.registerClass('Sys._Application', Sys.Component, Sys.IContainer);
+Sys.Application = new Sys._Application();
+var $find = Sys.Application.findComponent;
+
+Sys.UI.Behavior = function Sys$UI$Behavior(element) {
+ /// <summary locid="M:J#Sys.UI.Behavior.#ctor" />
+ /// <param name="element" domElement="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ Sys.UI.Behavior.initializeBase(this);
+ this._element = element;
+ var behaviors = element._behaviors;
+ if (!behaviors) {
+ element._behaviors = [this];
+ }
+ else {
+ behaviors[behaviors.length] = this;
+ }
+}
+ function Sys$UI$Behavior$get_element() {
+ /// <value domElement="true" locid="P:J#Sys.UI.Behavior.element"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._element;
+ }
+ function Sys$UI$Behavior$get_id() {
+ /// <value type="String" locid="P:J#Sys.UI.Behavior.id"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ var baseId = Sys.UI.Behavior.callBaseMethod(this, 'get_id');
+ if (baseId) return baseId;
+ if (!this._element || !this._element.id) return '';
+ return this._element.id + '$' + this.get_name();
+ }
+ function Sys$UI$Behavior$get_name() {
+ /// <value type="String" locid="P:J#Sys.UI.Behavior.name"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this._name) return this._name;
+ var name = Object.getTypeName(this);
+ var i = name.lastIndexOf('.');
+ if (i !== -1) name = name.substr(i + 1);
+ if (!this.get_isInitialized()) this._name = name;
+ return name;
+ }
+ function Sys$UI$Behavior$set_name(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: String}]);
+ if (e) throw e;
+ if ((value === '') || (value.charAt(0) === ' ') || (value.charAt(value.length - 1) === ' '))
+ throw Error.argument('value', Sys.Res.invalidId);
+ if (typeof(this._element[value]) !== 'undefined')
+ throw Error.invalidOperation(String.format(Sys.Res.behaviorDuplicateName, value));
+ if (this.get_isInitialized()) throw Error.invalidOperation(Sys.Res.cantSetNameAfterInit);
+ this._name = value;
+ }
+ function Sys$UI$Behavior$initialize() {
+ Sys.UI.Behavior.callBaseMethod(this, 'initialize');
+ var name = this.get_name();
+ if (name) this._element[name] = this;
+ }
+ function Sys$UI$Behavior$dispose() {
+ Sys.UI.Behavior.callBaseMethod(this, 'dispose');
+ var e = this._element;
+ if (e) {
+ var name = this.get_name();
+ if (name) {
+ e[name] = null;
+ }
+ var behaviors = e._behaviors;
+ Array.remove(behaviors, this);
+ if (behaviors.length === 0) {
+ e._behaviors = null;
+ }
+ delete this._element;
+ }
+ }
+Sys.UI.Behavior.prototype = {
+ _name: null,
+ get_element: Sys$UI$Behavior$get_element,
+ get_id: Sys$UI$Behavior$get_id,
+ get_name: Sys$UI$Behavior$get_name,
+ set_name: Sys$UI$Behavior$set_name,
+ initialize: Sys$UI$Behavior$initialize,
+ dispose: Sys$UI$Behavior$dispose
+}
+Sys.UI.Behavior.registerClass('Sys.UI.Behavior', Sys.Component);
+Sys.UI.Behavior.getBehaviorByName = function Sys$UI$Behavior$getBehaviorByName(element, name) {
+ /// <summary locid="M:J#Sys.UI.Behavior.getBehaviorByName" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="name" type="String"></param>
+ /// <returns type="Sys.UI.Behavior" mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "name", type: String}
+ ]);
+ if (e) throw e;
+ var b = element[name];
+ return (b && Sys.UI.Behavior.isInstanceOfType(b)) ? b : null;
+}
+Sys.UI.Behavior.getBehaviors = function Sys$UI$Behavior$getBehaviors(element) {
+ /// <summary locid="M:J#Sys.UI.Behavior.getBehaviors" />
+ /// <param name="element" domElement="true"></param>
+ /// <returns type="Array" elementType="Sys.UI.Behavior"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ if (!element._behaviors) return [];
+ return Array.clone(element._behaviors);
+}
+Sys.UI.Behavior.getBehaviorsByType = function Sys$UI$Behavior$getBehaviorsByType(element, type) {
+ /// <summary locid="M:J#Sys.UI.Behavior.getBehaviorsByType" />
+ /// <param name="element" domElement="true"></param>
+ /// <param name="type" type="Type"></param>
+ /// <returns type="Array" elementType="Sys.UI.Behavior"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true},
+ {name: "type", type: Type}
+ ]);
+ if (e) throw e;
+ var behaviors = element._behaviors;
+ var results = [];
+ if (behaviors) {
+ for (var i = 0, l = behaviors.length; i < l; i++) {
+ if (type.isInstanceOfType(behaviors[i])) {
+ results[results.length] = behaviors[i];
+ }
+ }
+ }
+ return results;
+}
+
+Sys.UI.VisibilityMode = function Sys$UI$VisibilityMode() {
+ /// <summary locid="M:J#Sys.UI.VisibilityMode.#ctor" />
+ /// <field name="hide" type="Number" integer="true" static="true" locid="F:J#Sys.UI.VisibilityMode.hide"></field>
+ /// <field name="collapse" type="Number" integer="true" static="true" locid="F:J#Sys.UI.VisibilityMode.collapse"></field>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+}
+Sys.UI.VisibilityMode.prototype = {
+ hide: 0,
+ collapse: 1
+}
+Sys.UI.VisibilityMode.registerEnum("Sys.UI.VisibilityMode");
+
+Sys.UI.Control = function Sys$UI$Control(element) {
+ /// <summary locid="M:J#Sys.UI.Control.#ctor" />
+ /// <param name="element" domElement="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "element", domElement: true}
+ ]);
+ if (e) throw e;
+ if (typeof(element.control) !== 'undefined') throw Error.invalidOperation(Sys.Res.controlAlreadyDefined);
+ Sys.UI.Control.initializeBase(this);
+ this._element = element;
+ element.control = this;
+ var role = this.get_role();
+ if (role) {
+ element.setAttribute("role", role);
+ }
+}
+ function Sys$UI$Control$get_element() {
+ /// <value domElement="true" locid="P:J#Sys.UI.Control.element"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._element;
+ }
+ function Sys$UI$Control$get_id() {
+ /// <value type="String" locid="P:J#Sys.UI.Control.id"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._element) return '';
+ return this._element.id;
+ }
+ function Sys$UI$Control$set_id(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: String}]);
+ if (e) throw e;
+ throw Error.invalidOperation(Sys.Res.cantSetId);
+ }
+ function Sys$UI$Control$get_parent() {
+ /// <value type="Sys.UI.Control" locid="P:J#Sys.UI.Control.parent"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this._parent) return this._parent;
+ if (!this._element) return null;
+
+ var parentElement = this._element.parentNode;
+ while (parentElement) {
+ if (parentElement.control) {
+ return parentElement.control;
+ }
+ parentElement = parentElement.parentNode;
+ }
+ return null;
+ }
+ function Sys$UI$Control$set_parent(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Sys.UI.Control}]);
+ if (e) throw e;
+ if (!this._element) throw Error.invalidOperation(Sys.Res.cantBeCalledAfterDispose);
+ var parents = [this];
+ var current = value;
+ while (current) {
+ if (Array.contains(parents, current)) throw Error.invalidOperation(Sys.Res.circularParentChain);
+ parents[parents.length] = current;
+ current = current.get_parent();
+ }
+ this._parent = value;
+ }
+ function Sys$UI$Control$get_role() {
+ /// <value type="String" locid="P:J#Sys.UI.Control.role"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return null;
+ }
+ function Sys$UI$Control$get_visibilityMode() {
+ /// <value type="Sys.UI.VisibilityMode" locid="P:J#Sys.UI.Control.visibilityMode"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._element) throw Error.invalidOperation(Sys.Res.cantBeCalledAfterDispose);
+ return Sys.UI.DomElement.getVisibilityMode(this._element);
+ }
+ function Sys$UI$Control$set_visibilityMode(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Sys.UI.VisibilityMode}]);
+ if (e) throw e;
+ if (!this._element) throw Error.invalidOperation(Sys.Res.cantBeCalledAfterDispose);
+ Sys.UI.DomElement.setVisibilityMode(this._element, value);
+ }
+ function Sys$UI$Control$get_visible() {
+ /// <value type="Boolean" locid="P:J#Sys.UI.Control.visible"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._element) throw Error.invalidOperation(Sys.Res.cantBeCalledAfterDispose);
+ return Sys.UI.DomElement.getVisible(this._element);
+ }
+ function Sys$UI$Control$set_visible(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Boolean}]);
+ if (e) throw e;
+ if (!this._element) throw Error.invalidOperation(Sys.Res.cantBeCalledAfterDispose);
+ Sys.UI.DomElement.setVisible(this._element, value)
+ }
+ function Sys$UI$Control$addCssClass(className) {
+ /// <summary locid="M:J#Sys.UI.Control.addCssClass" />
+ /// <param name="className" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "className", type: String}
+ ]);
+ if (e) throw e;
+ if (!this._element) throw Error.invalidOperation(Sys.Res.cantBeCalledAfterDispose);
+ Sys.UI.DomElement.addCssClass(this._element, className);
+ }
+ function Sys$UI$Control$dispose() {
+ Sys.UI.Control.callBaseMethod(this, 'dispose');
+ if (this._element) {
+ this._element.control = null;
+ delete this._element;
+ }
+ if (this._parent) delete this._parent;
+ }
+ function Sys$UI$Control$onBubbleEvent(source, args) {
+ /// <summary locid="M:J#Sys.UI.Control.onBubbleEvent" />
+ /// <param name="source"></param>
+ /// <param name="args" type="Sys.EventArgs"></param>
+ /// <returns type="Boolean"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "source"},
+ {name: "args", type: Sys.EventArgs}
+ ]);
+ if (e) throw e;
+ return false;
+ }
+ function Sys$UI$Control$raiseBubbleEvent(source, args) {
+ /// <summary locid="M:J#Sys.UI.Control.raiseBubbleEvent" />
+ /// <param name="source"></param>
+ /// <param name="args" type="Sys.EventArgs"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "source"},
+ {name: "args", type: Sys.EventArgs}
+ ]);
+ if (e) throw e;
+ this._raiseBubbleEvent(source, args);
+ }
+ function Sys$UI$Control$_raiseBubbleEvent(source, args) {
+ var currentTarget = this.get_parent();
+ while (currentTarget) {
+ if (currentTarget.onBubbleEvent(source, args)) {
+ return;
+ }
+ currentTarget = currentTarget.get_parent();
+ }
+ }
+ function Sys$UI$Control$removeCssClass(className) {
+ /// <summary locid="M:J#Sys.UI.Control.removeCssClass" />
+ /// <param name="className" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "className", type: String}
+ ]);
+ if (e) throw e;
+ if (!this._element) throw Error.invalidOperation(Sys.Res.cantBeCalledAfterDispose);
+ Sys.UI.DomElement.removeCssClass(this._element, className);
+ }
+ function Sys$UI$Control$toggleCssClass(className) {
+ /// <summary locid="M:J#Sys.UI.Control.toggleCssClass" />
+ /// <param name="className" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "className", type: String}
+ ]);
+ if (e) throw e;
+ if (!this._element) throw Error.invalidOperation(Sys.Res.cantBeCalledAfterDispose);
+ Sys.UI.DomElement.toggleCssClass(this._element, className);
+ }
+Sys.UI.Control.prototype = {
+ _parent: null,
+ _visibilityMode: Sys.UI.VisibilityMode.hide,
+ get_element: Sys$UI$Control$get_element,
+ get_id: Sys$UI$Control$get_id,
+ set_id: Sys$UI$Control$set_id,
+ get_parent: Sys$UI$Control$get_parent,
+ set_parent: Sys$UI$Control$set_parent,
+ get_role: Sys$UI$Control$get_role,
+ get_visibilityMode: Sys$UI$Control$get_visibilityMode,
+ set_visibilityMode: Sys$UI$Control$set_visibilityMode,
+ get_visible: Sys$UI$Control$get_visible,
+ set_visible: Sys$UI$Control$set_visible,
+ addCssClass: Sys$UI$Control$addCssClass,
+ dispose: Sys$UI$Control$dispose,
+ onBubbleEvent: Sys$UI$Control$onBubbleEvent,
+ raiseBubbleEvent: Sys$UI$Control$raiseBubbleEvent,
+ _raiseBubbleEvent: Sys$UI$Control$_raiseBubbleEvent,
+ removeCssClass: Sys$UI$Control$removeCssClass,
+ toggleCssClass: Sys$UI$Control$toggleCssClass
+}
+Sys.UI.Control.registerClass('Sys.UI.Control', Sys.Component);
+Sys.HistoryEventArgs = function Sys$HistoryEventArgs(state) {
+ /// <summary locid="M:J#Sys.HistoryEventArgs.#ctor" />
+ /// <param name="state" type="Object"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "state", type: Object}
+ ]);
+ if (e) throw e;
+ Sys.HistoryEventArgs.initializeBase(this);
+ this._state = state;
+}
+ function Sys$HistoryEventArgs$get_state() {
+ /// <value type="Object" locid="P:J#Sys.HistoryEventArgs.state"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._state;
+ }
+Sys.HistoryEventArgs.prototype = {
+ get_state: Sys$HistoryEventArgs$get_state
+}
+Sys.HistoryEventArgs.registerClass('Sys.HistoryEventArgs', Sys.EventArgs);
+Sys.Application._appLoadHandler = null;
+Sys.Application._beginRequestHandler = null;
+Sys.Application._clientId = null;
+Sys.Application._currentEntry = '';
+Sys.Application._endRequestHandler = null;
+Sys.Application._history = null;
+Sys.Application._enableHistory = false;
+Sys.Application._historyEnabledInScriptManager = false;
+Sys.Application._historyFrame = null;
+Sys.Application._historyInitialized = false;
+Sys.Application._historyPointIsNew = false;
+Sys.Application._ignoreTimer = false;
+Sys.Application._initialState = null;
+Sys.Application._state = {};
+Sys.Application._timerCookie = 0;
+Sys.Application._timerHandler = null;
+Sys.Application._uniqueId = null;
+Sys._Application.prototype.get_stateString = function Sys$_Application$get_stateString() {
+ /// <summary locid="M:J#Sys._Application.get_stateString" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ var hash = null;
+
+ if (Sys.Browser.agent === Sys.Browser.Firefox) {
+ var href = window.location.href;
+ var hashIndex = href.indexOf('#');
+ if (hashIndex !== -1) {
+ hash = href.substring(hashIndex + 1);
+ }
+ else {
+ hash = "";
+ }
+ return hash;
+ }
+ else {
+ hash = window.location.hash;
+ }
+
+ if ((hash.length > 0) && (hash.charAt(0) === '#')) {
+ hash = hash.substring(1);
+ }
+ return hash;
+};
+Sys._Application.prototype.get_enableHistory = function Sys$_Application$get_enableHistory() {
+ /// <summary locid="M:J#Sys._Application.get_enableHistory" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._enableHistory;
+};
+Sys._Application.prototype.set_enableHistory = function Sys$_Application$set_enableHistory(value) {
+ if (this._initialized && !this._initializing) {
+ throw Error.invalidOperation(Sys.Res.historyCannotEnableHistory);
+ }
+ else if (this._historyEnabledInScriptManager && !value) {
+ throw Error.invalidOperation(Sys.Res.invalidHistorySettingCombination);
+ }
+ this._enableHistory = value;
+};
+Sys._Application.prototype.add_navigate = function Sys$_Application$add_navigate(handler) {
+ /// <summary locid="E:J#Sys.Application.navigate" />
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ this.get_events().addHandler("navigate", handler);
+};
+Sys._Application.prototype.remove_navigate = function Sys$_Application$remove_navigate(handler) {
+ /// <summary locid="M:J#Sys._Application.remove_navigate" />
+ /// <param name="handler" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "handler", type: Function}
+ ]);
+ if (e) throw e;
+ this.get_events().removeHandler("navigate", handler);
+};
+Sys._Application.prototype.addHistoryPoint = function Sys$_Application$addHistoryPoint(state, title) {
+ /// <summary locid="M:J#Sys.Application.addHistoryPoint" />
+ /// <param name="state" type="Object"></param>
+ /// <param name="title" type="String" optional="true" mayBeNull="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "state", type: Object},
+ {name: "title", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ if (!this._enableHistory) throw Error.invalidOperation(Sys.Res.historyCannotAddHistoryPointWithHistoryDisabled);
+ for (var n in state) {
+ var v = state[n];
+ var t = typeof(v);
+ if ((v !== null) && ((t === 'object') || (t === 'function') || (t === 'undefined'))) {
+ throw Error.argument('state', Sys.Res.stateMustBeStringDictionary);
+ }
+ }
+ this._ensureHistory();
+ var initialState = this._state;
+ for (var key in state) {
+ var value = state[key];
+ if (value === null) {
+ if (typeof(initialState[key]) !== 'undefined') {
+ delete initialState[key];
+ }
+ }
+ else {
+ initialState[key] = value;
+ }
+ }
+ var entry = this._serializeState(initialState);
+ this._historyPointIsNew = true;
+ this._setState(entry, title);
+ this._raiseNavigate();
+};
+Sys._Application.prototype.setServerId = function Sys$_Application$setServerId(clientId, uniqueId) {
+ /// <summary locid="M:J#Sys.Application.setServerId" />
+ /// <param name="clientId" type="String"></param>
+ /// <param name="uniqueId" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "clientId", type: String},
+ {name: "uniqueId", type: String}
+ ]);
+ if (e) throw e;
+ this._clientId = clientId;
+ this._uniqueId = uniqueId;
+};
+Sys._Application.prototype.setServerState = function Sys$_Application$setServerState(value) {
+ /// <summary locid="M:J#Sys.Application.setServerState" />
+ /// <param name="value" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "value", type: String}
+ ]);
+ if (e) throw e;
+ this._ensureHistory();
+ this._state.__s = value;
+ this._updateHiddenField(value);
+};
+Sys._Application.prototype._deserializeState = function Sys$_Application$_deserializeState(entry) {
+ var result = {};
+ entry = entry || '';
+ var serverSeparator = entry.indexOf('&&');
+ if ((serverSeparator !== -1) && (serverSeparator + 2 < entry.length)) {
+ result.__s = entry.substr(serverSeparator + 2);
+ entry = entry.substr(0, serverSeparator);
+ }
+ var tokens = entry.split('&');
+ for (var i = 0, l = tokens.length; i < l; i++) {
+ var token = tokens[i];
+ var equal = token.indexOf('=');
+ if ((equal !== -1) && (equal + 1 < token.length)) {
+ var name = token.substr(0, equal);
+ var value = token.substr(equal + 1);
+ result[name] = decodeURIComponent(value);
+ }
+ }
+ return result;
+};
+Sys._Application.prototype._enableHistoryInScriptManager = function Sys$_Application$_enableHistoryInScriptManager() {
+ this._enableHistory = true;
+ this._historyEnabledInScriptManager = true;
+};
+Sys._Application.prototype._ensureHistory = function Sys$_Application$_ensureHistory() {
+ if (!this._historyInitialized && this._enableHistory) {
+ if ((Sys.Browser.agent === Sys.Browser.InternetExplorer) && (Sys.Browser.documentMode < 8)) {
+ this._historyFrame = document.getElementById('__historyFrame');
+ if (!this._historyFrame) throw Error.invalidOperation(Sys.Res.historyMissingFrame);
+ this._ignoreIFrame = true;
+ }
+ this._timerHandler = Function.createDelegate(this, this._onIdle);
+ this._timerCookie = window.setTimeout(this._timerHandler, 100);
+
+ try {
+ this._initialState = this._deserializeState(this.get_stateString());
+ } catch(e) {}
+
+ this._historyInitialized = true;
+ }
+};
+Sys._Application.prototype._navigate = function Sys$_Application$_navigate(entry) {
+ this._ensureHistory();
+ var state = this._deserializeState(entry);
+
+ if (this._uniqueId) {
+ var oldServerEntry = this._state.__s || '';
+ var newServerEntry = state.__s || '';
+ if (newServerEntry !== oldServerEntry) {
+ this._updateHiddenField(newServerEntry);
+ __doPostBack(this._uniqueId, newServerEntry);
+ this._state = state;
+ return;
+ }
+ }
+ this._setState(entry);
+ this._state = state;
+ this._raiseNavigate();
+};
+Sys._Application.prototype._onIdle = function Sys$_Application$_onIdle() {
+ delete this._timerCookie;
+
+ var entry = this.get_stateString();
+ if (entry !== this._currentEntry) {
+ if (!this._ignoreTimer) {
+ this._historyPointIsNew = false;
+ this._navigate(entry);
+ }
+ }
+ else {
+ this._ignoreTimer = false;
+ }
+ this._timerCookie = window.setTimeout(this._timerHandler, 100);
+};
+Sys._Application.prototype._onIFrameLoad = function Sys$_Application$_onIFrameLoad(entry) {
+ this._ensureHistory();
+ if (!this._ignoreIFrame) {
+ this._historyPointIsNew = false;
+ this._navigate(entry);
+ }
+ this._ignoreIFrame = false;
+};
+Sys._Application.prototype._onPageRequestManagerBeginRequest = function Sys$_Application$_onPageRequestManagerBeginRequest(sender, args) {
+ this._ignoreTimer = true;
+};
+Sys._Application.prototype._onPageRequestManagerEndRequest = function Sys$_Application$_onPageRequestManagerEndRequest(sender, args) {
+ var dataItem = args.get_dataItems()[this._clientId];
+ var eventTarget = document.getElementById("__EVENTTARGET");
+ if (eventTarget && eventTarget.value === this._uniqueId) {
+ eventTarget.value = '';
+ }
+ if (typeof(dataItem) !== 'undefined') {
+ this.setServerState(dataItem);
+ this._historyPointIsNew = true;
+ }
+ else {
+ this._ignoreTimer = false;
+ }
+ var entry = this._serializeState(this._state);
+ if (entry !== this._currentEntry) {
+ this._ignoreTimer = true;
+ this._setState(entry);
+ this._raiseNavigate();
+ }
+};
+Sys._Application.prototype._raiseNavigate = function Sys$_Application$_raiseNavigate() {
+ var h = this.get_events().getHandler("navigate");
+ var stateClone = {};
+ for (var key in this._state) {
+ if (key !== '__s') {
+ stateClone[key] = this._state[key];
+ }
+ }
+ var args = new Sys.HistoryEventArgs(stateClone);
+ if (h) {
+ h(this, args);
+ }
+ var err;
+ try {
+ if ((Sys.Browser.agent === Sys.Browser.Firefox) && window.location.hash &&
+ (!window.frameElement || window.top.location.hash)) {
+ window.history.go(0);
+ }
+ }
+ catch(err) {
+ }
+};
+Sys._Application.prototype._serializeState = function Sys$_Application$_serializeState(state) {
+ var serialized = [];
+ for (var key in state) {
+ var value = state[key];
+ if (key === '__s') {
+ var serverState = value;
+ }
+ else {
+ if (key.indexOf('=') !== -1) throw Error.argument('state', Sys.Res.stateFieldNameInvalid);
+ serialized[serialized.length] = key + '=' + encodeURIComponent(value);
+ }
+ }
+ return serialized.join('&') + (serverState ? '&&' + serverState : '');
+};
+Sys._Application.prototype._setState = function Sys$_Application$_setState(entry, title) {
+ if (this._enableHistory) {
+ entry = entry || '';
+ if (entry !== this._currentEntry) {
+ if (window.theForm) {
+ var action = window.theForm.action;
+ var hashIndex = action.indexOf('#');
+ window.theForm.action = ((hashIndex !== -1) ? action.substring(0, hashIndex) : action) + '#' + entry;
+ }
+
+ if (this._historyFrame && this._historyPointIsNew) {
+ this._ignoreIFrame = true;
+ var frameDoc = this._historyFrame.contentWindow.document;
+ frameDoc.open("javascript:'<html></html>'");
+ frameDoc.write("<html><head><title>" + (title || document.title) +
+ "</title><scri" + "pt type=\"text/javascript\">parent.Sys.Application._onIFrameLoad(" +
+ Sys.Serialization.JavaScriptSerializer.serialize(entry) +
+ ");</scri" + "pt></head><body></body></html>");
+ frameDoc.close();
+ }
+ this._ignoreTimer = false;
+ this._currentEntry = entry;
+ if (this._historyFrame || this._historyPointIsNew) {
+ var currentHash = this.get_stateString();
+ if (entry !== currentHash) {
+ var loc = document.location;
+ if (loc.href.length - loc.hash.length + entry.length > 1024) {
+ throw Error.invalidOperation(Sys.Res.urlMustBeLessThan1024chars);
+ }
+ window.location.hash = entry;
+ this._currentEntry = this.get_stateString();
+ if ((typeof(title) !== 'undefined') && (title !== null)) {
+ document.title = title;
+ }
+ }
+ }
+ this._historyPointIsNew = false;
+ }
+ }
+};
+Sys._Application.prototype._updateHiddenField = function Sys$_Application$_updateHiddenField(value) {
+ if (this._clientId) {
+ var serverStateField = document.getElementById(this._clientId);
+ if (serverStateField) {
+ serverStateField.value = value;
+ }
+ }
+};
+
+if (!window.XMLHttpRequest) {
+ window.XMLHttpRequest = function window$XMLHttpRequest() {
+ var progIDs = [ 'Msxml2.XMLHTTP.3.0', 'Msxml2.XMLHTTP' ];
+ for (var i = 0, l = progIDs.length; i < l; i++) {
+ try {
+ return new ActiveXObject(progIDs[i]);
+ }
+ catch (ex) {
+ }
+ }
+ return null;
+ }
+}
+Type.registerNamespace('Sys.Net');
+
+Sys.Net.WebRequestExecutor = function Sys$Net$WebRequestExecutor() {
+ /// <summary locid="M:J#Sys.Net.WebRequestExecutor.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ this._webRequest = null;
+ this._resultObject = null;
+}
+ function Sys$Net$WebRequestExecutor$get_webRequest() {
+ /// <value type="Sys.Net.WebRequest" locid="P:J#Sys.Net.WebRequestExecutor.webRequest"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._webRequest;
+ }
+ function Sys$Net$WebRequestExecutor$_set_webRequest(value) {
+ if (this.get_started()) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, 'set_webRequest'));
+ }
+ this._webRequest = value;
+ }
+ function Sys$Net$WebRequestExecutor$get_started() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.WebRequestExecutor.started"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$get_responseAvailable() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.WebRequestExecutor.responseAvailable"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$get_timedOut() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.WebRequestExecutor.timedOut"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$get_aborted() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.WebRequestExecutor.aborted"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$get_responseData() {
+ /// <value type="String" locid="P:J#Sys.Net.WebRequestExecutor.responseData"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$get_statusCode() {
+ /// <value type="Number" locid="P:J#Sys.Net.WebRequestExecutor.statusCode"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$get_statusText() {
+ /// <value type="String" locid="P:J#Sys.Net.WebRequestExecutor.statusText"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$get_xml() {
+ /// <value locid="P:J#Sys.Net.WebRequestExecutor.xml"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$get_object() {
+ /// <value locid="P:J#Sys.Net.WebRequestExecutor.object"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._resultObject) {
+ this._resultObject = Sys.Serialization.JavaScriptSerializer.deserialize(this.get_responseData());
+ }
+ return this._resultObject;
+ }
+ function Sys$Net$WebRequestExecutor$executeRequest() {
+ /// <summary locid="M:J#Sys.Net.WebRequestExecutor.executeRequest" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$abort() {
+ /// <summary locid="M:J#Sys.Net.WebRequestExecutor.abort" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$getResponseHeader(header) {
+ /// <summary locid="M:J#Sys.Net.WebRequestExecutor.getResponseHeader" />
+ /// <param name="header" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "header", type: String}
+ ]);
+ if (e) throw e;
+ throw Error.notImplemented();
+ }
+ function Sys$Net$WebRequestExecutor$getAllResponseHeaders() {
+ /// <summary locid="M:J#Sys.Net.WebRequestExecutor.getAllResponseHeaders" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ throw Error.notImplemented();
+ }
+Sys.Net.WebRequestExecutor.prototype = {
+ get_webRequest: Sys$Net$WebRequestExecutor$get_webRequest,
+ _set_webRequest: Sys$Net$WebRequestExecutor$_set_webRequest,
+ get_started: Sys$Net$WebRequestExecutor$get_started,
+ get_responseAvailable: Sys$Net$WebRequestExecutor$get_responseAvailable,
+ get_timedOut: Sys$Net$WebRequestExecutor$get_timedOut,
+ get_aborted: Sys$Net$WebRequestExecutor$get_aborted,
+ get_responseData: Sys$Net$WebRequestExecutor$get_responseData,
+ get_statusCode: Sys$Net$WebRequestExecutor$get_statusCode,
+ get_statusText: Sys$Net$WebRequestExecutor$get_statusText,
+ get_xml: Sys$Net$WebRequestExecutor$get_xml,
+ get_object: Sys$Net$WebRequestExecutor$get_object,
+ executeRequest: Sys$Net$WebRequestExecutor$executeRequest,
+ abort: Sys$Net$WebRequestExecutor$abort,
+ getResponseHeader: Sys$Net$WebRequestExecutor$getResponseHeader,
+ getAllResponseHeaders: Sys$Net$WebRequestExecutor$getAllResponseHeaders
+}
+Sys.Net.WebRequestExecutor.registerClass('Sys.Net.WebRequestExecutor');
+
+Sys.Net.XMLDOM = function Sys$Net$XMLDOM(markup) {
+ /// <summary locid="M:J#Sys.Net.XMLDOM.#ctor" />
+ /// <param name="markup" type="String"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "markup", type: String}
+ ]);
+ if (e) throw e;
+ if (!window.DOMParser) {
+ var progIDs = [ 'Msxml2.DOMDocument.3.0', 'Msxml2.DOMDocument' ];
+ for (var i = 0, l = progIDs.length; i < l; i++) {
+ try {
+ var xmlDOM = new ActiveXObject(progIDs[i]);
+ xmlDOM.async = false;
+ xmlDOM.loadXML(markup);
+ xmlDOM.setProperty('SelectionLanguage', 'XPath');
+ return xmlDOM;
+ }
+ catch (ex) {
+ }
+ }
+ }
+ else {
+ try {
+ var domParser = new window.DOMParser();
+ return domParser.parseFromString(markup, 'text/xml');
+ }
+ catch (ex) {
+ }
+ }
+ return null;
+}
+Sys.Net.XMLHttpExecutor = function Sys$Net$XMLHttpExecutor() {
+ /// <summary locid="M:J#Sys.Net.XMLHttpExecutor.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ Sys.Net.XMLHttpExecutor.initializeBase(this);
+ var _this = this;
+ this._xmlHttpRequest = null;
+ this._webRequest = null;
+ this._responseAvailable = false;
+ this._timedOut = false;
+ this._timer = null;
+ this._aborted = false;
+ this._started = false;
+ this._onReadyStateChange = (function () {
+
+ if (_this._xmlHttpRequest.readyState === 4 ) {
+ try {
+ if (typeof(_this._xmlHttpRequest.status) === "undefined") {
+ return;
+ }
+ }
+ catch(ex) {
+ return;
+ }
+
+ _this._clearTimer();
+ _this._responseAvailable = true;
+ _this._webRequest.completed(Sys.EventArgs.Empty);
+ if (_this._xmlHttpRequest != null) {
+ _this._xmlHttpRequest.onreadystatechange = Function.emptyMethod;
+ _this._xmlHttpRequest = null;
+ }
+ }
+ });
+ this._clearTimer = (function() {
+ if (_this._timer != null) {
+ window.clearTimeout(_this._timer);
+ _this._timer = null;
+ }
+ });
+ this._onTimeout = (function() {
+ if (!_this._responseAvailable) {
+ _this._clearTimer();
+ _this._timedOut = true;
+ _this._xmlHttpRequest.onreadystatechange = Function.emptyMethod;
+ _this._xmlHttpRequest.abort();
+ _this._webRequest.completed(Sys.EventArgs.Empty);
+ _this._xmlHttpRequest = null;
+ }
+ });
+}
+ function Sys$Net$XMLHttpExecutor$get_timedOut() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.XMLHttpExecutor.timedOut"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._timedOut;
+ }
+ function Sys$Net$XMLHttpExecutor$get_started() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.XMLHttpExecutor.started"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._started;
+ }
+ function Sys$Net$XMLHttpExecutor$get_responseAvailable() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.XMLHttpExecutor.responseAvailable"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._responseAvailable;
+ }
+ function Sys$Net$XMLHttpExecutor$get_aborted() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.XMLHttpExecutor.aborted"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._aborted;
+ }
+ function Sys$Net$XMLHttpExecutor$executeRequest() {
+ /// <summary locid="M:J#Sys.Net.XMLHttpExecutor.executeRequest" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ this._webRequest = this.get_webRequest();
+ if (this._started) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, 'executeRequest'));
+ }
+ if (this._webRequest === null) {
+ throw Error.invalidOperation(Sys.Res.nullWebRequest);
+ }
+ var body = this._webRequest.get_body();
+ var headers = this._webRequest.get_headers();
+ this._xmlHttpRequest = new XMLHttpRequest();
+ this._xmlHttpRequest.onreadystatechange = this._onReadyStateChange;
+ var verb = this._webRequest.get_httpVerb();
+ this._xmlHttpRequest.open(verb, this._webRequest.getResolvedUrl(), true );
+ this._xmlHttpRequest.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ if (headers) {
+ for (var header in headers) {
+ var val = headers[header];
+ if (typeof(val) !== "function")
+ this._xmlHttpRequest.setRequestHeader(header, val);
+ }
+ }
+ if (verb.toLowerCase() === "post") {
+ if ((headers === null) || !headers['Content-Type']) {
+ this._xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
+ }
+ if (!body) {
+ body = "";
+ }
+ }
+ var timeout = this._webRequest.get_timeout();
+ if (timeout > 0) {
+ this._timer = window.setTimeout(Function.createDelegate(this, this._onTimeout), timeout);
+ }
+ this._xmlHttpRequest.send(body);
+ this._started = true;
+ }
+ function Sys$Net$XMLHttpExecutor$getResponseHeader(header) {
+ /// <summary locid="M:J#Sys.Net.XMLHttpExecutor.getResponseHeader" />
+ /// <param name="header" type="String"></param>
+ /// <returns type="String"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "header", type: String}
+ ]);
+ if (e) throw e;
+ if (!this._responseAvailable) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallBeforeResponse, 'getResponseHeader'));
+ }
+ if (!this._xmlHttpRequest) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallOutsideHandler, 'getResponseHeader'));
+ }
+ var result;
+ try {
+ result = this._xmlHttpRequest.getResponseHeader(header);
+ } catch (e) {
+ }
+ if (!result) result = "";
+ return result;
+ }
+ function Sys$Net$XMLHttpExecutor$getAllResponseHeaders() {
+ /// <summary locid="M:J#Sys.Net.XMLHttpExecutor.getAllResponseHeaders" />
+ /// <returns type="String"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._responseAvailable) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallBeforeResponse, 'getAllResponseHeaders'));
+ }
+ if (!this._xmlHttpRequest) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallOutsideHandler, 'getAllResponseHeaders'));
+ }
+ return this._xmlHttpRequest.getAllResponseHeaders();
+ }
+ function Sys$Net$XMLHttpExecutor$get_responseData() {
+ /// <value type="String" locid="P:J#Sys.Net.XMLHttpExecutor.responseData"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._responseAvailable) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallBeforeResponse, 'get_responseData'));
+ }
+ if (!this._xmlHttpRequest) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallOutsideHandler, 'get_responseData'));
+ }
+ return this._xmlHttpRequest.responseText;
+ }
+ function Sys$Net$XMLHttpExecutor$get_statusCode() {
+ /// <value type="Number" locid="P:J#Sys.Net.XMLHttpExecutor.statusCode"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._responseAvailable) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallBeforeResponse, 'get_statusCode'));
+ }
+ if (!this._xmlHttpRequest) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallOutsideHandler, 'get_statusCode'));
+ }
+ var result = 0;
+ try {
+ result = this._xmlHttpRequest.status;
+ }
+ catch(ex) {
+ }
+ return result;
+ }
+ function Sys$Net$XMLHttpExecutor$get_statusText() {
+ /// <value type="String" locid="P:J#Sys.Net.XMLHttpExecutor.statusText"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._responseAvailable) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallBeforeResponse, 'get_statusText'));
+ }
+ if (!this._xmlHttpRequest) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallOutsideHandler, 'get_statusText'));
+ }
+ return this._xmlHttpRequest.statusText;
+ }
+ function Sys$Net$XMLHttpExecutor$get_xml() {
+ /// <value locid="P:J#Sys.Net.XMLHttpExecutor.xml"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._responseAvailable) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallBeforeResponse, 'get_xml'));
+ }
+ if (!this._xmlHttpRequest) {
+ throw Error.invalidOperation(String.format(Sys.Res.cannotCallOutsideHandler, 'get_xml'));
+ }
+ var xml = this._xmlHttpRequest.responseXML;
+ if (!xml || !xml.documentElement) {
+ xml = Sys.Net.XMLDOM(this._xmlHttpRequest.responseText);
+ if (!xml || !xml.documentElement)
+ return null;
+ }
+ else if (navigator.userAgent.indexOf('MSIE') !== -1) {
+ xml.setProperty('SelectionLanguage', 'XPath');
+ }
+ if (xml.documentElement.namespaceURI === "http://www.mozilla.org/newlayout/xml/parsererror.xml" &&
+ xml.documentElement.tagName === "parsererror") {
+ return null;
+ }
+
+ if (xml.documentElement.firstChild && xml.documentElement.firstChild.tagName === "parsererror") {
+ return null;
+ }
+
+ return xml;
+ }
+ function Sys$Net$XMLHttpExecutor$abort() {
+ /// <summary locid="M:J#Sys.Net.XMLHttpExecutor.abort" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (!this._started) {
+ throw Error.invalidOperation(Sys.Res.cannotAbortBeforeStart);
+ }
+ if (this._aborted || this._responseAvailable || this._timedOut)
+ return;
+ this._aborted = true;
+ this._clearTimer();
+ if (this._xmlHttpRequest && !this._responseAvailable) {
+ this._xmlHttpRequest.onreadystatechange = Function.emptyMethod;
+ this._xmlHttpRequest.abort();
+
+ this._xmlHttpRequest = null;
+ this._webRequest.completed(Sys.EventArgs.Empty);
+ }
+ }
+Sys.Net.XMLHttpExecutor.prototype = {
+ get_timedOut: Sys$Net$XMLHttpExecutor$get_timedOut,
+ get_started: Sys$Net$XMLHttpExecutor$get_started,
+ get_responseAvailable: Sys$Net$XMLHttpExecutor$get_responseAvailable,
+ get_aborted: Sys$Net$XMLHttpExecutor$get_aborted,
+ executeRequest: Sys$Net$XMLHttpExecutor$executeRequest,
+ getResponseHeader: Sys$Net$XMLHttpExecutor$getResponseHeader,
+ getAllResponseHeaders: Sys$Net$XMLHttpExecutor$getAllResponseHeaders,
+ get_responseData: Sys$Net$XMLHttpExecutor$get_responseData,
+ get_statusCode: Sys$Net$XMLHttpExecutor$get_statusCode,
+ get_statusText: Sys$Net$XMLHttpExecutor$get_statusText,
+ get_xml: Sys$Net$XMLHttpExecutor$get_xml,
+ abort: Sys$Net$XMLHttpExecutor$abort
+}
+Sys.Net.XMLHttpExecutor.registerClass('Sys.Net.XMLHttpExecutor', Sys.Net.WebRequestExecutor);
+
+Sys.Net._WebRequestManager = function Sys$Net$_WebRequestManager() {
+ /// <summary locid="P:J#Sys.Net.WebRequestManager.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ this._defaultTimeout = 0;
+ this._defaultExecutorType = "Sys.Net.XMLHttpExecutor";
+}
+ function Sys$Net$_WebRequestManager$add_invokingRequest(handler) {
+ /// <summary locid="E:J#Sys.Net.WebRequestManager.invokingRequest" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this._get_eventHandlerList().addHandler("invokingRequest", handler);
+ }
+ function Sys$Net$_WebRequestManager$remove_invokingRequest(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this._get_eventHandlerList().removeHandler("invokingRequest", handler);
+ }
+ function Sys$Net$_WebRequestManager$add_completedRequest(handler) {
+ /// <summary locid="E:J#Sys.Net.WebRequestManager.completedRequest" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this._get_eventHandlerList().addHandler("completedRequest", handler);
+ }
+ function Sys$Net$_WebRequestManager$remove_completedRequest(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this._get_eventHandlerList().removeHandler("completedRequest", handler);
+ }
+ function Sys$Net$_WebRequestManager$_get_eventHandlerList() {
+ if (!this._events) {
+ this._events = new Sys.EventHandlerList();
+ }
+ return this._events;
+ }
+ function Sys$Net$_WebRequestManager$get_defaultTimeout() {
+ /// <value type="Number" locid="P:J#Sys.Net.WebRequestManager.defaultTimeout"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._defaultTimeout;
+ }
+ function Sys$Net$_WebRequestManager$set_defaultTimeout(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Number}]);
+ if (e) throw e;
+ if (value < 0) {
+ throw Error.argumentOutOfRange("value", value, Sys.Res.invalidTimeout);
+ }
+ this._defaultTimeout = value;
+ }
+ function Sys$Net$_WebRequestManager$get_defaultExecutorType() {
+ /// <value type="String" locid="P:J#Sys.Net.WebRequestManager.defaultExecutorType"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._defaultExecutorType;
+ }
+ function Sys$Net$_WebRequestManager$set_defaultExecutorType(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: String}]);
+ if (e) throw e;
+ this._defaultExecutorType = value;
+ }
+ function Sys$Net$_WebRequestManager$executeRequest(webRequest) {
+ /// <summary locid="M:J#Sys.Net.WebRequestManager.executeRequest" />
+ /// <param name="webRequest" type="Sys.Net.WebRequest"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "webRequest", type: Sys.Net.WebRequest}
+ ]);
+ if (e) throw e;
+ var executor = webRequest.get_executor();
+ if (!executor) {
+ var failed = false;
+ try {
+ var executorType = eval(this._defaultExecutorType);
+ executor = new executorType();
+ } catch (e) {
+ failed = true;
+ }
+ if (failed || !Sys.Net.WebRequestExecutor.isInstanceOfType(executor) || !executor) {
+ throw Error.argument("defaultExecutorType", String.format(Sys.Res.invalidExecutorType, this._defaultExecutorType));
+ }
+ webRequest.set_executor(executor);
+ }
+ if (executor.get_aborted()) {
+ return;
+ }
+ var evArgs = new Sys.Net.NetworkRequestEventArgs(webRequest);
+ var handler = this._get_eventHandlerList().getHandler("invokingRequest");
+ if (handler) {
+ handler(this, evArgs);
+ }
+ if (!evArgs.get_cancel()) {
+ executor.executeRequest();
+ }
+ }
+Sys.Net._WebRequestManager.prototype = {
+ add_invokingRequest: Sys$Net$_WebRequestManager$add_invokingRequest,
+ remove_invokingRequest: Sys$Net$_WebRequestManager$remove_invokingRequest,
+ add_completedRequest: Sys$Net$_WebRequestManager$add_completedRequest,
+ remove_completedRequest: Sys$Net$_WebRequestManager$remove_completedRequest,
+ _get_eventHandlerList: Sys$Net$_WebRequestManager$_get_eventHandlerList,
+ get_defaultTimeout: Sys$Net$_WebRequestManager$get_defaultTimeout,
+ set_defaultTimeout: Sys$Net$_WebRequestManager$set_defaultTimeout,
+ get_defaultExecutorType: Sys$Net$_WebRequestManager$get_defaultExecutorType,
+ set_defaultExecutorType: Sys$Net$_WebRequestManager$set_defaultExecutorType,
+ executeRequest: Sys$Net$_WebRequestManager$executeRequest
+}
+Sys.Net._WebRequestManager.registerClass('Sys.Net._WebRequestManager');
+Sys.Net.WebRequestManager = new Sys.Net._WebRequestManager();
+
+Sys.Net.NetworkRequestEventArgs = function Sys$Net$NetworkRequestEventArgs(webRequest) {
+ /// <summary locid="M:J#Sys.Net.NetworkRequestEventArgs.#ctor" />
+ /// <param name="webRequest" type="Sys.Net.WebRequest"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "webRequest", type: Sys.Net.WebRequest}
+ ]);
+ if (e) throw e;
+ Sys.Net.NetworkRequestEventArgs.initializeBase(this);
+ this._webRequest = webRequest;
+}
+ function Sys$Net$NetworkRequestEventArgs$get_webRequest() {
+ /// <value type="Sys.Net.WebRequest" locid="P:J#Sys.Net.NetworkRequestEventArgs.webRequest"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._webRequest;
+ }
+Sys.Net.NetworkRequestEventArgs.prototype = {
+ get_webRequest: Sys$Net$NetworkRequestEventArgs$get_webRequest
+}
+Sys.Net.NetworkRequestEventArgs.registerClass('Sys.Net.NetworkRequestEventArgs', Sys.CancelEventArgs);
+
+Sys.Net.WebRequest = function Sys$Net$WebRequest() {
+ /// <summary locid="M:J#Sys.Net.WebRequest.#ctor" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ this._url = "";
+ this._headers = { };
+ this._body = null;
+ this._userContext = null;
+ this._httpVerb = null;
+ this._executor = null;
+ this._invokeCalled = false;
+ this._timeout = 0;
+}
+ function Sys$Net$WebRequest$add_completed(handler) {
+ /// <summary locid="E:J#Sys.Net.WebRequest.completed" />
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this._get_eventHandlerList().addHandler("completed", handler);
+ }
+ function Sys$Net$WebRequest$remove_completed(handler) {
+ var e = Function._validateParams(arguments, [{name: "handler", type: Function}]);
+ if (e) throw e;
+ this._get_eventHandlerList().removeHandler("completed", handler);
+ }
+ function Sys$Net$WebRequest$completed(eventArgs) {
+ /// <summary locid="M:J#Sys.Net.WebRequest.completed" />
+ /// <param name="eventArgs" type="Sys.EventArgs"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "eventArgs", type: Sys.EventArgs}
+ ]);
+ if (e) throw e;
+ var handler = Sys.Net.WebRequestManager._get_eventHandlerList().getHandler("completedRequest");
+ if (handler) {
+ handler(this._executor, eventArgs);
+ }
+ handler = this._get_eventHandlerList().getHandler("completed");
+ if (handler) {
+ handler(this._executor, eventArgs);
+ }
+ }
+ function Sys$Net$WebRequest$_get_eventHandlerList() {
+ if (!this._events) {
+ this._events = new Sys.EventHandlerList();
+ }
+ return this._events;
+ }
+ function Sys$Net$WebRequest$get_url() {
+ /// <value type="String" locid="P:J#Sys.Net.WebRequest.url"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._url;
+ }
+ function Sys$Net$WebRequest$set_url(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: String}]);
+ if (e) throw e;
+ this._url = value;
+ }
+ function Sys$Net$WebRequest$get_headers() {
+ /// <value locid="P:J#Sys.Net.WebRequest.headers"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._headers;
+ }
+ function Sys$Net$WebRequest$get_httpVerb() {
+ /// <value type="String" locid="P:J#Sys.Net.WebRequest.httpVerb"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this._httpVerb === null) {
+ if (this._body === null) {
+ return "GET";
+ }
+ return "POST";
+ }
+ return this._httpVerb;
+ }
+ function Sys$Net$WebRequest$set_httpVerb(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: String}]);
+ if (e) throw e;
+ if (value.length === 0) {
+ throw Error.argument('value', Sys.Res.invalidHttpVerb);
+ }
+ this._httpVerb = value;
+ }
+ function Sys$Net$WebRequest$get_body() {
+ /// <value mayBeNull="true" locid="P:J#Sys.Net.WebRequest.body"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._body;
+ }
+ function Sys$Net$WebRequest$set_body(value) {
+ var e = Function._validateParams(arguments, [{name: "value", mayBeNull: true}]);
+ if (e) throw e;
+ this._body = value;
+ }
+ function Sys$Net$WebRequest$get_userContext() {
+ /// <value mayBeNull="true" locid="P:J#Sys.Net.WebRequest.userContext"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._userContext;
+ }
+ function Sys$Net$WebRequest$set_userContext(value) {
+ var e = Function._validateParams(arguments, [{name: "value", mayBeNull: true}]);
+ if (e) throw e;
+ this._userContext = value;
+ }
+ function Sys$Net$WebRequest$get_executor() {
+ /// <value type="Sys.Net.WebRequestExecutor" locid="P:J#Sys.Net.WebRequest.executor"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._executor;
+ }
+ function Sys$Net$WebRequest$set_executor(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Sys.Net.WebRequestExecutor}]);
+ if (e) throw e;
+ if (this._executor !== null && this._executor.get_started()) {
+ throw Error.invalidOperation(Sys.Res.setExecutorAfterActive);
+ }
+ this._executor = value;
+ this._executor._set_webRequest(this);
+ }
+ function Sys$Net$WebRequest$get_timeout() {
+ /// <value type="Number" locid="P:J#Sys.Net.WebRequest.timeout"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this._timeout === 0) {
+ return Sys.Net.WebRequestManager.get_defaultTimeout();
+ }
+ return this._timeout;
+ }
+ function Sys$Net$WebRequest$set_timeout(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Number}]);
+ if (e) throw e;
+ if (value < 0) {
+ throw Error.argumentOutOfRange("value", value, Sys.Res.invalidTimeout);
+ }
+ this._timeout = value;
+ }
+ function Sys$Net$WebRequest$getResolvedUrl() {
+ /// <summary locid="M:J#Sys.Net.WebRequest.getResolvedUrl" />
+ /// <returns type="String"></returns>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return Sys.Net.WebRequest._resolveUrl(this._url);
+ }
+ function Sys$Net$WebRequest$invoke() {
+ /// <summary locid="M:J#Sys.Net.WebRequest.invoke" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ if (this._invokeCalled) {
+ throw Error.invalidOperation(Sys.Res.invokeCalledTwice);
+ }
+ Sys.Net.WebRequestManager.executeRequest(this);
+ this._invokeCalled = true;
+ }
+Sys.Net.WebRequest.prototype = {
+ add_completed: Sys$Net$WebRequest$add_completed,
+ remove_completed: Sys$Net$WebRequest$remove_completed,
+ completed: Sys$Net$WebRequest$completed,
+ _get_eventHandlerList: Sys$Net$WebRequest$_get_eventHandlerList,
+ get_url: Sys$Net$WebRequest$get_url,
+ set_url: Sys$Net$WebRequest$set_url,
+ get_headers: Sys$Net$WebRequest$get_headers,
+ get_httpVerb: Sys$Net$WebRequest$get_httpVerb,
+ set_httpVerb: Sys$Net$WebRequest$set_httpVerb,
+ get_body: Sys$Net$WebRequest$get_body,
+ set_body: Sys$Net$WebRequest$set_body,
+ get_userContext: Sys$Net$WebRequest$get_userContext,
+ set_userContext: Sys$Net$WebRequest$set_userContext,
+ get_executor: Sys$Net$WebRequest$get_executor,
+ set_executor: Sys$Net$WebRequest$set_executor,
+ get_timeout: Sys$Net$WebRequest$get_timeout,
+ set_timeout: Sys$Net$WebRequest$set_timeout,
+ getResolvedUrl: Sys$Net$WebRequest$getResolvedUrl,
+ invoke: Sys$Net$WebRequest$invoke
+}
+Sys.Net.WebRequest._resolveUrl = function Sys$Net$WebRequest$_resolveUrl(url, baseUrl) {
+ if (url && url.indexOf('://') !== -1) {
+ return url;
+ }
+ if (!baseUrl || baseUrl.length === 0) {
+ var baseElement = document.getElementsByTagName('base')[0];
+ if (baseElement && baseElement.href && baseElement.href.length > 0) {
+ baseUrl = baseElement.href;
+ }
+ else {
+ baseUrl = document.URL;
+ }
+ }
+ var qsStart = baseUrl.indexOf('?');
+ if (qsStart !== -1) {
+ baseUrl = baseUrl.substr(0, qsStart);
+ }
+ qsStart = baseUrl.indexOf('#');
+ if (qsStart !== -1) {
+ baseUrl = baseUrl.substr(0, qsStart);
+ }
+ baseUrl = baseUrl.substr(0, baseUrl.lastIndexOf('/') + 1);
+ if (!url || url.length === 0) {
+ return baseUrl;
+ }
+ if (url.charAt(0) === '/') {
+ var slashslash = baseUrl.indexOf('://');
+ if (slashslash === -1) {
+ throw Error.argument("baseUrl", Sys.Res.badBaseUrl1);
+ }
+ var nextSlash = baseUrl.indexOf('/', slashslash + 3);
+ if (nextSlash === -1) {
+ throw Error.argument("baseUrl", Sys.Res.badBaseUrl2);
+ }
+ return baseUrl.substr(0, nextSlash) + url;
+ }
+ else {
+ var lastSlash = baseUrl.lastIndexOf('/');
+ if (lastSlash === -1) {
+ throw Error.argument("baseUrl", Sys.Res.badBaseUrl3);
+ }
+ return baseUrl.substr(0, lastSlash+1) + url;
+ }
+}
+Sys.Net.WebRequest._createQueryString = function Sys$Net$WebRequest$_createQueryString(queryString, encodeMethod, addParams) {
+ encodeMethod = encodeMethod || encodeURIComponent;
+ var i = 0, obj, val, arg, sb = new Sys.StringBuilder();
+ if (queryString) {
+ for (arg in queryString) {
+ obj = queryString[arg];
+ if (typeof(obj) === "function") continue;
+ val = Sys.Serialization.JavaScriptSerializer.serialize(obj);
+ if (i++) {
+ sb.append('&');
+ }
+ sb.append(arg);
+ sb.append('=');
+ sb.append(encodeMethod(val));
+ }
+ }
+ if (addParams) {
+ if (i) {
+ sb.append('&');
+ }
+ sb.append(addParams);
+ }
+ return sb.toString();
+}
+Sys.Net.WebRequest._createUrl = function Sys$Net$WebRequest$_createUrl(url, queryString, addParams) {
+ if (!queryString && !addParams) {
+ return url;
+ }
+ var qs = Sys.Net.WebRequest._createQueryString(queryString, null, addParams);
+ return qs.length
+ ? url + ((url && url.indexOf('?') >= 0) ? "&" : "?") + qs
+ : url;
+}
+Sys.Net.WebRequest.registerClass('Sys.Net.WebRequest');
+
+Sys._ScriptLoaderTask = function Sys$_ScriptLoaderTask(scriptElement, completedCallback) {
+ /// <summary locid="M:J#Sys._ScriptLoaderTask.#ctor" />
+ /// <param name="scriptElement" domElement="true"></param>
+ /// <param name="completedCallback" type="Function"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "scriptElement", domElement: true},
+ {name: "completedCallback", type: Function}
+ ]);
+ if (e) throw e;
+ this._scriptElement = scriptElement;
+ this._completedCallback = completedCallback;
+}
+ function Sys$_ScriptLoaderTask$get_scriptElement() {
+ /// <value domElement="true" locid="P:J#Sys._ScriptLoaderTask.scriptElement"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._scriptElement;
+ }
+ function Sys$_ScriptLoaderTask$dispose() {
+ if(this._disposed) {
+ return;
+ }
+ this._disposed = true;
+ this._removeScriptElementHandlers();
+ Sys._ScriptLoaderTask._clearScript(this._scriptElement);
+ this._scriptElement = null;
+ }
+ function Sys$_ScriptLoaderTask$execute() {
+ /// <summary locid="M:J#Sys._ScriptLoaderTask.execute" />
+ if (arguments.length !== 0) throw Error.parameterCount();
+ this._addScriptElementHandlers();
+ var headElements = document.getElementsByTagName('head');
+ if (headElements.length === 0) {
+ throw new Error.invalidOperation(Sys.Res.scriptLoadFailedNoHead);
+ }
+ else {
+ headElements[0].appendChild(this._scriptElement);
+ }
+ }
+ function Sys$_ScriptLoaderTask$_addScriptElementHandlers() {
+ this._scriptLoadDelegate = Function.createDelegate(this, this._scriptLoadHandler);
+
+ if (Sys.Browser.agent !== Sys.Browser.InternetExplorer) {
+ this._scriptElement.readyState = 'loaded';
+ $addHandler(this._scriptElement, 'load', this._scriptLoadDelegate);
+ }
+ else {
+ $addHandler(this._scriptElement, 'readystatechange', this._scriptLoadDelegate);
+ }
+ if (this._scriptElement.addEventListener) {
+ this._scriptErrorDelegate = Function.createDelegate(this, this._scriptErrorHandler);
+ this._scriptElement.addEventListener('error', this._scriptErrorDelegate, false);
+ }
+ }
+ function Sys$_ScriptLoaderTask$_removeScriptElementHandlers() {
+ if(this._scriptLoadDelegate) {
+ var scriptElement = this.get_scriptElement();
+ if (Sys.Browser.agent !== Sys.Browser.InternetExplorer) {
+ $removeHandler(scriptElement, 'load', this._scriptLoadDelegate);
+ }
+ else {
+ $removeHandler(scriptElement, 'readystatechange', this._scriptLoadDelegate);
+ }
+ if (this._scriptErrorDelegate) {
+ this._scriptElement.removeEventListener('error', this._scriptErrorDelegate, false);
+ this._scriptErrorDelegate = null;
+ }
+ this._scriptLoadDelegate = null;
+ }
+ }
+ function Sys$_ScriptLoaderTask$_scriptErrorHandler() {
+ if(this._disposed) {
+ return;
+ }
+
+ this._completedCallback(this.get_scriptElement(), false);
+ }
+ function Sys$_ScriptLoaderTask$_scriptLoadHandler() {
+ if(this._disposed) {
+ return;
+ }
+ var scriptElement = this.get_scriptElement();
+ if ((scriptElement.readyState !== 'loaded') &&
+ (scriptElement.readyState !== 'complete')) {
+ return;
+ }
+
+ this._completedCallback(scriptElement, true);
+ }
+Sys._ScriptLoaderTask.prototype = {
+ get_scriptElement: Sys$_ScriptLoaderTask$get_scriptElement,
+ dispose: Sys$_ScriptLoaderTask$dispose,
+ execute: Sys$_ScriptLoaderTask$execute,
+ _addScriptElementHandlers: Sys$_ScriptLoaderTask$_addScriptElementHandlers,
+ _removeScriptElementHandlers: Sys$_ScriptLoaderTask$_removeScriptElementHandlers,
+ _scriptErrorHandler: Sys$_ScriptLoaderTask$_scriptErrorHandler,
+ _scriptLoadHandler: Sys$_ScriptLoaderTask$_scriptLoadHandler
+}
+Sys._ScriptLoaderTask.registerClass("Sys._ScriptLoaderTask", null, Sys.IDisposable);
+Sys._ScriptLoaderTask._clearScript = function Sys$_ScriptLoaderTask$_clearScript(scriptElement) {
+ if (!Sys.Debug.isDebug) {
+ scriptElement.parentNode.removeChild(scriptElement);
+ }
+}
+Type.registerNamespace('Sys.Net');
+
+Sys.Net.WebServiceProxy = function Sys$Net$WebServiceProxy() {
+}
+ function Sys$Net$WebServiceProxy$get_timeout() {
+ /// <value type="Number" locid="P:J#Sys.Net.WebServiceProxy.timeout"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._timeout || 0;
+ }
+ function Sys$Net$WebServiceProxy$set_timeout(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Number}]);
+ if (e) throw e;
+ if (value < 0) { throw Error.argumentOutOfRange('value', value, Sys.Res.invalidTimeout); }
+ this._timeout = value;
+ }
+ function Sys$Net$WebServiceProxy$get_defaultUserContext() {
+ /// <value mayBeNull="true" locid="P:J#Sys.Net.WebServiceProxy.defaultUserContext"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return (typeof(this._userContext) === "undefined") ? null : this._userContext;
+ }
+ function Sys$Net$WebServiceProxy$set_defaultUserContext(value) {
+ var e = Function._validateParams(arguments, [{name: "value", mayBeNull: true}]);
+ if (e) throw e;
+ this._userContext = value;
+ }
+ function Sys$Net$WebServiceProxy$get_defaultSucceededCallback() {
+ /// <value type="Function" mayBeNull="true" locid="P:J#Sys.Net.WebServiceProxy.defaultSucceededCallback"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._succeeded || null;
+ }
+ function Sys$Net$WebServiceProxy$set_defaultSucceededCallback(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Function, mayBeNull: true}]);
+ if (e) throw e;
+ this._succeeded = value;
+ }
+ function Sys$Net$WebServiceProxy$get_defaultFailedCallback() {
+ /// <value type="Function" mayBeNull="true" locid="P:J#Sys.Net.WebServiceProxy.defaultFailedCallback"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._failed || null;
+ }
+ function Sys$Net$WebServiceProxy$set_defaultFailedCallback(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Function, mayBeNull: true}]);
+ if (e) throw e;
+ this._failed = value;
+ }
+ function Sys$Net$WebServiceProxy$get_enableJsonp() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.WebServiceProxy.enableJsonp"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return !!this._jsonp;
+ }
+ function Sys$Net$WebServiceProxy$set_enableJsonp(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: Boolean}]);
+ if (e) throw e;
+ this._jsonp = value;
+ }
+ function Sys$Net$WebServiceProxy$get_path() {
+ /// <value type="String" locid="P:J#Sys.Net.WebServiceProxy.path"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._path || null;
+ }
+ function Sys$Net$WebServiceProxy$set_path(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: String}]);
+ if (e) throw e;
+ this._path = value;
+ }
+ function Sys$Net$WebServiceProxy$get_jsonpCallbackParameter() {
+ /// <value type="String" locid="P:J#Sys.Net.WebServiceProxy.jsonpCallbackParameter"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._callbackParameter || "callback";
+ }
+ function Sys$Net$WebServiceProxy$set_jsonpCallbackParameter(value) {
+ var e = Function._validateParams(arguments, [{name: "value", type: String}]);
+ if (e) throw e;
+ this._callbackParameter = value;
+ }
+ function Sys$Net$WebServiceProxy$_invoke(servicePath, methodName, useGet, params, onSuccess, onFailure, userContext) {
+ /// <summary locid="M:J#Sys.Net.WebServiceProxy._invoke" />
+ /// <param name="servicePath" type="String"></param>
+ /// <param name="methodName" type="String"></param>
+ /// <param name="useGet" type="Boolean"></param>
+ /// <param name="params"></param>
+ /// <param name="onSuccess" type="Function" mayBeNull="true" optional="true"></param>
+ /// <param name="onFailure" type="Function" mayBeNull="true" optional="true"></param>
+ /// <param name="userContext" mayBeNull="true" optional="true"></param>
+ /// <returns type="Sys.Net.WebRequest" mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "servicePath", type: String},
+ {name: "methodName", type: String},
+ {name: "useGet", type: Boolean},
+ {name: "params"},
+ {name: "onSuccess", type: Function, mayBeNull: true, optional: true},
+ {name: "onFailure", type: Function, mayBeNull: true, optional: true},
+ {name: "userContext", mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ onSuccess = onSuccess || this.get_defaultSucceededCallback();
+ onFailure = onFailure || this.get_defaultFailedCallback();
+ if (userContext === null || typeof userContext === 'undefined') userContext = this.get_defaultUserContext();
+ return Sys.Net.WebServiceProxy.invoke(servicePath, methodName, useGet, params, onSuccess, onFailure, userContext, this.get_timeout(), this.get_enableJsonp(), this.get_jsonpCallbackParameter());
+ }
+Sys.Net.WebServiceProxy.prototype = {
+ get_timeout: Sys$Net$WebServiceProxy$get_timeout,
+ set_timeout: Sys$Net$WebServiceProxy$set_timeout,
+ get_defaultUserContext: Sys$Net$WebServiceProxy$get_defaultUserContext,
+ set_defaultUserContext: Sys$Net$WebServiceProxy$set_defaultUserContext,
+ get_defaultSucceededCallback: Sys$Net$WebServiceProxy$get_defaultSucceededCallback,
+ set_defaultSucceededCallback: Sys$Net$WebServiceProxy$set_defaultSucceededCallback,
+ get_defaultFailedCallback: Sys$Net$WebServiceProxy$get_defaultFailedCallback,
+ set_defaultFailedCallback: Sys$Net$WebServiceProxy$set_defaultFailedCallback,
+ get_enableJsonp: Sys$Net$WebServiceProxy$get_enableJsonp,
+ set_enableJsonp: Sys$Net$WebServiceProxy$set_enableJsonp,
+ get_path: Sys$Net$WebServiceProxy$get_path,
+ set_path: Sys$Net$WebServiceProxy$set_path,
+ get_jsonpCallbackParameter: Sys$Net$WebServiceProxy$get_jsonpCallbackParameter,
+ set_jsonpCallbackParameter: Sys$Net$WebServiceProxy$set_jsonpCallbackParameter,
+ _invoke: Sys$Net$WebServiceProxy$_invoke
+}
+Sys.Net.WebServiceProxy.registerClass('Sys.Net.WebServiceProxy');
+Sys.Net.WebServiceProxy.invoke = function Sys$Net$WebServiceProxy$invoke(servicePath, methodName, useGet, params, onSuccess, onFailure, userContext, timeout, enableJsonp, jsonpCallbackParameter) {
+ /// <summary locid="M:J#Sys.Net.WebServiceProxy.invoke" />
+ /// <param name="servicePath" type="String"></param>
+ /// <param name="methodName" type="String" mayBeNull="true" optional="true"></param>
+ /// <param name="useGet" type="Boolean" optional="true"></param>
+ /// <param name="params" mayBeNull="true" optional="true"></param>
+ /// <param name="onSuccess" type="Function" mayBeNull="true" optional="true"></param>
+ /// <param name="onFailure" type="Function" mayBeNull="true" optional="true"></param>
+ /// <param name="userContext" mayBeNull="true" optional="true"></param>
+ /// <param name="timeout" type="Number" optional="true"></param>
+ /// <param name="enableJsonp" type="Boolean" optional="true" mayBeNull="true"></param>
+ /// <param name="jsonpCallbackParameter" type="String" optional="true" mayBeNull="true"></param>
+ /// <returns type="Sys.Net.WebRequest" mayBeNull="true"></returns>
+ var e = Function._validateParams(arguments, [
+ {name: "servicePath", type: String},
+ {name: "methodName", type: String, mayBeNull: true, optional: true},
+ {name: "useGet", type: Boolean, optional: true},
+ {name: "params", mayBeNull: true, optional: true},
+ {name: "onSuccess", type: Function, mayBeNull: true, optional: true},
+ {name: "onFailure", type: Function, mayBeNull: true, optional: true},
+ {name: "userContext", mayBeNull: true, optional: true},
+ {name: "timeout", type: Number, optional: true},
+ {name: "enableJsonp", type: Boolean, mayBeNull: true, optional: true},
+ {name: "jsonpCallbackParameter", type: String, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ var schemeHost = (enableJsonp !== false) ? Sys.Net.WebServiceProxy._xdomain.exec(servicePath) : null,
+ tempCallback, jsonp = schemeHost && (schemeHost.length === 3) &&
+ ((schemeHost[1] !== location.protocol) || (schemeHost[2] !== location.host));
+ useGet = jsonp || useGet;
+ if (jsonp) {
+ jsonpCallbackParameter = jsonpCallbackParameter || "callback";
+ tempCallback = "_jsonp" + Sys._jsonp++;
+ }
+ if (!params) params = {};
+ var urlParams = params;
+ if (!useGet || !urlParams) urlParams = {};
+ var script, error, timeoutcookie = null, loader, body = null,
+ url = Sys.Net.WebRequest._createUrl(methodName
+ ? (servicePath+"/"+encodeURIComponent(methodName))
+ : servicePath, urlParams, jsonp ? (jsonpCallbackParameter + "=Sys." + tempCallback) : null);
+ if (jsonp) {
+ script = document.createElement("script");
+ script.src = url;
+ loader = new Sys._ScriptLoaderTask(script, function(script, loaded) {
+ if (!loaded || tempCallback) {
+ jsonpComplete({ Message: String.format(Sys.Res.webServiceFailedNoMsg, methodName) }, -1);
+ }
+ });
+ function jsonpComplete(data, statusCode) {
+ if (timeoutcookie !== null) {
+ window.clearTimeout(timeoutcookie);
+ timeoutcookie = null;
+ }
+ loader.dispose();
+ delete Sys[tempCallback];
+ tempCallback = null;
+ if ((typeof(statusCode) !== "undefined") && (statusCode !== 200)) {
+ if (onFailure) {
+ error = new Sys.Net.WebServiceError(false,
+ data.Message || String.format(Sys.Res.webServiceFailedNoMsg, methodName),
+ data.StackTrace || null,
+ data.ExceptionType || null,
+ data);
+ error._statusCode = statusCode;
+ onFailure(error, userContext, methodName);
+ }
+ else {
+ if (data.StackTrace && data.Message) {
+ error = data.StackTrace + "-- " + data.Message;
+ }
+ else {
+ error = data.StackTrace || data.Message;
+ }
+ error = String.format(error ? Sys.Res.webServiceFailed : Sys.Res.webServiceFailedNoMsg, methodName, error);
+ throw Sys.Net.WebServiceProxy._createFailedError(methodName, String.format(Sys.Res.webServiceFailed, methodName, error));
+ }
+ }
+ else if (onSuccess) {
+ onSuccess(data, userContext, methodName);
+ }
+ }
+ Sys[tempCallback] = jsonpComplete;
+ loader.execute();
+ return null;
+ }
+ var request = new Sys.Net.WebRequest();
+ request.set_url(url);
+ request.get_headers()['Content-Type'] = 'application/json; charset=utf-8';
+ if (!useGet) {
+ body = Sys.Serialization.JavaScriptSerializer.serialize(params);
+ if (body === "{}") body = "";
+ }
+ request.set_body(body);
+ request.add_completed(onComplete);
+ if (timeout && timeout > 0) request.set_timeout(timeout);
+ request.invoke();
+
+ function onComplete(response, eventArgs) {
+ if (response.get_responseAvailable()) {
+ var statusCode = response.get_statusCode();
+ var result = null;
+
+ try {
+ var contentType = response.getResponseHeader("Content-Type");
+ if (contentType.startsWith("application/json")) {
+ result = response.get_object();
+ }
+ else if (contentType.startsWith("text/xml")) {
+ result = response.get_xml();
+ }
+ else {
+ result = response.get_responseData();
+ }
+ } catch (ex) {
+ }
+ var error = response.getResponseHeader("jsonerror");
+ var errorObj = (error === "true");
+ if (errorObj) {
+ if (result) {
+ result = new Sys.Net.WebServiceError(false, result.Message, result.StackTrace, result.ExceptionType, result);
+ }
+ }
+ else if (contentType.startsWith("application/json")) {
+ result = (!result || (typeof(result.d) === "undefined")) ? result : result.d;
+ }
+ if (((statusCode < 200) || (statusCode >= 300)) || errorObj) {
+ if (onFailure) {
+ if (!result || !errorObj) {
+ result = new Sys.Net.WebServiceError(false , String.format(Sys.Res.webServiceFailedNoMsg, methodName));
+ }
+ result._statusCode = statusCode;
+ onFailure(result, userContext, methodName);
+ }
+ else {
+ if (result && errorObj) {
+ error = result.get_exceptionType() + "-- " + result.get_message();
+ }
+ else {
+ error = response.get_responseData();
+ }
+ throw Sys.Net.WebServiceProxy._createFailedError(methodName, String.format(Sys.Res.webServiceFailed, methodName, error));
+ }
+ }
+ else if (onSuccess) {
+ onSuccess(result, userContext, methodName);
+ }
+ }
+ else {
+ var msg;
+ if (response.get_timedOut()) {
+ msg = String.format(Sys.Res.webServiceTimedOut, methodName);
+ }
+ else {
+ msg = String.format(Sys.Res.webServiceFailedNoMsg, methodName)
+ }
+ if (onFailure) {
+ onFailure(new Sys.Net.WebServiceError(response.get_timedOut(), msg, "", ""), userContext, methodName);
+ }
+ else {
+ throw Sys.Net.WebServiceProxy._createFailedError(methodName, msg);
+ }
+ }
+ }
+ return request;
+}
+Sys.Net.WebServiceProxy._createFailedError = function Sys$Net$WebServiceProxy$_createFailedError(methodName, errorMessage) {
+ var displayMessage = "Sys.Net.WebServiceFailedException: " + errorMessage;
+ var e = Error.create(displayMessage, { 'name': 'Sys.Net.WebServiceFailedException', 'methodName': methodName });
+ e.popStackFrame();
+ return e;
+}
+Sys.Net.WebServiceProxy._defaultFailedCallback = function Sys$Net$WebServiceProxy$_defaultFailedCallback(err, methodName) {
+ var error = err.get_exceptionType() + "-- " + err.get_message();
+ throw Sys.Net.WebServiceProxy._createFailedError(methodName, String.format(Sys.Res.webServiceFailed, methodName, error));
+}
+Sys.Net.WebServiceProxy._generateTypedConstructor = function Sys$Net$WebServiceProxy$_generateTypedConstructor(type) {
+ return function(properties) {
+ if (properties) {
+ for (var name in properties) {
+ this[name] = properties[name];
+ }
+ }
+ this.__type = type;
+ }
+}
+Sys._jsonp = 0;
+Sys.Net.WebServiceProxy._xdomain = /^\s*([a-zA-Z0-9\+\-\.]+\:)\/\/([^?#\/]+)/;
+
+Sys.Net.WebServiceError = function Sys$Net$WebServiceError(timedOut, message, stackTrace, exceptionType, errorObject) {
+ /// <summary locid="M:J#Sys.Net.WebServiceError.#ctor" />
+ /// <param name="timedOut" type="Boolean"></param>
+ /// <param name="message" type="String" mayBeNull="true"></param>
+ /// <param name="stackTrace" type="String" mayBeNull="true" optional="true"></param>
+ /// <param name="exceptionType" type="String" mayBeNull="true" optional="true"></param>
+ /// <param name="errorObject" type="Object" mayBeNull="true" optional="true"></param>
+ var e = Function._validateParams(arguments, [
+ {name: "timedOut", type: Boolean},
+ {name: "message", type: String, mayBeNull: true},
+ {name: "stackTrace", type: String, mayBeNull: true, optional: true},
+ {name: "exceptionType", type: String, mayBeNull: true, optional: true},
+ {name: "errorObject", type: Object, mayBeNull: true, optional: true}
+ ]);
+ if (e) throw e;
+ this._timedOut = timedOut;
+ this._message = message;
+ this._stackTrace = stackTrace;
+ this._exceptionType = exceptionType;
+ this._errorObject = errorObject;
+ this._statusCode = -1;
+}
+ function Sys$Net$WebServiceError$get_timedOut() {
+ /// <value type="Boolean" locid="P:J#Sys.Net.WebServiceError.timedOut"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._timedOut;
+ }
+ function Sys$Net$WebServiceError$get_statusCode() {
+ /// <value type="Number" locid="P:J#Sys.Net.WebServiceError.statusCode"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._statusCode;
+ }
+ function Sys$Net$WebServiceError$get_message() {
+ /// <value type="String" locid="P:J#Sys.Net.WebServiceError.message"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._message;
+ }
+ function Sys$Net$WebServiceError$get_stackTrace() {
+ /// <value type="String" locid="P:J#Sys.Net.WebServiceError.stackTrace"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._stackTrace || "";
+ }
+ function Sys$Net$WebServiceError$get_exceptionType() {
+ /// <value type="String" locid="P:J#Sys.Net.WebServiceError.exceptionType"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._exceptionType || "";
+ }
+ function Sys$Net$WebServiceError$get_errorObject() {
+ /// <value type="Object" locid="P:J#Sys.Net.WebServiceError.errorObject"></value>
+ if (arguments.length !== 0) throw Error.parameterCount();
+ return this._errorObject || null;
+ }
+Sys.Net.WebServiceError.prototype = {
+ get_timedOut: Sys$Net$WebServiceError$get_timedOut,
+ get_statusCode: Sys$Net$WebServiceError$get_statusCode,
+ get_message: Sys$Net$WebServiceError$get_message,
+ get_stackTrace: Sys$Net$WebServiceError$get_stackTrace,
+ get_exceptionType: Sys$Net$WebServiceError$get_exceptionType,
+ get_errorObject: Sys$Net$WebServiceError$get_errorObject
+}
+Sys.Net.WebServiceError.registerClass('Sys.Net.WebServiceError');
+
+
+Type.registerNamespace('Sys');
+
+Sys.Res={
+'urlMustBeLessThan1024chars':'The history state must be small enough to not make the url larger than 1024 characters.',
+'argumentTypeName':'Value is not the name of an existing type.',
+'cantBeCalledAfterDispose':'Can\'t be called after dispose.',
+'componentCantSetIdAfterAddedToApp':'The id property of a component can\'t be set after it\'s been added to the Application object.',
+'behaviorDuplicateName':'A behavior with name \'{0}\' already exists or it is the name of an existing property on the target element.',
+'notATypeName':'Value is not a valid type name.',
+'elementNotFound':'An element with id \'{0}\' could not be found.',
+'stateMustBeStringDictionary':'The state object can only have null and string fields.',
+'boolTrueOrFalse':'Value must be \'true\' or \'false\'.',
+'scriptLoadFailedNoHead':'ScriptLoader requires pages to contain a <head> element.',
+'stringFormatInvalid':'The format string is invalid.',
+'referenceNotFound':'Component \'{0}\' was not found.',
+'enumReservedName':'\'{0}\' is a reserved name that can\'t be used as an enum value name.',
+'circularParentChain':'The chain of control parents can\'t have circular references.',
+'namespaceContainsNonObject':'Object {0} already exists and is not an object.',
+'undefinedEvent':'\'{0}\' is not an event.',
+'propertyUndefined':'\'{0}\' is not a property or an existing field.',
+'observableConflict':'Object already contains a member with the name \'{0}\'.',
+'historyCannotEnableHistory':'Cannot set enableHistory after initialization.',
+'eventHandlerInvalid':'Handler was not added through the Sys.UI.DomEvent.addHandler method.',
+'scriptLoadFailedDebug':'The script \'{0}\' failed to load. Check for:\r\n Inaccessible path.\r\n Script errors. (IE) Enable \'Display a notification about every script error\' under advanced settings.',
+'propertyNotWritable':'\'{0}\' is not a writable property.',
+'enumInvalidValueName':'\'{0}\' is not a valid name for an enum value.',
+'controlAlreadyDefined':'A control is already associated with the element.',
+'addHandlerCantBeUsedForError':'Can\'t add a handler for the error event using this method. Please set the window.onerror property instead.',
+'cantAddNonFunctionhandler':'Can\'t add a handler that is not a function.',
+'invalidNameSpace':'Value is not a valid namespace identifier.',
+'notAnInterface':'Value is not a valid interface.',
+'eventHandlerNotFunction':'Handler must be a function.',
+'propertyNotAnArray':'\'{0}\' is not an Array property.',
+'namespaceContainsClass':'Object {0} already exists as a class, enum, or interface.',
+'typeRegisteredTwice':'Type {0} has already been registered. The type may be defined multiple times or the script file that defines it may have already been loaded. A possible cause is a change of settings during a partial update.',
+'cantSetNameAfterInit':'The name property can\'t be set on this object after initialization.',
+'historyMissingFrame':'For the history feature to work in IE, the page must have an iFrame element with id \'__historyFrame\' pointed to a page that gets its title from the \'title\' query string parameter and calls Sys.Application._onIFrameLoad() on the parent window. This can be done by setting EnableHistory to true on ScriptManager.',
+'appDuplicateComponent':'Two components with the same id \'{0}\' can\'t be added to the application.',
+'historyCannotAddHistoryPointWithHistoryDisabled':'A history point can only be added if enableHistory is set to true.',
+'baseNotAClass':'Value is not a class.',
+'expectedElementOrId':'Value must be a DOM element or DOM element Id.',
+'methodNotFound':'No method found with name \'{0}\'.',
+'arrayParseBadFormat':'Value must be a valid string representation for an array. It must start with a \'[\' and end with a \']\'.',
+'stateFieldNameInvalid':'State field names must not contain any \'=\' characters.',
+'cantSetId':'The id property can\'t be set on this object.',
+'stringFormatBraceMismatch':'The format string contains an unmatched opening or closing brace.',
+'enumValueNotInteger':'An enumeration definition can only contain integer values.',
+'propertyNullOrUndefined':'Cannot set the properties of \'{0}\' because it returned a null value.',
+'argumentDomNode':'Value must be a DOM element or a text node.',
+'componentCantSetIdTwice':'The id property of a component can\'t be set more than once.',
+'createComponentOnDom':'Value must be null for Components that are not Controls or Behaviors.',
+'createNotComponent':'{0} does not derive from Sys.Component.',
+'createNoDom':'Value must not be null for Controls and Behaviors.',
+'cantAddWithoutId':'Can\'t add a component that doesn\'t have an id.',
+'notObservable':'Instances of type \'{0}\' cannot be observed.',
+'badTypeName':'Value is not the name of the type being registered or the name is a reserved word.',
+'argumentInteger':'Value must be an integer.',
+'invokeCalledTwice':'Cannot call invoke more than once.',
+'webServiceFailed':'The server method \'{0}\' failed with the following error: {1}',
+'argumentType':'Object cannot be converted to the required type.',
+'argumentNull':'Value cannot be null.',
+'scriptAlreadyLoaded':'The script \'{0}\' has been referenced multiple times. If referencing Microsoft AJAX scripts explicitly, set the MicrosoftAjaxMode property of the ScriptManager to Explicit.',
+'scriptDependencyNotFound':'The script \'{0}\' failed to load because it is dependent on script \'{1}\'.',
+'formatBadFormatSpecifier':'Format specifier was invalid.',
+'requiredScriptReferenceNotIncluded':'\'{0}\' requires that you have included a script reference to \'{1}\'.',
+'webServiceFailedNoMsg':'The server method \'{0}\' failed.',
+'argumentDomElement':'Value must be a DOM element.',
+'invalidExecutorType':'Could not create a valid Sys.Net.WebRequestExecutor from: {0}.',
+'cannotCallBeforeResponse':'Cannot call {0} when responseAvailable is false.',
+'actualValue':'Actual value was {0}.',
+'enumInvalidValue':'\'{0}\' is not a valid value for enum {1}.',
+'scriptLoadFailed':'The script \'{0}\' could not be loaded.',
+'parameterCount':'Parameter count mismatch.',
+'cannotDeserializeEmptyString':'Cannot deserialize empty string.',
+'formatInvalidString':'Input string was not in a correct format.',
+'invalidTimeout':'Value must be greater than or equal to zero.',
+'cannotAbortBeforeStart':'Cannot abort when executor has not started.',
+'argument':'Value does not fall within the expected range.',
+'cannotDeserializeInvalidJson':'Cannot deserialize. The data does not correspond to valid JSON.',
+'invalidHttpVerb':'httpVerb cannot be set to an empty or null string.',
+'nullWebRequest':'Cannot call executeRequest with a null webRequest.',
+'eventHandlerInvalid':'Handler was not added through the Sys.UI.DomEvent.addHandler method.',
+'cannotSerializeNonFiniteNumbers':'Cannot serialize non finite numbers.',
+'argumentUndefined':'Value cannot be undefined.',
+'webServiceInvalidReturnType':'The server method \'{0}\' returned an invalid type. Expected type: {1}',
+'servicePathNotSet':'The path to the web service has not been set.',
+'argumentTypeWithTypes':'Object of type \'{0}\' cannot be converted to type \'{1}\'.',
+'cannotCallOnceStarted':'Cannot call {0} once started.',
+'badBaseUrl1':'Base URL does not contain ://.',
+'badBaseUrl2':'Base URL does not contain another /.',
+'badBaseUrl3':'Cannot find last / in base URL.',
+'setExecutorAfterActive':'Cannot set executor after it has become active.',
+'paramName':'Parameter name: {0}',
+'nullReferenceInPath':'Null reference while evaluating data path: \'{0}\'.',
+'cannotCallOutsideHandler':'Cannot call {0} outside of a completed event handler.',
+'cannotSerializeObjectWithCycle':'Cannot serialize object with cyclic reference within child properties.',
+'format':'One of the identified items was in an invalid format.',
+'assertFailedCaller':'Assertion Failed: {0}\r\nat {1}',
+'argumentOutOfRange':'Specified argument was out of the range of valid values.',
+'webServiceTimedOut':'The server method \'{0}\' timed out.',
+'notImplemented':'The method or operation is not implemented.',
+'assertFailed':'Assertion Failed: {0}',
+'invalidOperation':'Operation is not valid due to the current state of the object.',
+'breakIntoDebugger':'{0}\r\n\r\nBreak into debugger?'
+};
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftAjax.js b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftAjax.js
new file mode 100644
index 0000000..52e6626
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftAjax.js
@@ -0,0 +1,6 @@
+//----------------------------------------------------------
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//----------------------------------------------------------
+// MicrosoftAjax.js
+Function.__typeName="Function";Function.__class=true;Function.createCallback=function(b,a){return function(){var e=arguments.length;if(e>0){var d=[];for(var c=0;c<e;c++)d[c]=arguments[c];d[e]=a;return b.apply(this,d)}return b.call(this,a)}};Function.createDelegate=function(a,b){return function(){return b.apply(a,arguments)}};Function.emptyFunction=Function.emptyMethod=function(){};Function.validateParameters=function(c,b,a){return Function._validateParams(c,b,a)};Function._validateParams=function(g,e,c){var a,d=e.length;c=c||typeof c==="undefined";a=Function._validateParameterCount(g,e,c);if(a){a.popStackFrame();return a}for(var b=0,i=g.length;b<i;b++){var f=e[Math.min(b,d-1)],h=f.name;if(f.parameterArray)h+="["+(b-d+1)+"]";else if(!c&&b>=d)break;a=Function._validateParameter(g[b],f,h);if(a){a.popStackFrame();return a}}return null};Function._validateParameterCount=function(j,d,i){var a,c,b=d.length,e=j.length;if(e<b){var f=b;for(a=0;a<b;a++){var g=d[a];if(g.optional||g.parameterArray)f--}if(e<f)c=true}else if(i&&e>b){c=true;for(a=0;a<b;a++)if(d[a].parameterArray){c=false;break}}if(c){var h=Error.parameterCount();h.popStackFrame();return h}return null};Function._validateParameter=function(c,a,h){var b,g=a.type,l=!!a.integer,k=!!a.domElement,m=!!a.mayBeNull;b=Function._validateParameterType(c,g,l,k,m,h);if(b){b.popStackFrame();return b}var e=a.elementType,f=!!a.elementMayBeNull;if(g===Array&&typeof c!=="undefined"&&c!==null&&(e||!f)){var j=!!a.elementInteger,i=!!a.elementDomElement;for(var d=0;d<c.length;d++){var n=c[d];b=Function._validateParameterType(n,e,j,i,f,h+"["+d+"]");if(b){b.popStackFrame();return b}}}return null};Function._validateParameterType=function(b,c,k,j,h,d){var a,g;if(typeof b==="undefined")if(h)return null;else{a=Error.argumentUndefined(d);a.popStackFrame();return a}if(b===null)if(h)return null;else{a=Error.argumentNull(d);a.popStackFrame();return a}if(c&&c.__enum){if(typeof b!=="number"){a=Error.argumentType(d,Object.getType(b),c);a.popStackFrame();return a}if(b%1===0){var e=c.prototype;if(!c.__flags||b===0){for(g in e)if(e[g]===b)return null}else{var i=b;for(g in e){var f=e[g];if(f===0)continue;if((f&b)===f)i-=f;if(i===0)return null}}}a=Error.argumentOutOfRange(d,b,String.format(Sys.Res.enumInvalidValue,b,c.getName()));a.popStackFrame();return a}if(j&&(!Sys._isDomElement(b)||b.nodeType===3)){a=Error.argument(d,Sys.Res.argumentDomElement);a.popStackFrame();return a}if(c&&!Sys._isInstanceOfType(c,b)){a=Error.argumentType(d,Object.getType(b),c);a.popStackFrame();return a}if(c===Number&&k)if(b%1!==0){a=Error.argumentOutOfRange(d,b,Sys.Res.argumentInteger);a.popStackFrame();return a}return null};Error.__typeName="Error";Error.__class=true;Error.create=function(d,b){var a=new Error(d);a.message=d;if(b)for(var c in b)a[c]=b[c];a.popStackFrame();return a};Error.argument=function(a,c){var b="Sys.ArgumentException: "+(c?c:Sys.Res.argument);if(a)b+="\n"+String.format(Sys.Res.paramName,a);var d=Error.create(b,{name:"Sys.ArgumentException",paramName:a});d.popStackFrame();return d};Error.argumentNull=function(a,c){var b="Sys.ArgumentNullException: "+(c?c:Sys.Res.argumentNull);if(a)b+="\n"+String.format(Sys.Res.paramName,a);var d=Error.create(b,{name:"Sys.ArgumentNullException",paramName:a});d.popStackFrame();return d};Error.argumentOutOfRange=function(c,a,d){var b="Sys.ArgumentOutOfRangeException: "+(d?d:Sys.Res.argumentOutOfRange);if(c)b+="\n"+String.format(Sys.Res.paramName,c);if(typeof a!=="undefined"&&a!==null)b+="\n"+String.format(Sys.Res.actualValue,a);var e=Error.create(b,{name:"Sys.ArgumentOutOfRangeException",paramName:c,actualValue:a});e.popStackFrame();return e};Error.argumentType=function(d,c,b,e){var a="Sys.ArgumentTypeException: ";if(e)a+=e;else if(c&&b)a+=String.format(Sys.Res.argumentTypeWithTypes,c.getName(),b.getName());else a+=Sys.Res.argumentType;if(d)a+="\n"+String.format(Sys.Res.paramName,d);var f=Error.create(a,{name:"Sys.ArgumentTypeException",paramName:d,actualType:c,expectedType:b});f.popStackFrame();return f};Error.argumentUndefined=function(a,c){var b="Sys.ArgumentUndefinedException: "+(c?c:Sys.Res.argumentUndefined);if(a)b+="\n"+String.format(Sys.Res.paramName,a);var d=Error.create(b,{name:"Sys.ArgumentUndefinedException",paramName:a});d.popStackFrame();return d};Error.format=function(a){var c="Sys.FormatException: "+(a?a:Sys.Res.format),b=Error.create(c,{name:"Sys.FormatException"});b.popStackFrame();return b};Error.invalidOperation=function(a){var c="Sys.InvalidOperationException: "+(a?a:Sys.Res.invalidOperation),b=Error.create(c,{name:"Sys.InvalidOperationException"});b.popStackFrame();return b};Error.notImplemented=function(a){var c="Sys.NotImplementedException: "+(a?a:Sys.Res.notImplemented),b=Error.create(c,{name:"Sys.NotImplementedException"});b.popStackFrame();return b};Error.parameterCount=function(a){var c="Sys.ParameterCountException: "+(a?a:Sys.Res.parameterCount),b=Error.create(c,{name:"Sys.ParameterCountException"});b.popStackFrame();return b};Error.prototype.popStackFrame=function(){if(typeof this.stack==="undefined"||this.stack===null||typeof this.fileName==="undefined"||this.fileName===null||typeof this.lineNumber==="undefined"||this.lineNumber===null)return;var a=this.stack.split("\n"),c=a[0],e=this.fileName+":"+this.lineNumber;while(typeof c!=="undefined"&&c!==null&&c.indexOf(e)===-1){a.shift();c=a[0]}var d=a[1];if(typeof d==="undefined"||d===null)return;var b=d.match(/@(.*):(\d+)$/);if(typeof b==="undefined"||b===null)return;this.fileName=b[1];this.lineNumber=parseInt(b[2]);a.shift();this.stack=a.join("\n")};Object.__typeName="Object";Object.__class=true;Object.getType=function(b){var a=b.constructor;if(!a||typeof a!=="function"||!a.__typeName||a.__typeName==="Object")return Object;return a};Object.getTypeName=function(a){return Object.getType(a).getName()};String.__typeName="String";String.__class=true;String.prototype.endsWith=function(a){return this.substr(this.length-a.length)===a};String.prototype.startsWith=function(a){return this.substr(0,a.length)===a};String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")};String.prototype.trimEnd=function(){return this.replace(/\s+$/,"")};String.prototype.trimStart=function(){return this.replace(/^\s+/,"")};String.format=function(){return String._toFormattedString(false,arguments)};String._toFormattedString=function(l,j){var c="",e=j[0];for(var a=0;true;){var f=e.indexOf("{",a),d=e.indexOf("}",a);if(f<0&&d<0){c+=e.slice(a);break}if(d>0&&(d<f||f<0)){c+=e.slice(a,d+1);a=d+2;continue}c+=e.slice(a,f);a=f+1;if(e.charAt(a)==="{"){c+="{";a++;continue}if(d<0)break;var h=e.substring(a,d),g=h.indexOf(":"),k=parseInt(g<0?h:h.substring(0,g),10)+1,i=g<0?"":h.substring(g+1),b=j[k];if(typeof b==="undefined"||b===null)b="";if(b.toFormattedString)c+=b.toFormattedString(i);else if(l&&b.localeFormat)c+=b.localeFormat(i);else if(b.format)c+=b.format(i);else c+=b.toString();a=d+1}return c};Boolean.__typeName="Boolean";Boolean.__class=true;Boolean.parse=function(b){var a=b.trim().toLowerCase();if(a==="false")return false;if(a==="true")return true};Date.__typeName="Date";Date.__class=true;Number.__typeName="Number";Number.__class=true;RegExp.__typeName="RegExp";RegExp.__class=true;if(!window)this.window=this;window.Type=Function;Type.prototype.callBaseMethod=function(a,d,b){var c=Sys._getBaseMethod(this,a,d);if(!b)return c.apply(a);else return c.apply(a,b)};Type.prototype.getBaseMethod=function(a,b){return Sys._getBaseMethod(this,a,b)};Type.prototype.getBaseType=function(){return typeof this.__baseType==="undefined"?null:this.__baseType};Type.prototype.getInterfaces=function(){var a=[],b=this;while(b){var c=b.__interfaces;if(c)for(var d=0,f=c.length;d<f;d++){var e=c[d];if(!Array.contains(a,e))a[a.length]=e}b=b.__baseType}return a};Type.prototype.getName=function(){return typeof this.__typeName==="undefined"?"":this.__typeName};Type.prototype.implementsInterface=function(d){this.resolveInheritance();var c=d.getName(),a=this.__interfaceCache;if(a){var e=a[c];if(typeof e!=="undefined")return e}else a=this.__interfaceCache={};var b=this;while(b){var f=b.__interfaces;if(f)if(Array.indexOf(f,d)!==-1)return a[c]=true;b=b.__baseType}return a[c]=false};Type.prototype.inheritsFrom=function(b){this.resolveInheritance();var a=this.__baseType;while(a){if(a===b)return true;a=a.__baseType}return false};Type.prototype.initializeBase=function(a,b){this.resolveInheritance();if(this.__baseType)if(!b)this.__baseType.apply(a);else this.__baseType.apply(a,b);return a};Type.prototype.isImplementedBy=function(a){if(typeof a==="undefined"||a===null)return false;var b=Object.getType(a);return !!(b.implementsInterface&&b.implementsInterface(this))};Type.prototype.isInstanceOfType=function(a){return Sys._isInstanceOfType(this,a)};Type.prototype.registerClass=function(c,b,d){this.prototype.constructor=this;this.__typeName=c;this.__class=true;if(b){this.__baseType=b;this.__basePrototypePending=true}Sys.__upperCaseTypes[c.toUpperCase()]=this;if(d){this.__interfaces=[];for(var a=2,f=arguments.length;a<f;a++){var e=arguments[a];this.__interfaces.push(e)}}return this};Type.prototype.registerInterface=function(a){Sys.__upperCaseTypes[a.toUpperCase()]=this;this.prototype.constructor=this;this.__typeName=a;this.__interface=true;return this};Type.prototype.resolveInheritance=function(){if(this.__basePrototypePending){var b=this.__baseType;b.resolveInheritance();for(var a in b.prototype){var c=b.prototype[a];if(!this.prototype[a])this.prototype[a]=c}delete this.__basePrototypePending}};Type.getRootNamespaces=function(){return Array.clone(Sys.__rootNamespaces)};Type.isClass=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__class};Type.isInterface=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__interface};Type.isNamespace=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__namespace};Type.parse=function(typeName,ns){var fn;if(ns){fn=Sys.__upperCaseTypes[ns.getName().toUpperCase()+"."+typeName.toUpperCase()];return fn||null}if(!typeName)return null;if(!Type.__htClasses)Type.__htClasses={};fn=Type.__htClasses[typeName];if(!fn){fn=eval(typeName);Type.__htClasses[typeName]=fn}return fn};Type.registerNamespace=function(e){var d=window,c=e.split(".");for(var b=0;b<c.length;b++){var f=c[b],a=d[f];if(!a)a=d[f]={};if(!a.__namespace){if(b===0&&e!=="Sys")Sys.__rootNamespaces[Sys.__rootNamespaces.length]=a;a.__namespace=true;a.__typeName=c.slice(0,b+1).join(".");a.getName=function(){return this.__typeName}}d=a}};Type._checkDependency=function(c,a){var d=Type._registerScript._scripts,b=d?!!d[c]:false;if(typeof a!=="undefined"&&!b)throw Error.invalidOperation(String.format(Sys.Res.requiredScriptReferenceNotIncluded,a,c));return b};Type._registerScript=function(a,c){var b=Type._registerScript._scripts;if(!b)Type._registerScript._scripts=b={};if(b[a])throw Error.invalidOperation(String.format(Sys.Res.scriptAlreadyLoaded,a));b[a]=true;if(c)for(var d=0,f=c.length;d<f;d++){var e=c[d];if(!Type._checkDependency(e))throw Error.invalidOperation(String.format(Sys.Res.scriptDependencyNotFound,a,e))}};Type.registerNamespace("Sys");Sys.__upperCaseTypes={};Sys.__rootNamespaces=[Sys];Sys._isInstanceOfType=function(c,b){if(typeof b==="undefined"||b===null)return false;if(b instanceof c)return true;var a=Object.getType(b);return !!(a===c)||a.inheritsFrom&&a.inheritsFrom(c)||a.implementsInterface&&a.implementsInterface(c)};Sys._getBaseMethod=function(d,e,c){var b=d.getBaseType();if(b){var a=b.prototype[c];return a instanceof Function?a:null}return null};Sys._isDomElement=function(a){var c=false;if(typeof a.nodeType!=="number"){var b=a.ownerDocument||a.document||a;if(b!=a){var d=b.defaultView||b.parentWindow;c=d!=a}else c=typeof b.body==="undefined"}return !c};Array.__typeName="Array";Array.__class=true;Array.add=Array.enqueue=function(a,b){a[a.length]=b};Array.addRange=function(a,b){a.push.apply(a,b)};Array.clear=function(a){a.length=0};Array.clone=function(a){if(a.length===1)return [a[0]];else return Array.apply(null,a)};Array.contains=function(a,b){return Sys._indexOf(a,b)>=0};Array.dequeue=function(a){return a.shift()};Array.forEach=function(b,e,d){for(var a=0,f=b.length;a<f;a++){var c=b[a];if(typeof c!=="undefined")e.call(d,c,a,b)}};Array.indexOf=function(a,c,b){return Sys._indexOf(a,c,b)};Array.insert=function(a,b,c){a.splice(b,0,c)};Array.parse=function(value){if(!value)return [];return eval(value)};Array.remove=function(b,c){var a=Sys._indexOf(b,c);if(a>=0)b.splice(a,1);return a>=0};Array.removeAt=function(a,b){a.splice(b,1)};Sys._indexOf=function(d,e,a){if(typeof e==="undefined")return -1;var c=d.length;if(c!==0){a=a-0;if(isNaN(a))a=0;else{if(isFinite(a))a=a-a%1;if(a<0)a=Math.max(0,c+a)}for(var b=a;b<c;b++)if(typeof d[b]!=="undefined"&&d[b]===e)return b}return -1};Type._registerScript._scripts={"MicrosoftAjaxCore.js":true,"MicrosoftAjaxGlobalization.js":true,"MicrosoftAjaxSerialization.js":true,"MicrosoftAjaxComponentModel.js":true,"MicrosoftAjaxHistory.js":true,"MicrosoftAjaxNetwork.js":true,"MicrosoftAjaxWebServices.js":true};Sys.IDisposable=function(){};Sys.IDisposable.prototype={};Sys.IDisposable.registerInterface("Sys.IDisposable");Sys.StringBuilder=function(a){this._parts=typeof a!=="undefined"&&a!==null&&a!==""?[a.toString()]:[];this._value={};this._len=0};Sys.StringBuilder.prototype={append:function(a){this._parts[this._parts.length]=a},appendLine:function(a){this._parts[this._parts.length]=typeof a==="undefined"||a===null||a===""?"\r\n":a+"\r\n"},clear:function(){this._parts=[];this._value={};this._len=0},isEmpty:function(){if(this._parts.length===0)return true;return this.toString()===""},toString:function(a){a=a||"";var b=this._parts;if(this._len!==b.length){this._value={};this._len=b.length}var d=this._value;if(typeof d[a]==="undefined"){if(a!=="")for(var c=0;c<b.length;)if(typeof b[c]==="undefined"||b[c]===""||b[c]===null)b.splice(c,1);else c++;d[a]=this._parts.join(a)}return d[a]}};Sys.StringBuilder.registerClass("Sys.StringBuilder");Sys.Browser={};Sys.Browser.InternetExplorer={};Sys.Browser.Firefox={};Sys.Browser.Safari={};Sys.Browser.Opera={};Sys.Browser.agent=null;Sys.Browser.hasDebuggerStatement=false;Sys.Browser.name=navigator.appName;Sys.Browser.version=parseFloat(navigator.appVersion);Sys.Browser.documentMode=0;if(navigator.userAgent.indexOf(" MSIE ")>-1){Sys.Browser.agent=Sys.Browser.InternetExplorer;Sys.Browser.version=parseFloat(navigator.userAgent.match(/MSIE (\d+\.\d+)/)[1]);if(Sys.Browser.version>=8)if(document.documentMode>=7)Sys.Browser.documentMode=document.documentMode;Sys.Browser.hasDebuggerStatement=true}else if(navigator.userAgent.indexOf(" Firefox/")>-1){Sys.Browser.agent=Sys.Browser.Firefox;Sys.Browser.version=parseFloat(navigator.userAgent.match(/Firefox\/(\d+\.\d+)/)[1]);Sys.Browser.name="Firefox";Sys.Browser.hasDebuggerStatement=true}else if(navigator.userAgent.indexOf(" AppleWebKit/")>-1){Sys.Browser.agent=Sys.Browser.Safari;Sys.Browser.version=parseFloat(navigator.userAgent.match(/AppleWebKit\/(\d+(\.\d+)?)/)[1]);Sys.Browser.name="Safari"}else if(navigator.userAgent.indexOf("Opera/")>-1)Sys.Browser.agent=Sys.Browser.Opera;Sys.EventArgs=function(){};Sys.EventArgs.registerClass("Sys.EventArgs");Sys.EventArgs.Empty=new Sys.EventArgs;Sys.CancelEventArgs=function(){Sys.CancelEventArgs.initializeBase(this);this._cancel=false};Sys.CancelEventArgs.prototype={get_cancel:function(){return this._cancel},set_cancel:function(a){this._cancel=a}};Sys.CancelEventArgs.registerClass("Sys.CancelEventArgs",Sys.EventArgs);Type.registerNamespace("Sys.UI");Sys._Debug=function(){};Sys._Debug.prototype={_appendConsole:function(a){if(typeof Debug!=="undefined"&&Debug.writeln)Debug.writeln(a);if(window.console&&window.console.log)window.console.log(a);if(window.opera)window.opera.postError(a);if(window.debugService)window.debugService.trace(a)},_appendTrace:function(b){var a=document.getElementById("TraceConsole");if(a&&a.tagName.toUpperCase()==="TEXTAREA")a.value+=b+"\n"},assert:function(c,a,b){if(!c){a=b&&this.assert.caller?String.format(Sys.Res.assertFailedCaller,a,this.assert.caller):String.format(Sys.Res.assertFailed,a);if(confirm(String.format(Sys.Res.breakIntoDebugger,a)))this.fail(a)}},clearTrace:function(){var a=document.getElementById("TraceConsole");if(a&&a.tagName.toUpperCase()==="TEXTAREA")a.value=""},fail:function(message){this._appendConsole(message);if(Sys.Browser.hasDebuggerStatement)eval("debugger")},trace:function(a){this._appendConsole(a);this._appendTrace(a)},traceDump:function(a,b){var c=this._traceDump(a,b,true)},_traceDump:function(a,c,f,b,d){c=c?c:"traceDump";b=b?b:"";if(a===null){this.trace(b+c+": null");return}switch(typeof a){case "undefined":this.trace(b+c+": Undefined");break;case "number":case "string":case "boolean":this.trace(b+c+": "+a);break;default:if(Date.isInstanceOfType(a)||RegExp.isInstanceOfType(a)){this.trace(b+c+": "+a.toString());break}if(!d)d=[];else if(Array.contains(d,a)){this.trace(b+c+": ...");return}Array.add(d,a);if(a==window||a===document||window.HTMLElement&&a instanceof HTMLElement||typeof a.nodeName==="string"){var k=a.tagName?a.tagName:"DomElement";if(a.id)k+=" - "+a.id;this.trace(b+c+" {"+k+"}")}else{var i=Object.getTypeName(a);this.trace(b+c+(typeof i==="string"?" {"+i+"}":""));if(b===""||f){b+=" ";var e,j,l,g,h;if(Array.isInstanceOfType(a)){j=a.length;for(e=0;e<j;e++)this._traceDump(a[e],"["+e+"]",f,b,d)}else for(g in a){h=a[g];if(!Function.isInstanceOfType(h))this._traceDump(h,g,f,b,d)}}}Array.remove(d,a)}}};Sys._Debug.registerClass("Sys._Debug");Sys.Debug=new Sys._Debug;Sys.Debug.isDebug=false;function Sys$Enum$parse(c,e){var a,b,i;if(e){a=this.__lowerCaseValues;if(!a){this.__lowerCaseValues=a={};var g=this.prototype;for(var f in g)a[f.toLowerCase()]=g[f]}}else a=this.prototype;if(!this.__flags){i=e?c.toLowerCase():c;b=a[i.trim()];if(typeof b!=="number")throw Error.argument("value",String.format(Sys.Res.enumInvalidValue,c,this.__typeName));return b}else{var h=(e?c.toLowerCase():c).split(","),j=0;for(var d=h.length-1;d>=0;d--){var k=h[d].trim();b=a[k];if(typeof b!=="number")throw Error.argument("value",String.format(Sys.Res.enumInvalidValue,c.split(",")[d].trim(),this.__typeName));j|=b}return j}}function Sys$Enum$toString(c){if(typeof c==="undefined"||c===null)return this.__string;var d=this.prototype,a;if(!this.__flags||c===0){for(a in d)if(d[a]===c)return a}else{var b=this.__sortedValues;if(!b){b=[];for(a in d)b[b.length]={key:a,value:d[a]};b.sort(function(a,b){return a.value-b.value});this.__sortedValues=b}var e=[],g=c;for(a=b.length-1;a>=0;a--){var h=b[a],f=h.value;if(f===0)continue;if((f&c)===f){e[e.length]=h.key;g-=f;if(g===0)break}}if(e.length&&g===0)return e.reverse().join(", ")}return ""}Type.prototype.registerEnum=function(b,c){Sys.__upperCaseTypes[b.toUpperCase()]=this;for(var a in this.prototype)this[a]=this.prototype[a];this.__typeName=b;this.parse=Sys$Enum$parse;this.__string=this.toString();this.toString=Sys$Enum$toString;this.__flags=c;this.__enum=true};Type.isEnum=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__enum};Type.isFlags=function(a){if(typeof a==="undefined"||a===null)return false;return !!a.__flags};Sys.CollectionChange=function(e,a,c,b,d){this.action=e;if(a)if(!(a instanceof Array))a=[a];this.newItems=a||null;if(typeof c!=="number")c=-1;this.newStartingIndex=c;if(b)if(!(b instanceof Array))b=[b];this.oldItems=b||null;if(typeof d!=="number")d=-1;this.oldStartingIndex=d};Sys.CollectionChange.registerClass("Sys.CollectionChange");Sys.NotifyCollectionChangedAction=function(){throw Error.notImplemented()};Sys.NotifyCollectionChangedAction.prototype={add:0,remove:1,reset:2};Sys.NotifyCollectionChangedAction.registerEnum("Sys.NotifyCollectionChangedAction");Sys.NotifyCollectionChangedEventArgs=function(a){this._changes=a;Sys.NotifyCollectionChangedEventArgs.initializeBase(this)};Sys.NotifyCollectionChangedEventArgs.prototype={get_changes:function(){return this._changes||[]}};Sys.NotifyCollectionChangedEventArgs.registerClass("Sys.NotifyCollectionChangedEventArgs",Sys.EventArgs);Sys.Observer=function(){};Sys.Observer.registerClass("Sys.Observer");Sys.Observer.makeObservable=function(a){var c=a instanceof Array,b=Sys.Observer;if(a.setValue===b._observeMethods.setValue)return a;b._addMethods(a,b._observeMethods);if(c)b._addMethods(a,b._arrayMethods);return a};Sys.Observer._addMethods=function(c,b){for(var a in b)c[a]=b[a]};Sys.Observer._addEventHandler=function(c,a,b){Sys.Observer._getContext(c,true).events._addHandler(a,b)};Sys.Observer.addEventHandler=function(c,a,b){Sys.Observer._addEventHandler(c,a,b)};Sys.Observer._removeEventHandler=function(c,a,b){Sys.Observer._getContext(c,true).events._removeHandler(a,b)};Sys.Observer.removeEventHandler=function(c,a,b){Sys.Observer._removeEventHandler(c,a,b)};Sys.Observer.raiseEvent=function(b,e,d){var c=Sys.Observer._getContext(b);if(!c)return;var a=c.events.getHandler(e);if(a)a(b,d)};Sys.Observer.addPropertyChanged=function(b,a){Sys.Observer._addEventHandler(b,"propertyChanged",a)};Sys.Observer.removePropertyChanged=function(b,a){Sys.Observer._removeEventHandler(b,"propertyChanged",a)};Sys.Observer.beginUpdate=function(a){Sys.Observer._getContext(a,true).updating=true};Sys.Observer.endUpdate=function(b){var a=Sys.Observer._getContext(b);if(!a||!a.updating)return;a.updating=false;var d=a.dirty;a.dirty=false;if(d){if(b instanceof Array){var c=a.changes;a.changes=null;Sys.Observer.raiseCollectionChanged(b,c)}Sys.Observer.raisePropertyChanged(b,"")}};Sys.Observer.isUpdating=function(b){var a=Sys.Observer._getContext(b);return a?a.updating:false};Sys.Observer._setValue=function(a,j,g){var b,f,k=a,d=j.split(".");for(var i=0,m=d.length-1;i<m;i++){var l=d[i];b=a["get_"+l];if(typeof b==="function")a=b.call(a);else a=a[l];var n=typeof a;if(a===null||n==="undefined")throw Error.invalidOperation(String.format(Sys.Res.nullReferenceInPath,j))}var e,c=d[m];b=a["get_"+c];f=a["set_"+c];if(typeof b==="function")e=b.call(a);else e=a[c];if(typeof f==="function")f.call(a,g);else a[c]=g;if(e!==g){var h=Sys.Observer._getContext(k);if(h&&h.updating){h.dirty=true;return}Sys.Observer.raisePropertyChanged(k,d[0])}};Sys.Observer.setValue=function(b,a,c){Sys.Observer._setValue(b,a,c)};Sys.Observer.raisePropertyChanged=function(b,a){Sys.Observer.raiseEvent(b,"propertyChanged",new Sys.PropertyChangedEventArgs(a))};Sys.Observer.addCollectionChanged=function(b,a){Sys.Observer._addEventHandler(b,"collectionChanged",a)};Sys.Observer.removeCollectionChanged=function(b,a){Sys.Observer._removeEventHandler(b,"collectionChanged",a)};Sys.Observer._collectionChange=function(d,c){var a=Sys.Observer._getContext(d);if(a&&a.updating){a.dirty=true;var b=a.changes;if(!b)a.changes=b=[c];else b.push(c)}else{Sys.Observer.raiseCollectionChanged(d,[c]);Sys.Observer.raisePropertyChanged(d,"length")}};Sys.Observer.add=function(a,b){var c=new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.add,[b],a.length);Array.add(a,b);Sys.Observer._collectionChange(a,c)};Sys.Observer.addRange=function(a,b){var c=new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.add,b,a.length);Array.addRange(a,b);Sys.Observer._collectionChange(a,c)};Sys.Observer.clear=function(a){var b=Array.clone(a);Array.clear(a);Sys.Observer._collectionChange(a,new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.reset,null,-1,b,0))};Sys.Observer.insert=function(a,b,c){Array.insert(a,b,c);Sys.Observer._collectionChange(a,new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.add,[c],b))};Sys.Observer.remove=function(a,b){var c=Array.indexOf(a,b);if(c!==-1){Array.remove(a,b);Sys.Observer._collectionChange(a,new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.remove,null,-1,[b],c));return true}return false};Sys.Observer.removeAt=function(b,a){if(a>-1&&a<b.length){var c=b[a];Array.removeAt(b,a);Sys.Observer._collectionChange(b,new Sys.CollectionChange(Sys.NotifyCollectionChangedAction.remove,null,-1,[c],a))}};Sys.Observer.raiseCollectionChanged=function(b,a){Sys.Observer.raiseEvent(b,"collectionChanged",new Sys.NotifyCollectionChangedEventArgs(a))};Sys.Observer._observeMethods={add_propertyChanged:function(a){Sys.Observer._addEventHandler(this,"propertyChanged",a)},remove_propertyChanged:function(a){Sys.Observer._removeEventHandler(this,"propertyChanged",a)},addEventHandler:function(a,b){Sys.Observer._addEventHandler(this,a,b)},removeEventHandler:function(a,b){Sys.Observer._removeEventHandler(this,a,b)},get_isUpdating:function(){return Sys.Observer.isUpdating(this)},beginUpdate:function(){Sys.Observer.beginUpdate(this)},endUpdate:function(){Sys.Observer.endUpdate(this)},setValue:function(b,a){Sys.Observer._setValue(this,b,a)},raiseEvent:function(b,a){Sys.Observer.raiseEvent(this,b,a)},raisePropertyChanged:function(a){Sys.Observer.raiseEvent(this,"propertyChanged",new Sys.PropertyChangedEventArgs(a))}};Sys.Observer._arrayMethods={add_collectionChanged:function(a){Sys.Observer._addEventHandler(this,"collectionChanged",a)},remove_collectionChanged:function(a){Sys.Observer._removeEventHandler(this,"collectionChanged",a)},add:function(a){Sys.Observer.add(this,a)},addRange:function(a){Sys.Observer.addRange(this,a)},clear:function(){Sys.Observer.clear(this)},insert:function(a,b){Sys.Observer.insert(this,a,b)},remove:function(a){return Sys.Observer.remove(this,a)},removeAt:function(a){Sys.Observer.removeAt(this,a)},raiseCollectionChanged:function(a){Sys.Observer.raiseEvent(this,"collectionChanged",new Sys.NotifyCollectionChangedEventArgs(a))}};Sys.Observer._getContext=function(b,c){var a=b._observerContext;if(a)return a();if(c)return (b._observerContext=Sys.Observer._createContext())();return null};Sys.Observer._createContext=function(){var a={events:new Sys.EventHandlerList};return function(){return a}};Date._appendPreOrPostMatch=function(e,b){var d=0,a=false;for(var c=0,g=e.length;c<g;c++){var f=e.charAt(c);switch(f){case "'":if(a)b.append("'");else d++;a=false;break;case "\\":if(a)b.append("\\");a=!a;break;default:b.append(f);a=false}}return d};Date._expandFormat=function(a,b){if(!b)b="F";var c=b.length;if(c===1)switch(b){case "d":return a.ShortDatePattern;case "D":return a.LongDatePattern;case "t":return a.ShortTimePattern;case "T":return a.LongTimePattern;case "f":return a.LongDatePattern+" "+a.ShortTimePattern;case "F":return a.FullDateTimePattern;case "M":case "m":return a.MonthDayPattern;case "s":return a.SortableDateTimePattern;case "Y":case "y":return a.YearMonthPattern;default:throw Error.format(Sys.Res.formatInvalidString)}else if(c===2&&b.charAt(0)==="%")b=b.charAt(1);return b};Date._expandYear=function(c,a){var d=new Date,e=Date._getEra(d);if(a<100){var b=Date._getEraYear(d,c,e);a+=b-b%100;if(a>c.Calendar.TwoDigitYearMax)a-=100}return a};Date._getEra=function(e,c){if(!c)return 0;var b,d=e.getTime();for(var a=0,f=c.length;a<f;a+=4){b=c[a+2];if(b===null||d>=b)return a}return 0};Date._getEraYear=function(d,b,e,c){var a=d.getFullYear();if(!c&&b.eras)a-=b.eras[e+3];return a};Date._getParseRegExp=function(b,e){if(!b._parseRegExp)b._parseRegExp={};else if(b._parseRegExp[e])return b._parseRegExp[e];var c=Date._expandFormat(b,e);c=c.replace(/([\^\$\.\*\+\?\|\[\]\(\)\{\}])/g,"\\\\$1");var a=new Sys.StringBuilder("^"),j=[],f=0,i=0,h=Date._getTokenRegExp(),d;while((d=h.exec(c))!==null){var l=c.slice(f,d.index);f=h.lastIndex;i+=Date._appendPreOrPostMatch(l,a);if(i%2===1){a.append(d[0]);continue}switch(d[0]){case "dddd":case "ddd":case "MMMM":case "MMM":case "gg":case "g":a.append("(\\D+)");break;case "tt":case "t":a.append("(\\D*)");break;case "yyyy":a.append("(\\d{4})");break;case "fff":a.append("(\\d{3})");break;case "ff":a.append("(\\d{2})");break;case "f":a.append("(\\d)");break;case "dd":case "d":case "MM":case "M":case "yy":case "y":case "HH":case "H":case "hh":case "h":case "mm":case "m":case "ss":case "s":a.append("(\\d\\d?)");break;case "zzz":a.append("([+-]?\\d\\d?:\\d{2})");break;case "zz":case "z":a.append("([+-]?\\d\\d?)");break;case "/":a.append("(\\"+b.DateSeparator+")")}Array.add(j,d[0])}Date._appendPreOrPostMatch(c.slice(f),a);a.append("$");var k=a.toString().replace(/\s+/g,"\\s+"),g={"regExp":k,"groups":j};b._parseRegExp[e]=g;return g};Date._getTokenRegExp=function(){return /\/|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z|gg|g/g};Date.parseLocale=function(a){return Date._parse(a,Sys.CultureInfo.CurrentCulture,arguments)};Date.parseInvariant=function(a){return Date._parse(a,Sys.CultureInfo.InvariantCulture,arguments)};Date._parse=function(h,d,i){var a,c,b,f,e,g=false;for(a=1,c=i.length;a<c;a++){f=i[a];if(f){g=true;b=Date._parseExact(h,f,d);if(b)return b}}if(!g){e=d._getDateTimeFormats();for(a=0,c=e.length;a<c;a++){b=Date._parseExact(h,e[a],d);if(b)return b}}return null};Date._parseExact=function(w,D,k){w=w.trim();var g=k.dateTimeFormat,A=Date._getParseRegExp(g,D),C=(new RegExp(A.regExp)).exec(w);if(C===null)return null;var B=A.groups,x=null,e=null,c=null,j=null,i=null,d=0,h,q=0,r=0,f=0,n=null,v=false;for(var t=0,E=B.length;t<E;t++){var a=C[t+1];if(a)switch(B[t]){case "dd":case "d":j=parseInt(a,10);if(j<1||j>31)return null;break;case "MMMM":c=k._getMonthIndex(a);if(c<0||c>11)return null;break;case "MMM":c=k._getAbbrMonthIndex(a);if(c<0||c>11)return null;break;case "M":case "MM":c=parseInt(a,10)-1;if(c<0||c>11)return null;break;case "y":case "yy":e=Date._expandYear(g,parseInt(a,10));if(e<0||e>9999)return null;break;case "yyyy":e=parseInt(a,10);if(e<0||e>9999)return null;break;case "h":case "hh":d=parseInt(a,10);if(d===12)d=0;if(d<0||d>11)return null;break;case "H":case "HH":d=parseInt(a,10);if(d<0||d>23)return null;break;case "m":case "mm":q=parseInt(a,10);if(q<0||q>59)return null;break;case "s":case "ss":r=parseInt(a,10);if(r<0||r>59)return null;break;case "tt":case "t":var z=a.toUpperCase();v=z===g.PMDesignator.toUpperCase();if(!v&&z!==g.AMDesignator.toUpperCase())return null;break;case "f":f=parseInt(a,10)*100;if(f<0||f>999)return null;break;case "ff":f=parseInt(a,10)*10;if(f<0||f>999)return null;break;case "fff":f=parseInt(a,10);if(f<0||f>999)return null;break;case "dddd":i=k._getDayIndex(a);if(i<0||i>6)return null;break;case "ddd":i=k._getAbbrDayIndex(a);if(i<0||i>6)return null;break;case "zzz":var u=a.split(/:/);if(u.length!==2)return null;h=parseInt(u[0],10);if(h<-12||h>13)return null;var o=parseInt(u[1],10);if(o<0||o>59)return null;n=h*60+(a.startsWith("-")?-o:o);break;case "z":case "zz":h=parseInt(a,10);if(h<-12||h>13)return null;n=h*60;break;case "g":case "gg":var p=a;if(!p||!g.eras)return null;p=p.toLowerCase().trim();for(var s=0,F=g.eras.length;s<F;s+=4)if(p===g.eras[s+1].toLowerCase()){x=s;break}if(x===null)return null}}var b=new Date,l,m=g.Calendar.convert;if(m)l=m.fromGregorian(b);if(!m)l=[b.getFullYear(),b.getMonth(),b.getDate()];if(e===null)e=l[0];else if(g.eras)e+=g.eras[(x||0)+3];if(c===null)c=l[1];if(j===null)j=l[2];if(m){b=m.toGregorian(e,c,j);if(b===null)return null}else{b.setFullYear(e,c,j);if(b.getDate()!==j)return null;if(i!==null&&b.getDay()!==i)return null}if(v&&d<12)d+=12;b.setHours(d,q,r,f);if(n!==null){var y=b.getMinutes()-(n+b.getTimezoneOffset());b.setHours(b.getHours()+parseInt(y/60,10),y%60)}return b};Date.prototype.format=function(a){return this._toFormattedString(a,Sys.CultureInfo.InvariantCulture)};Date.prototype.localeFormat=function(a){return this._toFormattedString(a,Sys.CultureInfo.CurrentCulture)};Date.prototype._toFormattedString=function(e,j){var b=j.dateTimeFormat,n=b.Calendar.convert;if(!e||!e.length||e==="i")if(j&&j.name.length)if(n)return this._toFormattedString(b.FullDateTimePattern,j);else{var r=new Date(this.getTime()),x=Date._getEra(this,b.eras);r.setFullYear(Date._getEraYear(this,b,x));return r.toLocaleString()}else return this.toString();var l=b.eras,k=e==="s";e=Date._expandFormat(b,e);var a=new Sys.StringBuilder,c;function d(a){if(a<10)return "0"+a;return a.toString()}function m(a){if(a<10)return "00"+a;if(a<100)return "0"+a;return a.toString()}function v(a){if(a<10)return "000"+a;else if(a<100)return "00"+a;else if(a<1000)return "0"+a;return a.toString()}var h,p,t=/([^d]|^)(d|dd)([^d]|$)/g;function s(){if(h||p)return h;h=t.test(e);p=true;return h}var q=0,o=Date._getTokenRegExp(),f;if(!k&&n)f=n.fromGregorian(this);for(;true;){var w=o.lastIndex,i=o.exec(e),u=e.slice(w,i?i.index:e.length);q+=Date._appendPreOrPostMatch(u,a);if(!i)break;if(q%2===1){a.append(i[0]);continue}function g(a,b){if(f)return f[b];switch(b){case 0:return a.getFullYear();case 1:return a.getMonth();case 2:return a.getDate()}}switch(i[0]){case "dddd":a.append(b.DayNames[this.getDay()]);break;case "ddd":a.append(b.AbbreviatedDayNames[this.getDay()]);break;case "dd":h=true;a.append(d(g(this,2)));break;case "d":h=true;a.append(g(this,2));break;case "MMMM":a.append(b.MonthGenitiveNames&&s()?b.MonthGenitiveNames[g(this,1)]:b.MonthNames[g(this,1)]);break;case "MMM":a.append(b.AbbreviatedMonthGenitiveNames&&s()?b.AbbreviatedMonthGenitiveNames[g(this,1)]:b.AbbreviatedMonthNames[g(this,1)]);break;case "MM":a.append(d(g(this,1)+1));break;case "M":a.append(g(this,1)+1);break;case "yyyy":a.append(v(f?f[0]:Date._getEraYear(this,b,Date._getEra(this,l),k)));break;case "yy":a.append(d((f?f[0]:Date._getEraYear(this,b,Date._getEra(this,l),k))%100));break;case "y":a.append((f?f[0]:Date._getEraYear(this,b,Date._getEra(this,l),k))%100);break;case "hh":c=this.getHours()%12;if(c===0)c=12;a.append(d(c));break;case "h":c=this.getHours()%12;if(c===0)c=12;a.append(c);break;case "HH":a.append(d(this.getHours()));break;case "H":a.append(this.getHours());break;case "mm":a.append(d(this.getMinutes()));break;case "m":a.append(this.getMinutes());break;case "ss":a.append(d(this.getSeconds()));break;case "s":a.append(this.getSeconds());break;case "tt":a.append(this.getHours()<12?b.AMDesignator:b.PMDesignator);break;case "t":a.append((this.getHours()<12?b.AMDesignator:b.PMDesignator).charAt(0));break;case "f":a.append(m(this.getMilliseconds()).charAt(0));break;case "ff":a.append(m(this.getMilliseconds()).substr(0,2));break;case "fff":a.append(m(this.getMilliseconds()));break;case "z":c=this.getTimezoneOffset()/60;a.append((c<=0?"+":"-")+Math.floor(Math.abs(c)));break;case "zz":c=this.getTimezoneOffset()/60;a.append((c<=0?"+":"-")+d(Math.floor(Math.abs(c))));break;case "zzz":c=this.getTimezoneOffset()/60;a.append((c<=0?"+":"-")+d(Math.floor(Math.abs(c)))+":"+d(Math.abs(this.getTimezoneOffset()%60)));break;case "g":case "gg":if(b.eras)a.append(b.eras[Date._getEra(this,l)+1]);break;case "/":a.append(b.DateSeparator)}}return a.toString()};String.localeFormat=function(){return String._toFormattedString(true,arguments)};Number.parseLocale=function(a){return Number._parse(a,Sys.CultureInfo.CurrentCulture)};Number.parseInvariant=function(a){return Number._parse(a,Sys.CultureInfo.InvariantCulture)};Number._parse=function(b,o){b=b.trim();if(b.match(/^[+-]?infinity$/i))return parseFloat(b);if(b.match(/^0x[a-f0-9]+$/i))return parseInt(b);var a=o.numberFormat,g=Number._parseNumberNegativePattern(b,a,a.NumberNegativePattern),h=g[0],e=g[1];if(h===""&&a.NumberNegativePattern!==1){g=Number._parseNumberNegativePattern(b,a,1);h=g[0];e=g[1]}if(h==="")h="+";var j,d,f=e.indexOf("e");if(f<0)f=e.indexOf("E");if(f<0){d=e;j=null}else{d=e.substr(0,f);j=e.substr(f+1)}var c,k,m=d.indexOf(a.NumberDecimalSeparator);if(m<0){c=d;k=null}else{c=d.substr(0,m);k=d.substr(m+a.NumberDecimalSeparator.length)}c=c.split(a.NumberGroupSeparator).join("");var n=a.NumberGroupSeparator.replace(/\u00A0/g," ");if(a.NumberGroupSeparator!==n)c=c.split(n).join("");var l=h+c;if(k!==null)l+="."+k;if(j!==null){var i=Number._parseNumberNegativePattern(j,a,1);if(i[0]==="")i[0]="+";l+="e"+i[0]+i[1]}if(l.match(/^[+-]?\d*\.?\d*(e[+-]?\d+)?$/))return parseFloat(l);return Number.NaN};Number._parseNumberNegativePattern=function(a,d,e){var b=d.NegativeSign,c=d.PositiveSign;switch(e){case 4:b=" "+b;c=" "+c;case 3:if(a.endsWith(b))return ["-",a.substr(0,a.length-b.length)];else if(a.endsWith(c))return ["+",a.substr(0,a.length-c.length)];break;case 2:b+=" ";c+=" ";case 1:if(a.startsWith(b))return ["-",a.substr(b.length)];else if(a.startsWith(c))return ["+",a.substr(c.length)];break;case 0:if(a.startsWith("(")&&a.endsWith(")"))return ["-",a.substr(1,a.length-2)]}return ["",a]};Number.prototype.format=function(a){return this._toFormattedString(a,Sys.CultureInfo.InvariantCulture)};Number.prototype.localeFormat=function(a){return this._toFormattedString(a,Sys.CultureInfo.CurrentCulture)};Number.prototype._toFormattedString=function(e,j){if(!e||e.length===0||e==="i")if(j&&j.name.length>0)return this.toLocaleString();else return this.toString();var o=["n %","n%","%n"],n=["-n %","-n%","-%n"],p=["(n)","-n","- n","n-","n -"],m=["$n","n$","$ n","n $"],l=["($n)","-$n","$-n","$n-","(n$)","-n$","n-$","n$-","-n $","-$ n","n $-","$ n-","$ -n","n- $","($ n)","(n $)"];function g(a,c,d){for(var b=a.length;b<c;b++)a=d?"0"+a:a+"0";return a}function i(j,i,l,n,p){var h=l[0],k=1,o=Math.pow(10,i),m=Math.round(j*o)/o;if(!isFinite(m))m=j;j=m;var b=j.toString(),a="",c,e=b.split(/e/i);b=e[0];c=e.length>1?parseInt(e[1]):0;e=b.split(".");b=e[0];a=e.length>1?e[1]:"";var q;if(c>0){a=g(a,c,false);b+=a.slice(0,c);a=a.substr(c)}else if(c<0){c=-c;b=g(b,c+1,true);a=b.slice(-c,b.length)+a;b=b.slice(0,-c)}if(i>0){if(a.length>i)a=a.slice(0,i);else a=g(a,i,false);a=p+a}else a="";var d=b.length-1,f="";while(d>=0){if(h===0||h>d)if(f.length>0)return b.slice(0,d+1)+n+f+a;else return b.slice(0,d+1)+a;if(f.length>0)f=b.slice(d-h+1,d+1)+n+f;else f=b.slice(d-h+1,d+1);d-=h;if(k<l.length){h=l[k];k++}}return b.slice(0,d+1)+n+f+a}var a=j.numberFormat,d=Math.abs(this);if(!e)e="D";var b=-1;if(e.length>1)b=parseInt(e.slice(1),10);var c;switch(e.charAt(0)){case "d":case "D":c="n";if(b!==-1)d=g(""+d,b,true);if(this<0)d=-d;break;case "c":case "C":if(this<0)c=l[a.CurrencyNegativePattern];else c=m[a.CurrencyPositivePattern];if(b===-1)b=a.CurrencyDecimalDigits;d=i(Math.abs(this),b,a.CurrencyGroupSizes,a.CurrencyGroupSeparator,a.CurrencyDecimalSeparator);break;case "n":case "N":if(this<0)c=p[a.NumberNegativePattern];else c="n";if(b===-1)b=a.NumberDecimalDigits;d=i(Math.abs(this),b,a.NumberGroupSizes,a.NumberGroupSeparator,a.NumberDecimalSeparator);break;case "p":case "P":if(this<0)c=n[a.PercentNegativePattern];else c=o[a.PercentPositivePattern];if(b===-1)b=a.PercentDecimalDigits;d=i(Math.abs(this)*100,b,a.PercentGroupSizes,a.PercentGroupSeparator,a.PercentDecimalSeparator);break;default:throw Error.format(Sys.Res.formatBadFormatSpecifier)}var k=/n|\$|-|%/g,f="";for(;true;){var q=k.lastIndex,h=k.exec(c);f+=c.slice(q,h?h.index:c.length);if(!h)break;switch(h[0]){case "n":f+=d;break;case "$":f+=a.CurrencySymbol;break;case "-":if(/[1-9]/.test(d))f+=a.NegativeSign;break;case "%":f+=a.PercentSymbol}}return f};Sys.CultureInfo=function(c,b,a){this.name=c;this.numberFormat=b;this.dateTimeFormat=a};Sys.CultureInfo.prototype={_getDateTimeFormats:function(){if(!this._dateTimeFormats){var a=this.dateTimeFormat;this._dateTimeFormats=[a.MonthDayPattern,a.YearMonthPattern,a.ShortDatePattern,a.ShortTimePattern,a.LongDatePattern,a.LongTimePattern,a.FullDateTimePattern,a.RFC1123Pattern,a.SortableDateTimePattern,a.UniversalSortableDateTimePattern]}return this._dateTimeFormats},_getIndex:function(c,d,e){var b=this._toUpper(c),a=Array.indexOf(d,b);if(a===-1)a=Array.indexOf(e,b);return a},_getMonthIndex:function(a){if(!this._upperMonths){this._upperMonths=this._toUpperArray(this.dateTimeFormat.MonthNames);this._upperMonthsGenitive=this._toUpperArray(this.dateTimeFormat.MonthGenitiveNames)}return this._getIndex(a,this._upperMonths,this._upperMonthsGenitive)},_getAbbrMonthIndex:function(a){if(!this._upperAbbrMonths){this._upperAbbrMonths=this._toUpperArray(this.dateTimeFormat.AbbreviatedMonthNames);this._upperAbbrMonthsGenitive=this._toUpperArray(this.dateTimeFormat.AbbreviatedMonthGenitiveNames)}return this._getIndex(a,this._upperAbbrMonths,this._upperAbbrMonthsGenitive)},_getDayIndex:function(a){if(!this._upperDays)this._upperDays=this._toUpperArray(this.dateTimeFormat.DayNames);return Array.indexOf(this._upperDays,this._toUpper(a))},_getAbbrDayIndex:function(a){if(!this._upperAbbrDays)this._upperAbbrDays=this._toUpperArray(this.dateTimeFormat.AbbreviatedDayNames);return Array.indexOf(this._upperAbbrDays,this._toUpper(a))},_toUpperArray:function(c){var b=[];for(var a=0,d=c.length;a<d;a++)b[a]=this._toUpper(c[a]);return b},_toUpper:function(a){return a.split("\u00a0").join(" ").toUpperCase()}};Sys.CultureInfo.registerClass("Sys.CultureInfo");Sys.CultureInfo._parse=function(a){var b=a.dateTimeFormat;if(b&&!b.eras)b.eras=a.eras;return new Sys.CultureInfo(a.name,a.numberFormat,b)};Sys.CultureInfo.InvariantCulture=Sys.CultureInfo._parse({"name":"","numberFormat":{"CurrencyDecimalDigits":2,"CurrencyDecimalSeparator":".","IsReadOnly":true,"CurrencyGroupSizes":[3],"NumberGroupSizes":[3],"PercentGroupSizes":[3],"CurrencyGroupSeparator":",","CurrencySymbol":"\u00a4","NaNSymbol":"NaN","CurrencyNegativePattern":0,"NumberNegativePattern":1,"PercentPositivePattern":0,"PercentNegativePattern":0,"NegativeInfinitySymbol":"-Infinity","NegativeSign":"-","NumberDecimalDigits":2,"NumberDecimalSeparator":".","NumberGroupSeparator":",","CurrencyPositivePattern":0,"PositiveInfinitySymbol":"Infinity","PositiveSign":"+","PercentDecimalDigits":2,"PercentDecimalSeparator":".","PercentGroupSeparator":",","PercentSymbol":"%","PerMilleSymbol":"\u2030","NativeDigits":["0","1","2","3","4","5","6","7","8","9"],"DigitSubstitution":1},"dateTimeFormat":{"AMDesignator":"AM","Calendar":{"MinSupportedDateTime":"@-62135568000000@","MaxSupportedDateTime":"@253402300799999@","AlgorithmType":1,"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2029,"IsReadOnly":true},"DateSeparator":"/","FirstDayOfWeek":0,"CalendarWeekRule":0,"FullDateTimePattern":"dddd, dd MMMM yyyy HH:mm:ss","LongDatePattern":"dddd, dd MMMM yyyy","LongTimePattern":"HH:mm:ss","MonthDayPattern":"MMMM dd","PMDesignator":"PM","RFC1123Pattern":"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'","ShortDatePattern":"MM/dd/yyyy","ShortTimePattern":"HH:mm","SortableDateTimePattern":"yyyy'-'MM'-'dd'T'HH':'mm':'ss","TimeSeparator":":","UniversalSortableDateTimePattern":"yyyy'-'MM'-'dd HH':'mm':'ss'Z'","YearMonthPattern":"yyyy MMMM","AbbreviatedDayNames":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"ShortestDayNames":["Su","Mo","Tu","We","Th","Fr","Sa"],"DayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"AbbreviatedMonthNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"IsReadOnly":true,"NativeCalendarName":"Gregorian Calendar","AbbreviatedMonthGenitiveNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthGenitiveNames":["January","February","March","April","May","June","July","August","September","October","November","December",""]},"eras":[1,"A.D.",null,0]});if(typeof __cultureInfo==="object"){Sys.CultureInfo.CurrentCulture=Sys.CultureInfo._parse(__cultureInfo);delete __cultureInfo}else Sys.CultureInfo.CurrentCulture=Sys.CultureInfo._parse({"name":"en-US","numberFormat":{"CurrencyDecimalDigits":2,"CurrencyDecimalSeparator":".","IsReadOnly":false,"CurrencyGroupSizes":[3],"NumberGroupSizes":[3],"PercentGroupSizes":[3],"CurrencyGroupSeparator":",","CurrencySymbol":"$","NaNSymbol":"NaN","CurrencyNegativePattern":0,"NumberNegativePattern":1,"PercentPositivePattern":0,"PercentNegativePattern":0,"NegativeInfinitySymbol":"-Infinity","NegativeSign":"-","NumberDecimalDigits":2,"NumberDecimalSeparator":".","NumberGroupSeparator":",","CurrencyPositivePattern":0,"PositiveInfinitySymbol":"Infinity","PositiveSign":"+","PercentDecimalDigits":2,"PercentDecimalSeparator":".","PercentGroupSeparator":",","PercentSymbol":"%","PerMilleSymbol":"\u2030","NativeDigits":["0","1","2","3","4","5","6","7","8","9"],"DigitSubstitution":1},"dateTimeFormat":{"AMDesignator":"AM","Calendar":{"MinSupportedDateTime":"@-62135568000000@","MaxSupportedDateTime":"@253402300799999@","AlgorithmType":1,"CalendarType":1,"Eras":[1],"TwoDigitYearMax":2029,"IsReadOnly":false},"DateSeparator":"/","FirstDayOfWeek":0,"CalendarWeekRule":0,"FullDateTimePattern":"dddd, MMMM dd, yyyy h:mm:ss tt","LongDatePattern":"dddd, MMMM dd, yyyy","LongTimePattern":"h:mm:ss tt","MonthDayPattern":"MMMM dd","PMDesignator":"PM","RFC1123Pattern":"ddd, dd MMM yyyy HH':'mm':'ss 'GMT'","ShortDatePattern":"M/d/yyyy","ShortTimePattern":"h:mm tt","SortableDateTimePattern":"yyyy'-'MM'-'dd'T'HH':'mm':'ss","TimeSeparator":":","UniversalSortableDateTimePattern":"yyyy'-'MM'-'dd HH':'mm':'ss'Z'","YearMonthPattern":"MMMM, yyyy","AbbreviatedDayNames":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"ShortestDayNames":["Su","Mo","Tu","We","Th","Fr","Sa"],"DayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"AbbreviatedMonthNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthNames":["January","February","March","April","May","June","July","August","September","October","November","December",""],"IsReadOnly":false,"NativeCalendarName":"Gregorian Calendar","AbbreviatedMonthGenitiveNames":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec",""],"MonthGenitiveNames":["January","February","March","April","May","June","July","August","September","October","November","December",""]},"eras":[1,"A.D.",null,0]});Type.registerNamespace("Sys.Serialization");Sys.Serialization.JavaScriptSerializer=function(){};Sys.Serialization.JavaScriptSerializer.registerClass("Sys.Serialization.JavaScriptSerializer");Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs=[];Sys.Serialization.JavaScriptSerializer._charsToEscape=[];Sys.Serialization.JavaScriptSerializer._dateRegEx=new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)(?:[a-zA-Z]|(?:\\+|-)[0-9]{4})?\\)\\\\/\\"',"g");Sys.Serialization.JavaScriptSerializer._escapeChars={};Sys.Serialization.JavaScriptSerializer._escapeRegEx=new RegExp('["\\\\\\x00-\\x1F]',"i");Sys.Serialization.JavaScriptSerializer._escapeRegExGlobal=new RegExp('["\\\\\\x00-\\x1F]',"g");Sys.Serialization.JavaScriptSerializer._jsonRegEx=new RegExp("[^,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t]","g");Sys.Serialization.JavaScriptSerializer._jsonStringRegEx=new RegExp('"(\\\\.|[^"\\\\])*"',"g");Sys.Serialization.JavaScriptSerializer._serverTypeFieldName="__type";Sys.Serialization.JavaScriptSerializer._init=function(){var c=["\\u0000","\\u0001","\\u0002","\\u0003","\\u0004","\\u0005","\\u0006","\\u0007","\\b","\\t","\\n","\\u000b","\\f","\\r","\\u000e","\\u000f","\\u0010","\\u0011","\\u0012","\\u0013","\\u0014","\\u0015","\\u0016","\\u0017","\\u0018","\\u0019","\\u001a","\\u001b","\\u001c","\\u001d","\\u001e","\\u001f"];Sys.Serialization.JavaScriptSerializer._charsToEscape[0]="\\";Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs["\\"]=new RegExp("\\\\","g");Sys.Serialization.JavaScriptSerializer._escapeChars["\\"]="\\\\";Sys.Serialization.JavaScriptSerializer._charsToEscape[1]='"';Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs['"']=new RegExp('"',"g");Sys.Serialization.JavaScriptSerializer._escapeChars['"']='\\"';for(var a=0;a<32;a++){var b=String.fromCharCode(a);Sys.Serialization.JavaScriptSerializer._charsToEscape[a+2]=b;Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs[b]=new RegExp(b,"g");Sys.Serialization.JavaScriptSerializer._escapeChars[b]=c[a]}};Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder=function(b,a){a.append(b.toString())};Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder=function(a,b){if(isFinite(a))b.append(String(a));else throw Error.invalidOperation(Sys.Res.cannotSerializeNonFiniteNumbers)};Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder=function(a,c){c.append('"');if(Sys.Serialization.JavaScriptSerializer._escapeRegEx.test(a)){if(Sys.Serialization.JavaScriptSerializer._charsToEscape.length===0)Sys.Serialization.JavaScriptSerializer._init();if(a.length<128)a=a.replace(Sys.Serialization.JavaScriptSerializer._escapeRegExGlobal,function(a){return Sys.Serialization.JavaScriptSerializer._escapeChars[a]});else for(var d=0;d<34;d++){var b=Sys.Serialization.JavaScriptSerializer._charsToEscape[d];if(a.indexOf(b)!==-1)if(Sys.Browser.agent===Sys.Browser.Opera||Sys.Browser.agent===Sys.Browser.FireFox)a=a.split(b).join(Sys.Serialization.JavaScriptSerializer._escapeChars[b]);else a=a.replace(Sys.Serialization.JavaScriptSerializer._charsToEscapeRegExs[b],Sys.Serialization.JavaScriptSerializer._escapeChars[b])}}c.append(a);c.append('"')};Sys.Serialization.JavaScriptSerializer._serializeWithBuilder=function(b,a,i,g){var c;switch(typeof b){case "object":if(b)if(Number.isInstanceOfType(b))Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder(b,a);else if(Boolean.isInstanceOfType(b))Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder(b,a);else if(String.isInstanceOfType(b))Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder(b,a);else if(Array.isInstanceOfType(b)){a.append("[");for(c=0;c<b.length;++c){if(c>0)a.append(",");Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(b[c],a,false,g)}a.append("]")}else{if(Date.isInstanceOfType(b)){a.append('"\\/Date(');a.append(b.getTime());a.append(')\\/"');break}var d=[],f=0;for(var e in b){if(e.startsWith("$"))continue;if(e===Sys.Serialization.JavaScriptSerializer._serverTypeFieldName&&f!==0){d[f++]=d[0];d[0]=e}else d[f++]=e}if(i)d.sort();a.append("{");var j=false;for(c=0;c<f;c++){var h=b[d[c]];if(typeof h!=="undefined"&&typeof h!=="function"){if(j)a.append(",");else j=true;Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(d[c],a,i,g);a.append(":");Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(h,a,i,g)}}a.append("}")}else a.append("null");break;case "number":Sys.Serialization.JavaScriptSerializer._serializeNumberWithBuilder(b,a);break;case "string":Sys.Serialization.JavaScriptSerializer._serializeStringWithBuilder(b,a);break;case "boolean":Sys.Serialization.JavaScriptSerializer._serializeBooleanWithBuilder(b,a);break;default:a.append("null")}};Sys.Serialization.JavaScriptSerializer.serialize=function(b){var a=new Sys.StringBuilder;Sys.Serialization.JavaScriptSerializer._serializeWithBuilder(b,a,false);return a.toString()};Sys.Serialization.JavaScriptSerializer.deserialize=function(data,secure){if(data.length===0)throw Error.argument("data",Sys.Res.cannotDeserializeEmptyString);try{var exp=data.replace(Sys.Serialization.JavaScriptSerializer._dateRegEx,"$1new Date($2)");if(secure&&Sys.Serialization.JavaScriptSerializer._jsonRegEx.test(exp.replace(Sys.Serialization.JavaScriptSerializer._jsonStringRegEx,"")))throw null;return eval("("+exp+")")}catch(a){throw Error.argument("data",Sys.Res.cannotDeserializeInvalidJson)}};Type.registerNamespace("Sys.UI");Sys.EventHandlerList=function(){this._list={}};Sys.EventHandlerList.prototype={_addHandler:function(b,a){Array.add(this._getEvent(b,true),a)},addHandler:function(b,a){this._addHandler(b,a)},_removeHandler:function(c,b){var a=this._getEvent(c);if(!a)return;Array.remove(a,b)},removeHandler:function(b,a){this._removeHandler(b,a)},getHandler:function(b){var a=this._getEvent(b);if(!a||a.length===0)return null;a=Array.clone(a);return function(c,d){for(var b=0,e=a.length;b<e;b++)a[b](c,d)}},_getEvent:function(a,b){if(!this._list[a]){if(!b)return null;this._list[a]=[]}return this._list[a]}};Sys.EventHandlerList.registerClass("Sys.EventHandlerList");Sys.CommandEventArgs=function(c,a,b){Sys.CommandEventArgs.initializeBase(this);this._commandName=c;this._commandArgument=a;this._commandSource=b};Sys.CommandEventArgs.prototype={_commandName:null,_commandArgument:null,_commandSource:null,get_commandName:function(){return this._commandName},get_commandArgument:function(){return this._commandArgument},get_commandSource:function(){return this._commandSource}};Sys.CommandEventArgs.registerClass("Sys.CommandEventArgs",Sys.CancelEventArgs);Sys.INotifyPropertyChange=function(){};Sys.INotifyPropertyChange.prototype={};Sys.INotifyPropertyChange.registerInterface("Sys.INotifyPropertyChange");Sys.PropertyChangedEventArgs=function(a){Sys.PropertyChangedEventArgs.initializeBase(this);this._propertyName=a};Sys.PropertyChangedEventArgs.prototype={get_propertyName:function(){return this._propertyName}};Sys.PropertyChangedEventArgs.registerClass("Sys.PropertyChangedEventArgs",Sys.EventArgs);Sys.INotifyDisposing=function(){};Sys.INotifyDisposing.prototype={};Sys.INotifyDisposing.registerInterface("Sys.INotifyDisposing");Sys.Component=function(){if(Sys.Application)Sys.Application.registerDisposableObject(this)};Sys.Component.prototype={_id:null,_initialized:false,_updating:false,get_events:function(){if(!this._events)this._events=new Sys.EventHandlerList;return this._events},get_id:function(){return this._id},set_id:function(a){this._id=a},get_isInitialized:function(){return this._initialized},get_isUpdating:function(){return this._updating},add_disposing:function(a){this.get_events().addHandler("disposing",a)},remove_disposing:function(a){this.get_events().removeHandler("disposing",a)},add_propertyChanged:function(a){this.get_events().addHandler("propertyChanged",a)},remove_propertyChanged:function(a){this.get_events().removeHandler("propertyChanged",a)},beginUpdate:function(){this._updating=true},dispose:function(){if(this._events){var a=this._events.getHandler("disposing");if(a)a(this,Sys.EventArgs.Empty)}delete this._events;Sys.Application.unregisterDisposableObject(this);Sys.Application.removeComponent(this)},endUpdate:function(){this._updating=false;if(!this._initialized)this.initialize();this.updated()},initialize:function(){this._initialized=true},raisePropertyChanged:function(b){if(!this._events)return;var a=this._events.getHandler("propertyChanged");if(a)a(this,new Sys.PropertyChangedEventArgs(b))},updated:function(){}};Sys.Component.registerClass("Sys.Component",null,Sys.IDisposable,Sys.INotifyPropertyChange,Sys.INotifyDisposing);function Sys$Component$_setProperties(a,i){var d,j=Object.getType(a),e=j===Object||j===Sys.UI.DomElement,h=Sys.Component.isInstanceOfType(a)&&!a.get_isUpdating();if(h)a.beginUpdate();for(var c in i){var b=i[c],f=e?null:a["get_"+c];if(e||typeof f!=="function"){var k=a[c];if(!b||typeof b!=="object"||e&&!k)a[c]=b;else Sys$Component$_setProperties(k,b)}else{var l=a["set_"+c];if(typeof l==="function")l.apply(a,[b]);else if(b instanceof Array){d=f.apply(a);for(var g=0,m=d.length,n=b.length;g<n;g++,m++)d[m]=b[g]}else if(typeof b==="object"&&Object.getType(b)===Object){d=f.apply(a);Sys$Component$_setProperties(d,b)}}}if(h)a.endUpdate()}function Sys$Component$_setReferences(c,b){for(var a in b){var e=c["set_"+a],d=$find(b[a]);e.apply(c,[d])}}var $create=Sys.Component.create=function(h,f,d,c,g){var a=g?new h(g):new h,b=Sys.Application,i=b.get_isCreatingComponents();a.beginUpdate();if(f)Sys$Component$_setProperties(a,f);if(d)for(var e in d)a["add_"+e](d[e]);if(a.get_id())b.addComponent(a);if(i){b._createdComponents[b._createdComponents.length]=a;if(c)b._addComponentToSecondPass(a,c);else a.endUpdate()}else{if(c)Sys$Component$_setReferences(a,c);a.endUpdate()}return a};Sys.UI.MouseButton=function(){throw Error.notImplemented()};Sys.UI.MouseButton.prototype={leftButton:0,middleButton:1,rightButton:2};Sys.UI.MouseButton.registerEnum("Sys.UI.MouseButton");Sys.UI.Key=function(){throw Error.notImplemented()};Sys.UI.Key.prototype={backspace:8,tab:9,enter:13,esc:27,space:32,pageUp:33,pageDown:34,end:35,home:36,left:37,up:38,right:39,down:40,del:127};Sys.UI.Key.registerEnum("Sys.UI.Key");Sys.UI.Point=function(a,b){this.x=a;this.y=b};Sys.UI.Point.registerClass("Sys.UI.Point");Sys.UI.Bounds=function(c,d,b,a){this.x=c;this.y=d;this.height=a;this.width=b};Sys.UI.Bounds.registerClass("Sys.UI.Bounds");Sys.UI.DomEvent=function(e){var a=e,b=this.type=a.type.toLowerCase();this.rawEvent=a;this.altKey=a.altKey;if(typeof a.button!=="undefined")this.button=typeof a.which!=="undefined"?a.button:a.button===4?Sys.UI.MouseButton.middleButton:a.button===2?Sys.UI.MouseButton.rightButton:Sys.UI.MouseButton.leftButton;if(b==="keypress")this.charCode=a.charCode||a.keyCode;else if(a.keyCode&&a.keyCode===46)this.keyCode=127;else this.keyCode=a.keyCode;this.clientX=a.clientX;this.clientY=a.clientY;this.ctrlKey=a.ctrlKey;this.target=a.target?a.target:a.srcElement;if(!b.startsWith("key"))if(typeof a.offsetX!=="undefined"&&typeof a.offsetY!=="undefined"){this.offsetX=a.offsetX;this.offsetY=a.offsetY}else if(this.target&&this.target.nodeType!==3&&typeof a.clientX==="number"){var c=Sys.UI.DomElement.getLocation(this.target),d=Sys.UI.DomElement._getWindow(this.target);this.offsetX=(d.pageXOffset||0)+a.clientX-c.x;this.offsetY=(d.pageYOffset||0)+a.clientY-c.y}this.screenX=a.screenX;this.screenY=a.screenY;this.shiftKey=a.shiftKey};Sys.UI.DomEvent.prototype={preventDefault:function(){if(this.rawEvent.preventDefault)this.rawEvent.preventDefault();else if(window.event)this.rawEvent.returnValue=false},stopPropagation:function(){if(this.rawEvent.stopPropagation)this.rawEvent.stopPropagation();else if(window.event)this.rawEvent.cancelBubble=true}};Sys.UI.DomEvent.registerClass("Sys.UI.DomEvent");var $addHandler=Sys.UI.DomEvent.addHandler=function(a,d,e,g){if(!a._events)a._events={};var c=a._events[d];if(!c)a._events[d]=c=[];var b;if(a.addEventListener){b=function(b){return e.call(a,new Sys.UI.DomEvent(b))};a.addEventListener(d,b,false)}else if(a.attachEvent){b=function(){var b={};try{b=Sys.UI.DomElement._getWindow(a).event}catch(c){}return e.call(a,new Sys.UI.DomEvent(b))};a.attachEvent("on"+d,b)}c[c.length]={handler:e,browserHandler:b,autoRemove:g};if(g){var f=a.dispose;if(f!==Sys.UI.DomEvent._disposeHandlers){a.dispose=Sys.UI.DomEvent._disposeHandlers;if(typeof f!=="undefined")a._chainDispose=f}}},$addHandlers=Sys.UI.DomEvent.addHandlers=function(f,d,c,e){for(var b in d){var a=d[b];if(c)a=Function.createDelegate(c,a);$addHandler(f,b,a,e||false)}},$clearHandlers=Sys.UI.DomEvent.clearHandlers=function(a){Sys.UI.DomEvent._clearHandlers(a,false)};Sys.UI.DomEvent._clearHandlers=function(a,g){if(a._events){var e=a._events;for(var b in e){var d=e[b];for(var c=d.length-1;c>=0;c--){var f=d[c];if(!g||f.autoRemove)$removeHandler(a,b,f.handler)}}a._events=null}};Sys.UI.DomEvent._disposeHandlers=function(){Sys.UI.DomEvent._clearHandlers(this,true);var b=this._chainDispose,a=typeof b;if(a!=="undefined"){this.dispose=b;this._chainDispose=null;if(a==="function")this.dispose()}};var $removeHandler=Sys.UI.DomEvent.removeHandler=function(b,a,c){Sys.UI.DomEvent._removeHandler(b,a,c)};Sys.UI.DomEvent._removeHandler=function(a,e,f){var d=null,c=a._events[e];for(var b=0,g=c.length;b<g;b++)if(c[b].handler===f){d=c[b].browserHandler;break}if(a.removeEventListener)a.removeEventListener(e,d,false);else if(a.detachEvent)a.detachEvent("on"+e,d);c.splice(b,1)};Sys.UI.DomElement=function(){};Sys.UI.DomElement.registerClass("Sys.UI.DomElement");Sys.UI.DomElement.addCssClass=function(a,b){if(!Sys.UI.DomElement.containsCssClass(a,b))if(a.className==="")a.className=b;else a.className+=" "+b};Sys.UI.DomElement.containsCssClass=function(b,a){return Array.contains(b.className.split(" "),a)};Sys.UI.DomElement.getBounds=function(a){var b=Sys.UI.DomElement.getLocation(a);return new Sys.UI.Bounds(b.x,b.y,a.offsetWidth||0,a.offsetHeight||0)};var $get=Sys.UI.DomElement.getElementById=function(f,e){if(!e)return document.getElementById(f);if(e.getElementById)return e.getElementById(f);var c=[],d=e.childNodes;for(var b=0;b<d.length;b++){var a=d[b];if(a.nodeType==1)c[c.length]=a}while(c.length){a=c.shift();if(a.id==f)return a;d=a.childNodes;for(b=0;b<d.length;b++){a=d[b];if(a.nodeType==1)c[c.length]=a}}return null};if(document.documentElement.getBoundingClientRect)Sys.UI.DomElement.getLocation=function(b){if(b.self||b.nodeType===9)return new Sys.UI.Point(0,0);var f=b.getBoundingClientRect();if(!f)return new Sys.UI.Point(0,0);var i=b.ownerDocument.documentElement,c=Math.floor(f.left+.5)+i.scrollLeft,d=Math.floor(f.top+.5)+i.scrollTop;if(Sys.Browser.agent===Sys.Browser.InternetExplorer){try{var h=b.ownerDocument.parentWindow.frameElement||null;if(h){var k=h.frameBorder==="0"||h.frameBorder==="no"?2:0;c+=k;d+=k}}catch(l){}if(Sys.Browser.version<=7){var a,j,g,e=document.createElement("div");e.style.cssText="position:absolute !important;left:0px !important;right:0px !important;height:0px !important;width:1px !important;display:hidden !important";try{j=document.body.childNodes[0];document.body.insertBefore(e,j);g=e.getBoundingClientRect();document.body.removeChild(e);a=g.right-g.left}catch(l){}if(a&&a!==1){c=Math.floor(c/a);d=Math.floor(d/a)}}if((document.documentMode||0)<8){c-=2;d-=2}}return new Sys.UI.Point(c,d)};else if(Sys.Browser.agent===Sys.Browser.Safari)Sys.UI.DomElement.getLocation=function(c){if(c.window&&c.window===c||c.nodeType===9)return new Sys.UI.Point(0,0);var d=0,e=0,a,j=null,g=null,b;for(a=c;a;j=a,(g=b,a=a.offsetParent)){b=Sys.UI.DomElement._getCurrentStyle(a);var f=a.tagName?a.tagName.toUpperCase():null;if((a.offsetLeft||a.offsetTop)&&(f!=="BODY"||(!g||g.position!=="absolute"))){d+=a.offsetLeft;e+=a.offsetTop}if(j&&Sys.Browser.version>=3){d+=parseInt(b.borderLeftWidth);e+=parseInt(b.borderTopWidth)}}b=Sys.UI.DomElement._getCurrentStyle(c);var h=b?b.position:null;if(!h||h!=="absolute")for(a=c.parentNode;a;a=a.parentNode){f=a.tagName?a.tagName.toUpperCase():null;if(f!=="BODY"&&f!=="HTML"&&(a.scrollLeft||a.scrollTop)){d-=a.scrollLeft||0;e-=a.scrollTop||0}b=Sys.UI.DomElement._getCurrentStyle(a);var i=b?b.position:null;if(i&&i==="absolute")break}return new Sys.UI.Point(d,e)};else Sys.UI.DomElement.getLocation=function(d){if(d.window&&d.window===d||d.nodeType===9)return new Sys.UI.Point(0,0);var e=0,f=0,a,i=null,g=null,b=null;for(a=d;a;i=a,(g=b,a=a.offsetParent)){var c=a.tagName?a.tagName.toUpperCase():null;b=Sys.UI.DomElement._getCurrentStyle(a);if((a.offsetLeft||a.offsetTop)&&!(c==="BODY"&&(!g||g.position!=="absolute"))){e+=a.offsetLeft;f+=a.offsetTop}if(i!==null&&b){if(c!=="TABLE"&&c!=="TD"&&c!=="HTML"){e+=parseInt(b.borderLeftWidth)||0;f+=parseInt(b.borderTopWidth)||0}if(c==="TABLE"&&(b.position==="relative"||b.position==="absolute")){e+=parseInt(b.marginLeft)||0;f+=parseInt(b.marginTop)||0}}}b=Sys.UI.DomElement._getCurrentStyle(d);var h=b?b.position:null;if(!h||h!=="absolute")for(a=d.parentNode;a;a=a.parentNode){c=a.tagName?a.tagName.toUpperCase():null;if(c!=="BODY"&&c!=="HTML"&&(a.scrollLeft||a.scrollTop)){e-=a.scrollLeft||0;f-=a.scrollTop||0;b=Sys.UI.DomElement._getCurrentStyle(a);if(b){e+=parseInt(b.borderLeftWidth)||0;f+=parseInt(b.borderTopWidth)||0}}}return new Sys.UI.Point(e,f)};Sys.UI.DomElement.isDomElement=function(a){return Sys._isDomElement(a)};Sys.UI.DomElement.removeCssClass=function(d,c){var a=" "+d.className+" ",b=a.indexOf(" "+c+" ");if(b>=0)d.className=(a.substr(0,b)+" "+a.substring(b+c.length+1,a.length)).trim()};Sys.UI.DomElement.resolveElement=function(b,c){var a=b;if(!a)return null;if(typeof a==="string")a=Sys.UI.DomElement.getElementById(a,c);return a};Sys.UI.DomElement.raiseBubbleEvent=function(c,d){var b=c;while(b){var a=b.control;if(a&&a.onBubbleEvent&&a.raiseBubbleEvent){Sys.UI.DomElement._raiseBubbleEventFromControl(a,c,d);return}b=b.parentNode}};Sys.UI.DomElement._raiseBubbleEventFromControl=function(a,b,c){if(!a.onBubbleEvent(b,c))a._raiseBubbleEvent(b,c)};Sys.UI.DomElement.setLocation=function(b,c,d){var a=b.style;a.position="absolute";a.left=c+"px";a.top=d+"px"};Sys.UI.DomElement.toggleCssClass=function(b,a){if(Sys.UI.DomElement.containsCssClass(b,a))Sys.UI.DomElement.removeCssClass(b,a);else Sys.UI.DomElement.addCssClass(b,a)};Sys.UI.DomElement.getVisibilityMode=function(a){return a._visibilityMode===Sys.UI.VisibilityMode.hide?Sys.UI.VisibilityMode.hide:Sys.UI.VisibilityMode.collapse};Sys.UI.DomElement.setVisibilityMode=function(a,b){Sys.UI.DomElement._ensureOldDisplayMode(a);if(a._visibilityMode!==b){a._visibilityMode=b;if(Sys.UI.DomElement.getVisible(a)===false)if(a._visibilityMode===Sys.UI.VisibilityMode.hide)a.style.display=a._oldDisplayMode;else a.style.display="none";a._visibilityMode=b}};Sys.UI.DomElement.getVisible=function(b){var a=b.currentStyle||Sys.UI.DomElement._getCurrentStyle(b);if(!a)return true;return a.visibility!=="hidden"&&a.display!=="none"};Sys.UI.DomElement.setVisible=function(a,b){if(b!==Sys.UI.DomElement.getVisible(a)){Sys.UI.DomElement._ensureOldDisplayMode(a);a.style.visibility=b?"visible":"hidden";if(b||a._visibilityMode===Sys.UI.VisibilityMode.hide)a.style.display=a._oldDisplayMode;else a.style.display="none"}};Sys.UI.DomElement._ensureOldDisplayMode=function(a){if(!a._oldDisplayMode){var b=a.currentStyle||Sys.UI.DomElement._getCurrentStyle(a);a._oldDisplayMode=b?b.display:null;if(!a._oldDisplayMode||a._oldDisplayMode==="none")switch(a.tagName.toUpperCase()){case "DIV":case "P":case "ADDRESS":case "BLOCKQUOTE":case "BODY":case "COL":case "COLGROUP":case "DD":case "DL":case "DT":case "FIELDSET":case "FORM":case "H1":case "H2":case "H3":case "H4":case "H5":case "H6":case "HR":case "IFRAME":case "LEGEND":case "OL":case "PRE":case "TABLE":case "TD":case "TH":case "TR":case "UL":a._oldDisplayMode="block";break;case "LI":a._oldDisplayMode="list-item";break;default:a._oldDisplayMode="inline"}}};Sys.UI.DomElement._getWindow=function(a){var b=a.ownerDocument||a.document||a;return b.defaultView||b.parentWindow};Sys.UI.DomElement._getCurrentStyle=function(a){if(a.nodeType===3)return null;var c=Sys.UI.DomElement._getWindow(a);if(a.documentElement)a=a.documentElement;var b=c&&a!==c&&c.getComputedStyle?c.getComputedStyle(a,null):a.currentStyle||a.style;if(!b&&Sys.Browser.agent===Sys.Browser.Safari&&a.style){var g=a.style.display,f=a.style.position;a.style.position="absolute";a.style.display="block";var e=c.getComputedStyle(a,null);a.style.display=g;a.style.position=f;b={};for(var d in e)b[d]=e[d];b.display="none"}return b};Sys.IContainer=function(){};Sys.IContainer.prototype={};Sys.IContainer.registerInterface("Sys.IContainer");Sys.ApplicationLoadEventArgs=function(b,a){Sys.ApplicationLoadEventArgs.initializeBase(this);this._components=b;this._isPartialLoad=a};Sys.ApplicationLoadEventArgs.prototype={get_components:function(){return this._components},get_isPartialLoad:function(){return this._isPartialLoad}};Sys.ApplicationLoadEventArgs.registerClass("Sys.ApplicationLoadEventArgs",Sys.EventArgs);Sys._Application=function(){Sys._Application.initializeBase(this);this._disposableObjects=[];this._components={};this._createdComponents=[];this._secondPassComponents=[];this._unloadHandlerDelegate=Function.createDelegate(this,this._unloadHandler);Sys.UI.DomEvent.addHandler(window,"unload",this._unloadHandlerDelegate);this._domReady()};Sys._Application.prototype={_creatingComponents:false,_disposing:false,_deleteCount:0,get_isCreatingComponents:function(){return this._creatingComponents},get_isDisposing:function(){return this._disposing},add_init:function(a){if(this._initialized)a(this,Sys.EventArgs.Empty);else this.get_events().addHandler("init",a)},remove_init:function(a){this.get_events().removeHandler("init",a)},add_load:function(a){this.get_events().addHandler("load",a)},remove_load:function(a){this.get_events().removeHandler("load",a)},add_unload:function(a){this.get_events().addHandler("unload",a)},remove_unload:function(a){this.get_events().removeHandler("unload",a)},addComponent:function(a){this._components[a.get_id()]=a},beginCreateComponents:function(){this._creatingComponents=true},dispose:function(){if(!this._disposing){this._disposing=true;if(this._timerCookie){window.clearTimeout(this._timerCookie);delete this._timerCookie}if(this._endRequestHandler){Sys.WebForms.PageRequestManager.getInstance().remove_endRequest(this._endRequestHandler);delete this._endRequestHandler}if(this._beginRequestHandler){Sys.WebForms.PageRequestManager.getInstance().remove_beginRequest(this._beginRequestHandler);delete this._beginRequestHandler}if(window.pageUnload)window.pageUnload(this,Sys.EventArgs.Empty);var c=this.get_events().getHandler("unload");if(c)c(this,Sys.EventArgs.Empty);var b=Array.clone(this._disposableObjects);for(var a=0,f=b.length;a<f;a++){var d=b[a];if(typeof d!=="undefined")d.dispose()}Array.clear(this._disposableObjects);Sys.UI.DomEvent.removeHandler(window,"unload",this._unloadHandlerDelegate);if(Sys._ScriptLoader){var e=Sys._ScriptLoader.getInstance();if(e)e.dispose()}Sys._Application.callBaseMethod(this,"dispose")}},disposeElement:function(a,d){if(a.nodeType===1){var c=a.getElementsByTagName("*");for(var b=c.length-1;b>=0;b--)this._disposeElementInternal(c[b]);if(!d)this._disposeElementInternal(a)}},endCreateComponents:function(){var b=this._secondPassComponents;for(var a=0,d=b.length;a<d;a++){var c=b[a].component;Sys$Component$_setReferences(c,b[a].references);c.endUpdate()}this._secondPassComponents=[];this._creatingComponents=false},findComponent:function(b,a){return a?Sys.IContainer.isInstanceOfType(a)?a.findComponent(b):a[b]||null:Sys.Application._components[b]||null},getComponents:function(){var a=[],b=this._components;for(var c in b)a[a.length]=b[c];return a},initialize:function(){if(!this.get_isInitialized()&&!this._disposing){Sys._Application.callBaseMethod(this,"initialize");this._raiseInit();if(this.get_stateString){if(Sys.WebForms&&Sys.WebForms.PageRequestManager){this._beginRequestHandler=Function.createDelegate(this,this._onPageRequestManagerBeginRequest);Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(this._beginRequestHandler);this._endRequestHandler=Function.createDelegate(this,this._onPageRequestManagerEndRequest);Sys.WebForms.PageRequestManager.getInstance().add_endRequest(this._endRequestHandler)}var a=this.get_stateString();if(a!==this._currentEntry)this._navigate(a);else this._ensureHistory()}this.raiseLoad()}},notifyScriptLoaded:function(){},registerDisposableObject:function(b){if(!this._disposing){var a=this._disposableObjects,c=a.length;a[c]=b;b.__msdisposeindex=c}},raiseLoad:function(){var b=this.get_events().getHandler("load"),a=new Sys.ApplicationLoadEventArgs(Array.clone(this._createdComponents),!!this._loaded);this._loaded=true;if(b)b(this,a);if(window.pageLoad)window.pageLoad(this,a);this._createdComponents=[]},removeComponent:function(b){var a=b.get_id();if(a)delete this._components[a]},unregisterDisposableObject:function(a){if(!this._disposing){var e=a.__msdisposeindex;if(typeof e==="number"){var b=this._disposableObjects;delete b[e];delete a.__msdisposeindex;if(++this._deleteCount>1000){var c=[];for(var d=0,f=b.length;d<f;d++){a=b[d];if(typeof a!=="undefined"){a.__msdisposeindex=c.length;c.push(a)}}this._disposableObjects=c;this._deleteCount=0}}}},_addComponentToSecondPass:function(b,a){this._secondPassComponents[this._secondPassComponents.length]={component:b,references:a}},_disposeComponents:function(a){if(a)for(var b=a.length-1;b>=0;b--){var c=a[b];if(typeof c.dispose==="function")c.dispose()}},_disposeElementInternal:function(a){var d=a.dispose;if(d&&typeof d==="function")a.dispose();else{var c=a.control;if(c&&typeof c.dispose==="function")c.dispose()}var b=a._behaviors;if(b)this._disposeComponents(b);b=a._components;if(b){this._disposeComponents(b);a._components=null}},_domReady:function(){var a,g,f=this;function b(){f.initialize()}var c=function(){Sys.UI.DomEvent.removeHandler(window,"load",c);b()};Sys.UI.DomEvent.addHandler(window,"load",c);if(document.addEventListener)try{document.addEventListener("DOMContentLoaded",a=function(){document.removeEventListener("DOMContentLoaded",a,false);b()},false)}catch(h){}else if(document.attachEvent)if(window==window.top&&document.documentElement.doScroll){var e,d=document.createElement("div");a=function(){try{d.doScroll("left")}catch(c){e=window.setTimeout(a,0);return}d=null;b()};a()}else document.attachEvent("onreadystatechange",a=function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",a);b()}})},_raiseInit:function(){var a=this.get_events().getHandler("init");if(a){this.beginCreateComponents();a(this,Sys.EventArgs.Empty);this.endCreateComponents()}},_unloadHandler:function(){this.dispose()}};Sys._Application.registerClass("Sys._Application",Sys.Component,Sys.IContainer);Sys.Application=new Sys._Application;var $find=Sys.Application.findComponent;Sys.UI.Behavior=function(b){Sys.UI.Behavior.initializeBase(this);this._element=b;var a=b._behaviors;if(!a)b._behaviors=[this];else a[a.length]=this};Sys.UI.Behavior.prototype={_name:null,get_element:function(){return this._element},get_id:function(){var a=Sys.UI.Behavior.callBaseMethod(this,"get_id");if(a)return a;if(!this._element||!this._element.id)return "";return this._element.id+"$"+this.get_name()},get_name:function(){if(this._name)return this._name;var a=Object.getTypeName(this),b=a.lastIndexOf(".");if(b!==-1)a=a.substr(b+1);if(!this.get_isInitialized())this._name=a;return a},set_name:function(a){this._name=a},initialize:function(){Sys.UI.Behavior.callBaseMethod(this,"initialize");var a=this.get_name();if(a)this._element[a]=this},dispose:function(){Sys.UI.Behavior.callBaseMethod(this,"dispose");var a=this._element;if(a){var c=this.get_name();if(c)a[c]=null;var b=a._behaviors;Array.remove(b,this);if(b.length===0)a._behaviors=null;delete this._element}}};Sys.UI.Behavior.registerClass("Sys.UI.Behavior",Sys.Component);Sys.UI.Behavior.getBehaviorByName=function(b,c){var a=b[c];return a&&Sys.UI.Behavior.isInstanceOfType(a)?a:null};Sys.UI.Behavior.getBehaviors=function(a){if(!a._behaviors)return [];return Array.clone(a._behaviors)};Sys.UI.Behavior.getBehaviorsByType=function(d,e){var a=d._behaviors,c=[];if(a)for(var b=0,f=a.length;b<f;b++)if(e.isInstanceOfType(a[b]))c[c.length]=a[b];return c};Sys.UI.VisibilityMode=function(){throw Error.notImplemented()};Sys.UI.VisibilityMode.prototype={hide:0,collapse:1};Sys.UI.VisibilityMode.registerEnum("Sys.UI.VisibilityMode");Sys.UI.Control=function(a){Sys.UI.Control.initializeBase(this);this._element=a;a.control=this;var b=this.get_role();if(b)a.setAttribute("role",b)};Sys.UI.Control.prototype={_parent:null,_visibilityMode:Sys.UI.VisibilityMode.hide,get_element:function(){return this._element},get_id:function(){if(!this._element)return "";return this._element.id},set_id:function(){throw Error.invalidOperation(Sys.Res.cantSetId)},get_parent:function(){if(this._parent)return this._parent;if(!this._element)return null;var a=this._element.parentNode;while(a){if(a.control)return a.control;a=a.parentNode}return null},set_parent:function(a){this._parent=a},get_role:function(){return null},get_visibilityMode:function(){return Sys.UI.DomElement.getVisibilityMode(this._element)},set_visibilityMode:function(a){Sys.UI.DomElement.setVisibilityMode(this._element,a)},get_visible:function(){return Sys.UI.DomElement.getVisible(this._element)},set_visible:function(a){Sys.UI.DomElement.setVisible(this._element,a)},addCssClass:function(a){Sys.UI.DomElement.addCssClass(this._element,a)},dispose:function(){Sys.UI.Control.callBaseMethod(this,"dispose");if(this._element){this._element.control=null;delete this._element}if(this._parent)delete this._parent},onBubbleEvent:function(){return false},raiseBubbleEvent:function(a,b){this._raiseBubbleEvent(a,b)},_raiseBubbleEvent:function(b,c){var a=this.get_parent();while(a){if(a.onBubbleEvent(b,c))return;a=a.get_parent()}},removeCssClass:function(a){Sys.UI.DomElement.removeCssClass(this._element,a)},toggleCssClass:function(a){Sys.UI.DomElement.toggleCssClass(this._element,a)}};Sys.UI.Control.registerClass("Sys.UI.Control",Sys.Component);Sys.HistoryEventArgs=function(a){Sys.HistoryEventArgs.initializeBase(this);this._state=a};Sys.HistoryEventArgs.prototype={get_state:function(){return this._state}};Sys.HistoryEventArgs.registerClass("Sys.HistoryEventArgs",Sys.EventArgs);Sys.Application._appLoadHandler=null;Sys.Application._beginRequestHandler=null;Sys.Application._clientId=null;Sys.Application._currentEntry="";Sys.Application._endRequestHandler=null;Sys.Application._history=null;Sys.Application._enableHistory=false;Sys.Application._historyFrame=null;Sys.Application._historyInitialized=false;Sys.Application._historyPointIsNew=false;Sys.Application._ignoreTimer=false;Sys.Application._initialState=null;Sys.Application._state={};Sys.Application._timerCookie=0;Sys.Application._timerHandler=null;Sys.Application._uniqueId=null;Sys._Application.prototype.get_stateString=function(){var a=null;if(Sys.Browser.agent===Sys.Browser.Firefox){var c=window.location.href,b=c.indexOf("#");if(b!==-1)a=c.substring(b+1);else a="";return a}else a=window.location.hash;if(a.length>0&&a.charAt(0)==="#")a=a.substring(1);return a};Sys._Application.prototype.get_enableHistory=function(){return this._enableHistory};Sys._Application.prototype.set_enableHistory=function(a){this._enableHistory=a};Sys._Application.prototype.add_navigate=function(a){this.get_events().addHandler("navigate",a)};Sys._Application.prototype.remove_navigate=function(a){this.get_events().removeHandler("navigate",a)};Sys._Application.prototype.addHistoryPoint=function(c,f){this._ensureHistory();var b=this._state;for(var a in c){var d=c[a];if(d===null){if(typeof b[a]!=="undefined")delete b[a]}else b[a]=d}var e=this._serializeState(b);this._historyPointIsNew=true;this._setState(e,f);this._raiseNavigate()};Sys._Application.prototype.setServerId=function(a,b){this._clientId=a;this._uniqueId=b};Sys._Application.prototype.setServerState=function(a){this._ensureHistory();this._state.__s=a;this._updateHiddenField(a)};Sys._Application.prototype._deserializeState=function(a){var e={};a=a||"";var b=a.indexOf("&&");if(b!==-1&&b+2<a.length){e.__s=a.substr(b+2);a=a.substr(0,b)}var g=a.split("&");for(var f=0,j=g.length;f<j;f++){var d=g[f],c=d.indexOf("=");if(c!==-1&&c+1<d.length){var i=d.substr(0,c),h=d.substr(c+1);e[i]=decodeURIComponent(h)}}return e};Sys._Application.prototype._enableHistoryInScriptManager=function(){this._enableHistory=true};Sys._Application.prototype._ensureHistory=function(){if(!this._historyInitialized&&this._enableHistory){if(Sys.Browser.agent===Sys.Browser.InternetExplorer&&Sys.Browser.documentMode<8){this._historyFrame=document.getElementById("__historyFrame");this._ignoreIFrame=true}this._timerHandler=Function.createDelegate(this,this._onIdle);this._timerCookie=window.setTimeout(this._timerHandler,100);try{this._initialState=this._deserializeState(this.get_stateString())}catch(a){}this._historyInitialized=true}};Sys._Application.prototype._navigate=function(c){this._ensureHistory();var b=this._deserializeState(c);if(this._uniqueId){var d=this._state.__s||"",a=b.__s||"";if(a!==d){this._updateHiddenField(a);__doPostBack(this._uniqueId,a);this._state=b;return}}this._setState(c);this._state=b;this._raiseNavigate()};Sys._Application.prototype._onIdle=function(){delete this._timerCookie;var a=this.get_stateString();if(a!==this._currentEntry){if(!this._ignoreTimer){this._historyPointIsNew=false;this._navigate(a)}}else this._ignoreTimer=false;this._timerCookie=window.setTimeout(this._timerHandler,100)};Sys._Application.prototype._onIFrameLoad=function(a){this._ensureHistory();if(!this._ignoreIFrame){this._historyPointIsNew=false;this._navigate(a)}this._ignoreIFrame=false};Sys._Application.prototype._onPageRequestManagerBeginRequest=function(){this._ignoreTimer=true};Sys._Application.prototype._onPageRequestManagerEndRequest=function(e,d){var b=d.get_dataItems()[this._clientId],a=document.getElementById("__EVENTTARGET");if(a&&a.value===this._uniqueId)a.value="";if(typeof b!=="undefined"){this.setServerState(b);this._historyPointIsNew=true}else this._ignoreTimer=false;var c=this._serializeState(this._state);if(c!==this._currentEntry){this._ignoreTimer=true;this._setState(c);this._raiseNavigate()}};Sys._Application.prototype._raiseNavigate=function(){var c=this.get_events().getHandler("navigate"),b={};for(var a in this._state)if(a!=="__s")b[a]=this._state[a];var d=new Sys.HistoryEventArgs(b);if(c)c(this,d);var e;try{if(Sys.Browser.agent===Sys.Browser.Firefox&&window.location.hash&&(!window.frameElement||window.top.location.hash))window.history.go(0)}catch(f){}};Sys._Application.prototype._serializeState=function(d){var b=[];for(var a in d){var e=d[a];if(a==="__s")var c=e;else b[b.length]=a+"="+encodeURIComponent(e)}return b.join("&")+(c?"&&"+c:"")};Sys._Application.prototype._setState=function(a,b){if(this._enableHistory){a=a||"";if(a!==this._currentEntry){if(window.theForm){var d=window.theForm.action,e=d.indexOf("#");window.theForm.action=(e!==-1?d.substring(0,e):d)+"#"+a}if(this._historyFrame&&this._historyPointIsNew){this._ignoreIFrame=true;var c=this._historyFrame.contentWindow.document;c.open("javascript:'<html></html>'");c.write("<html><head><title>"+(b||document.title)+"</title><scri"+'pt type="text/javascript">parent.Sys.Application._onIFrameLoad('+Sys.Serialization.JavaScriptSerializer.serialize(a)+");</scri"+"pt></head><body></body></html>");c.close()}this._ignoreTimer=false;this._currentEntry=a;if(this._historyFrame||this._historyPointIsNew){var f=this.get_stateString();if(a!==f){window.location.hash=a;this._currentEntry=this.get_stateString();if(typeof b!=="undefined"&&b!==null)document.title=b}}this._historyPointIsNew=false}}};Sys._Application.prototype._updateHiddenField=function(b){if(this._clientId){var a=document.getElementById(this._clientId);if(a)a.value=b}};if(!window.XMLHttpRequest)window.XMLHttpRequest=function(){var b=["Msxml2.XMLHTTP.3.0","Msxml2.XMLHTTP"];for(var a=0,c=b.length;a<c;a++)try{return new ActiveXObject(b[a])}catch(d){}return null};Type.registerNamespace("Sys.Net");Sys.Net.WebRequestExecutor=function(){this._webRequest=null;this._resultObject=null};Sys.Net.WebRequestExecutor.prototype={get_webRequest:function(){return this._webRequest},_set_webRequest:function(a){this._webRequest=a},get_started:function(){throw Error.notImplemented()},get_responseAvailable:function(){throw Error.notImplemented()},get_timedOut:function(){throw Error.notImplemented()},get_aborted:function(){throw Error.notImplemented()},get_responseData:function(){throw Error.notImplemented()},get_statusCode:function(){throw Error.notImplemented()},get_statusText:function(){throw Error.notImplemented()},get_xml:function(){throw Error.notImplemented()},get_object:function(){if(!this._resultObject)this._resultObject=Sys.Serialization.JavaScriptSerializer.deserialize(this.get_responseData());return this._resultObject},executeRequest:function(){throw Error.notImplemented()},abort:function(){throw Error.notImplemented()},getResponseHeader:function(){throw Error.notImplemented()},getAllResponseHeaders:function(){throw Error.notImplemented()}};Sys.Net.WebRequestExecutor.registerClass("Sys.Net.WebRequestExecutor");Sys.Net.XMLDOM=function(d){if(!window.DOMParser){var c=["Msxml2.DOMDocument.3.0","Msxml2.DOMDocument"];for(var b=0,f=c.length;b<f;b++)try{var a=new ActiveXObject(c[b]);a.async=false;a.loadXML(d);a.setProperty("SelectionLanguage","XPath");return a}catch(g){}}else try{var e=new window.DOMParser;return e.parseFromString(d,"text/xml")}catch(g){}return null};Sys.Net.XMLHttpExecutor=function(){Sys.Net.XMLHttpExecutor.initializeBase(this);var a=this;this._xmlHttpRequest=null;this._webRequest=null;this._responseAvailable=false;this._timedOut=false;this._timer=null;this._aborted=false;this._started=false;this._onReadyStateChange=function(){if(a._xmlHttpRequest.readyState===4){try{if(typeof a._xmlHttpRequest.status==="undefined")return}catch(b){return}a._clearTimer();a._responseAvailable=true;try{a._webRequest.completed(Sys.EventArgs.Empty)}finally{if(a._xmlHttpRequest!=null){a._xmlHttpRequest.onreadystatechange=Function.emptyMethod;a._xmlHttpRequest=null}}}};this._clearTimer=function(){if(a._timer!=null){window.clearTimeout(a._timer);a._timer=null}};this._onTimeout=function(){if(!a._responseAvailable){a._clearTimer();a._timedOut=true;a._xmlHttpRequest.onreadystatechange=Function.emptyMethod;a._xmlHttpRequest.abort();a._webRequest.completed(Sys.EventArgs.Empty);a._xmlHttpRequest=null}}};Sys.Net.XMLHttpExecutor.prototype={get_timedOut:function(){return this._timedOut},get_started:function(){return this._started},get_responseAvailable:function(){return this._responseAvailable},get_aborted:function(){return this._aborted},executeRequest:function(){this._webRequest=this.get_webRequest();var c=this._webRequest.get_body(),a=this._webRequest.get_headers();this._xmlHttpRequest=new XMLHttpRequest;this._xmlHttpRequest.onreadystatechange=this._onReadyStateChange;var e=this._webRequest.get_httpVerb();this._xmlHttpRequest.open(e,this._webRequest.getResolvedUrl(),true);this._xmlHttpRequest.setRequestHeader("X-Requested-With","XMLHttpRequest");if(a)for(var b in a){var f=a[b];if(typeof f!=="function")this._xmlHttpRequest.setRequestHeader(b,f)}if(e.toLowerCase()==="post"){if(a===null||!a["Content-Type"])this._xmlHttpRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=utf-8");if(!c)c=""}var d=this._webRequest.get_timeout();if(d>0)this._timer=window.setTimeout(Function.createDelegate(this,this._onTimeout),d);this._xmlHttpRequest.send(c);this._started=true},getResponseHeader:function(b){var a;try{a=this._xmlHttpRequest.getResponseHeader(b)}catch(c){}if(!a)a="";return a},getAllResponseHeaders:function(){return this._xmlHttpRequest.getAllResponseHeaders()},get_responseData:function(){return this._xmlHttpRequest.responseText},get_statusCode:function(){var a=0;try{a=this._xmlHttpRequest.status}catch(b){}return a},get_statusText:function(){return this._xmlHttpRequest.statusText},get_xml:function(){var a=this._xmlHttpRequest.responseXML;if(!a||!a.documentElement){a=Sys.Net.XMLDOM(this._xmlHttpRequest.responseText);if(!a||!a.documentElement)return null}else if(navigator.userAgent.indexOf("MSIE")!==-1)a.setProperty("SelectionLanguage","XPath");if(a.documentElement.namespaceURI==="http://www.mozilla.org/newlayout/xml/parsererror.xml"&&a.documentElement.tagName==="parsererror")return null;if(a.documentElement.firstChild&&a.documentElement.firstChild.tagName==="parsererror")return null;return a},abort:function(){if(this._aborted||this._responseAvailable||this._timedOut)return;this._aborted=true;this._clearTimer();if(this._xmlHttpRequest&&!this._responseAvailable){this._xmlHttpRequest.onreadystatechange=Function.emptyMethod;this._xmlHttpRequest.abort();this._xmlHttpRequest=null;this._webRequest.completed(Sys.EventArgs.Empty)}}};Sys.Net.XMLHttpExecutor.registerClass("Sys.Net.XMLHttpExecutor",Sys.Net.WebRequestExecutor);Sys.Net._WebRequestManager=function(){this._defaultTimeout=0;this._defaultExecutorType="Sys.Net.XMLHttpExecutor"};Sys.Net._WebRequestManager.prototype={add_invokingRequest:function(a){this._get_eventHandlerList().addHandler("invokingRequest",a)},remove_invokingRequest:function(a){this._get_eventHandlerList().removeHandler("invokingRequest",a)},add_completedRequest:function(a){this._get_eventHandlerList().addHandler("completedRequest",a)},remove_completedRequest:function(a){this._get_eventHandlerList().removeHandler("completedRequest",a)},_get_eventHandlerList:function(){if(!this._events)this._events=new Sys.EventHandlerList;return this._events},get_defaultTimeout:function(){return this._defaultTimeout},set_defaultTimeout:function(a){this._defaultTimeout=a},get_defaultExecutorType:function(){return this._defaultExecutorType},set_defaultExecutorType:function(a){this._defaultExecutorType=a},executeRequest:function(webRequest){var executor=webRequest.get_executor();if(!executor){var failed=false;try{var executorType=eval(this._defaultExecutorType);executor=new executorType}catch(a){failed=true}webRequest.set_executor(executor)}if(executor.get_aborted())return;var evArgs=new Sys.Net.NetworkRequestEventArgs(webRequest),handler=this._get_eventHandlerList().getHandler("invokingRequest");if(handler)handler(this,evArgs);if(!evArgs.get_cancel())executor.executeRequest()}};Sys.Net._WebRequestManager.registerClass("Sys.Net._WebRequestManager");Sys.Net.WebRequestManager=new Sys.Net._WebRequestManager;Sys.Net.NetworkRequestEventArgs=function(a){Sys.Net.NetworkRequestEventArgs.initializeBase(this);this._webRequest=a};Sys.Net.NetworkRequestEventArgs.prototype={get_webRequest:function(){return this._webRequest}};Sys.Net.NetworkRequestEventArgs.registerClass("Sys.Net.NetworkRequestEventArgs",Sys.CancelEventArgs);Sys.Net.WebRequest=function(){this._url="";this._headers={};this._body=null;this._userContext=null;this._httpVerb=null;this._executor=null;this._invokeCalled=false;this._timeout=0};Sys.Net.WebRequest.prototype={add_completed:function(a){this._get_eventHandlerList().addHandler("completed",a)},remove_completed:function(a){this._get_eventHandlerList().removeHandler("completed",a)},completed:function(b){var a=Sys.Net.WebRequestManager._get_eventHandlerList().getHandler("completedRequest");if(a)a(this._executor,b);a=this._get_eventHandlerList().getHandler("completed");if(a)a(this._executor,b)},_get_eventHandlerList:function(){if(!this._events)this._events=new Sys.EventHandlerList;return this._events},get_url:function(){return this._url},set_url:function(a){this._url=a},get_headers:function(){return this._headers},get_httpVerb:function(){if(this._httpVerb===null){if(this._body===null)return "GET";return "POST"}return this._httpVerb},set_httpVerb:function(a){this._httpVerb=a},get_body:function(){return this._body},set_body:function(a){this._body=a},get_userContext:function(){return this._userContext},set_userContext:function(a){this._userContext=a},get_executor:function(){return this._executor},set_executor:function(a){this._executor=a;this._executor._set_webRequest(this)},get_timeout:function(){if(this._timeout===0)return Sys.Net.WebRequestManager.get_defaultTimeout();return this._timeout},set_timeout:function(a){this._timeout=a},getResolvedUrl:function(){return Sys.Net.WebRequest._resolveUrl(this._url)},invoke:function(){Sys.Net.WebRequestManager.executeRequest(this);this._invokeCalled=true}};Sys.Net.WebRequest._resolveUrl=function(b,a){if(b&&b.indexOf("://")!==-1)return b;if(!a||a.length===0){var d=document.getElementsByTagName("base")[0];if(d&&d.href&&d.href.length>0)a=d.href;else a=document.URL}var c=a.indexOf("?");if(c!==-1)a=a.substr(0,c);c=a.indexOf("#");if(c!==-1)a=a.substr(0,c);a=a.substr(0,a.lastIndexOf("/")+1);if(!b||b.length===0)return a;if(b.charAt(0)==="/"){var e=a.indexOf("://"),g=a.indexOf("/",e+3);return a.substr(0,g)+b}else{var f=a.lastIndexOf("/");return a.substr(0,f+1)+b}};Sys.Net.WebRequest._createQueryString=function(c,b,f){b=b||encodeURIComponent;var h=0,e,g,d,a=new Sys.StringBuilder;if(c)for(d in c){e=c[d];if(typeof e==="function")continue;g=Sys.Serialization.JavaScriptSerializer.serialize(e);if(h++)a.append("&");a.append(d);a.append("=");a.append(b(g))}if(f){if(h)a.append("&");a.append(f)}return a.toString()};Sys.Net.WebRequest._createUrl=function(a,b,c){if(!b&&!c)return a;var d=Sys.Net.WebRequest._createQueryString(b,null,c);return d.length?a+(a&&a.indexOf("?")>=0?"&":"?")+d:a};Sys.Net.WebRequest.registerClass("Sys.Net.WebRequest");Sys._ScriptLoaderTask=function(b,a){this._scriptElement=b;this._completedCallback=a};Sys._ScriptLoaderTask.prototype={get_scriptElement:function(){return this._scriptElement},dispose:function(){if(this._disposed)return;this._disposed=true;this._removeScriptElementHandlers();Sys._ScriptLoaderTask._clearScript(this._scriptElement);this._scriptElement=null},execute:function(){this._addScriptElementHandlers();document.getElementsByTagName("head")[0].appendChild(this._scriptElement)},_addScriptElementHandlers:function(){this._scriptLoadDelegate=Function.createDelegate(this,this._scriptLoadHandler);if(Sys.Browser.agent!==Sys.Browser.InternetExplorer){this._scriptElement.readyState="loaded";$addHandler(this._scriptElement,"load",this._scriptLoadDelegate)}else $addHandler(this._scriptElement,"readystatechange",this._scriptLoadDelegate);if(this._scriptElement.addEventListener){this._scriptErrorDelegate=Function.createDelegate(this,this._scriptErrorHandler);this._scriptElement.addEventListener("error",this._scriptErrorDelegate,false)}},_removeScriptElementHandlers:function(){if(this._scriptLoadDelegate){var a=this.get_scriptElement();if(Sys.Browser.agent!==Sys.Browser.InternetExplorer)$removeHandler(a,"load",this._scriptLoadDelegate);else $removeHandler(a,"readystatechange",this._scriptLoadDelegate);if(this._scriptErrorDelegate){this._scriptElement.removeEventListener("error",this._scriptErrorDelegate,false);this._scriptErrorDelegate=null}this._scriptLoadDelegate=null}},_scriptErrorHandler:function(){if(this._disposed)return;this._completedCallback(this.get_scriptElement(),false)},_scriptLoadHandler:function(){if(this._disposed)return;var a=this.get_scriptElement();if(a.readyState!=="loaded"&&a.readyState!=="complete")return;this._completedCallback(a,true)}};Sys._ScriptLoaderTask.registerClass("Sys._ScriptLoaderTask",null,Sys.IDisposable);Sys._ScriptLoaderTask._clearScript=function(a){if(!Sys.Debug.isDebug)a.parentNode.removeChild(a)};Type.registerNamespace("Sys.Net");Sys.Net.WebServiceProxy=function(){};Sys.Net.WebServiceProxy.prototype={get_timeout:function(){return this._timeout||0},set_timeout:function(a){if(a<0)throw Error.argumentOutOfRange("value",a,Sys.Res.invalidTimeout);this._timeout=a},get_defaultUserContext:function(){return typeof this._userContext==="undefined"?null:this._userContext},set_defaultUserContext:function(a){this._userContext=a},get_defaultSucceededCallback:function(){return this._succeeded||null},set_defaultSucceededCallback:function(a){this._succeeded=a},get_defaultFailedCallback:function(){return this._failed||null},set_defaultFailedCallback:function(a){this._failed=a},get_enableJsonp:function(){return !!this._jsonp},set_enableJsonp:function(a){this._jsonp=a},get_path:function(){return this._path||null},set_path:function(a){this._path=a},get_jsonpCallbackParameter:function(){return this._callbackParameter||"callback"},set_jsonpCallbackParameter:function(a){this._callbackParameter=a},_invoke:function(d,e,g,f,c,b,a){c=c||this.get_defaultSucceededCallback();b=b||this.get_defaultFailedCallback();if(a===null||typeof a==="undefined")a=this.get_defaultUserContext();return Sys.Net.WebServiceProxy.invoke(d,e,g,f,c,b,a,this.get_timeout(),this.get_enableJsonp(),this.get_jsonpCallbackParameter())}};Sys.Net.WebServiceProxy.registerClass("Sys.Net.WebServiceProxy");Sys.Net.WebServiceProxy.invoke=function(q,a,m,l,j,b,g,e,w,p){var i=w!==false?Sys.Net.WebServiceProxy._xdomain.exec(q):null,c,n=i&&i.length===3&&(i[1]!==location.protocol||i[2]!==location.host);m=n||m;if(n){p=p||"callback";c="_jsonp"+Sys._jsonp++}if(!l)l={};var r=l;if(!m||!r)r={};var s,h,f=null,k,o=null,u=Sys.Net.WebRequest._createUrl(a?q+"/"+encodeURIComponent(a):q,r,n?p+"=Sys."+c:null);if(n){s=document.createElement("script");s.src=u;k=new Sys._ScriptLoaderTask(s,function(d,b){if(!b||c)t({Message:String.format(Sys.Res.webServiceFailedNoMsg,a)},-1)});function v(){if(f===null)return;f=null;h=new Sys.Net.WebServiceError(true,String.format(Sys.Res.webServiceTimedOut,a));k.dispose();delete Sys[c];if(b)b(h,g,a)}function t(d,e){if(f!==null){window.clearTimeout(f);f=null}k.dispose();delete Sys[c];c=null;if(typeof e!=="undefined"&&e!==200){if(b){h=new Sys.Net.WebServiceError(false,d.Message||String.format(Sys.Res.webServiceFailedNoMsg,a),d.StackTrace||null,d.ExceptionType||null,d);h._statusCode=e;b(h,g,a)}}else if(j)j(d,g,a)}Sys[c]=t;e=e||Sys.Net.WebRequestManager.get_defaultTimeout();if(e>0)f=window.setTimeout(v,e);k.execute();return null}var d=new Sys.Net.WebRequest;d.set_url(u);d.get_headers()["Content-Type"]="application/json; charset=utf-8";if(!m){o=Sys.Serialization.JavaScriptSerializer.serialize(l);if(o==="{}")o=""}d.set_body(o);d.add_completed(x);if(e&&e>0)d.set_timeout(e);d.invoke();function x(d){if(d.get_responseAvailable()){var f=d.get_statusCode(),c=null;try{var e=d.getResponseHeader("Content-Type");if(e.startsWith("application/json"))c=d.get_object();else if(e.startsWith("text/xml"))c=d.get_xml();else c=d.get_responseData()}catch(m){}var k=d.getResponseHeader("jsonerror"),h=k==="true";if(h){if(c)c=new Sys.Net.WebServiceError(false,c.Message,c.StackTrace,c.ExceptionType,c)}else if(e.startsWith("application/json"))c=!c||typeof c.d==="undefined"?c:c.d;if(f<200||f>=300||h){if(b){if(!c||!h)c=new Sys.Net.WebServiceError(false,String.format(Sys.Res.webServiceFailedNoMsg,a));c._statusCode=f;b(c,g,a)}}else if(j)j(c,g,a)}else{var i;if(d.get_timedOut())i=String.format(Sys.Res.webServiceTimedOut,a);else i=String.format(Sys.Res.webServiceFailedNoMsg,a);if(b)b(new Sys.Net.WebServiceError(d.get_timedOut(),i,"",""),g,a)}}return d};Sys.Net.WebServiceProxy._generateTypedConstructor=function(a){return function(b){if(b)for(var c in b)this[c]=b[c];this.__type=a}};Sys._jsonp=0;Sys.Net.WebServiceProxy._xdomain=/^\s*([a-zA-Z0-9\+\-\.]+\:)\/\/([^?#\/]+)/;Sys.Net.WebServiceError=function(d,e,c,a,b){this._timedOut=d;this._message=e;this._stackTrace=c;this._exceptionType=a;this._errorObject=b;this._statusCode=-1};Sys.Net.WebServiceError.prototype={get_timedOut:function(){return this._timedOut},get_statusCode:function(){return this._statusCode},get_message:function(){return this._message},get_stackTrace:function(){return this._stackTrace||""},get_exceptionType:function(){return this._exceptionType||""},get_errorObject:function(){return this._errorObject||null}};Sys.Net.WebServiceError.registerClass("Sys.Net.WebServiceError");
+Type.registerNamespace('Sys');Sys.Res={'argumentInteger':'Value must be an integer.','invokeCalledTwice':'Cannot call invoke more than once.','webServiceFailed':'The server method \'{0}\' failed with the following error: {1}','argumentType':'Object cannot be converted to the required type.','argumentNull':'Value cannot be null.','scriptAlreadyLoaded':'The script \'{0}\' has been referenced multiple times. If referencing Microsoft AJAX scripts explicitly, set the MicrosoftAjaxMode property of the ScriptManager to Explicit.','scriptDependencyNotFound':'The script \'{0}\' failed to load because it is dependent on script \'{1}\'.','formatBadFormatSpecifier':'Format specifier was invalid.','requiredScriptReferenceNotIncluded':'\'{0}\' requires that you have included a script reference to \'{1}\'.','webServiceFailedNoMsg':'The server method \'{0}\' failed.','argumentDomElement':'Value must be a DOM element.','invalidExecutorType':'Could not create a valid Sys.Net.WebRequestExecutor from: {0}.','cannotCallBeforeResponse':'Cannot call {0} when responseAvailable is false.','actualValue':'Actual value was {0}.','enumInvalidValue':'\'{0}\' is not a valid value for enum {1}.','scriptLoadFailed':'The script \'{0}\' could not be loaded.','parameterCount':'Parameter count mismatch.','cannotDeserializeEmptyString':'Cannot deserialize empty string.','formatInvalidString':'Input string was not in a correct format.','invalidTimeout':'Value must be greater than or equal to zero.','cannotAbortBeforeStart':'Cannot abort when executor has not started.','argument':'Value does not fall within the expected range.','cannotDeserializeInvalidJson':'Cannot deserialize. The data does not correspond to valid JSON.','invalidHttpVerb':'httpVerb cannot be set to an empty or null string.','nullWebRequest':'Cannot call executeRequest with a null webRequest.','eventHandlerInvalid':'Handler was not added through the Sys.UI.DomEvent.addHandler method.','cannotSerializeNonFiniteNumbers':'Cannot serialize non finite numbers.','argumentUndefined':'Value cannot be undefined.','webServiceInvalidReturnType':'The server method \'{0}\' returned an invalid type. Expected type: {1}','servicePathNotSet':'The path to the web service has not been set.','argumentTypeWithTypes':'Object of type \'{0}\' cannot be converted to type \'{1}\'.','cannotCallOnceStarted':'Cannot call {0} once started.','badBaseUrl1':'Base URL does not contain ://.','badBaseUrl2':'Base URL does not contain another /.','badBaseUrl3':'Cannot find last / in base URL.','setExecutorAfterActive':'Cannot set executor after it has become active.','paramName':'Parameter name: {0}','nullReferenceInPath':'Null reference while evaluating data path: \'{0}\'.','cannotCallOutsideHandler':'Cannot call {0} outside of a completed event handler.','cannotSerializeObjectWithCycle':'Cannot serialize object with cyclic reference within child properties.','format':'One of the identified items was in an invalid format.','assertFailedCaller':'Assertion Failed: {0}\r\nat {1}','argumentOutOfRange':'Specified argument was out of the range of valid values.','webServiceTimedOut':'The server method \'{0}\' timed out.','notImplemented':'The method or operation is not implemented.','assertFailed':'Assertion Failed: {0}','invalidOperation':'Operation is not valid due to the current state of the object.','breakIntoDebugger':'{0}\r\n\r\nBreak into debugger?'};
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcAjax.debug.js b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcAjax.debug.js
new file mode 100644
index 0000000..eb68ba7
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcAjax.debug.js
@@ -0,0 +1,408 @@
+//!----------------------------------------------------------
+//! Copyright (C) Microsoft Corporation. All rights reserved.
+//!----------------------------------------------------------
+//! MicrosoftMvcAjax.js
+
+Type.registerNamespace('Sys.Mvc');
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.AjaxOptions
+
+Sys.Mvc.$create_AjaxOptions = function Sys_Mvc_AjaxOptions() { return {}; }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.InsertionMode
+
+Sys.Mvc.InsertionMode = function() {
+ /// <field name="replace" type="Number" integer="true" static="true">
+ /// </field>
+ /// <field name="insertBefore" type="Number" integer="true" static="true">
+ /// </field>
+ /// <field name="insertAfter" type="Number" integer="true" static="true">
+ /// </field>
+};
+Sys.Mvc.InsertionMode.prototype = {
+ replace: 0,
+ insertBefore: 1,
+ insertAfter: 2
+}
+Sys.Mvc.InsertionMode.registerEnum('Sys.Mvc.InsertionMode', false);
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.AjaxContext
+
+Sys.Mvc.AjaxContext = function Sys_Mvc_AjaxContext(request, updateTarget, loadingElement, insertionMode) {
+ /// <param name="request" type="Sys.Net.WebRequest">
+ /// </param>
+ /// <param name="updateTarget" type="Object" domElement="true">
+ /// </param>
+ /// <param name="loadingElement" type="Object" domElement="true">
+ /// </param>
+ /// <param name="insertionMode" type="Sys.Mvc.InsertionMode">
+ /// </param>
+ /// <field name="_insertionMode" type="Sys.Mvc.InsertionMode">
+ /// </field>
+ /// <field name="_loadingElement" type="Object" domElement="true">
+ /// </field>
+ /// <field name="_response" type="Sys.Net.WebRequestExecutor">
+ /// </field>
+ /// <field name="_request" type="Sys.Net.WebRequest">
+ /// </field>
+ /// <field name="_updateTarget" type="Object" domElement="true">
+ /// </field>
+ this._request = request;
+ this._updateTarget = updateTarget;
+ this._loadingElement = loadingElement;
+ this._insertionMode = insertionMode;
+}
+Sys.Mvc.AjaxContext.prototype = {
+ _insertionMode: 0,
+ _loadingElement: null,
+ _response: null,
+ _request: null,
+ _updateTarget: null,
+
+ get_data: function Sys_Mvc_AjaxContext$get_data() {
+ /// <value type="String"></value>
+ if (this._response) {
+ return this._response.get_responseData();
+ }
+ else {
+ return null;
+ }
+ },
+
+ get_insertionMode: function Sys_Mvc_AjaxContext$get_insertionMode() {
+ /// <value type="Sys.Mvc.InsertionMode"></value>
+ return this._insertionMode;
+ },
+
+ get_loadingElement: function Sys_Mvc_AjaxContext$get_loadingElement() {
+ /// <value type="Object" domElement="true"></value>
+ return this._loadingElement;
+ },
+
+ get_object: function Sys_Mvc_AjaxContext$get_object() {
+ /// <value type="Object"></value>
+ var executor = this.get_response();
+ return (executor) ? executor.get_object() : null;
+ },
+
+ get_response: function Sys_Mvc_AjaxContext$get_response() {
+ /// <value type="Sys.Net.WebRequestExecutor"></value>
+ return this._response;
+ },
+ set_response: function Sys_Mvc_AjaxContext$set_response(value) {
+ /// <value type="Sys.Net.WebRequestExecutor"></value>
+ this._response = value;
+ return value;
+ },
+
+ get_request: function Sys_Mvc_AjaxContext$get_request() {
+ /// <value type="Sys.Net.WebRequest"></value>
+ return this._request;
+ },
+
+ get_updateTarget: function Sys_Mvc_AjaxContext$get_updateTarget() {
+ /// <value type="Object" domElement="true"></value>
+ return this._updateTarget;
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.AsyncHyperlink
+
+Sys.Mvc.AsyncHyperlink = function Sys_Mvc_AsyncHyperlink() {
+}
+Sys.Mvc.AsyncHyperlink.handleClick = function Sys_Mvc_AsyncHyperlink$handleClick(anchor, evt, ajaxOptions) {
+ /// <param name="anchor" type="Object" domElement="true">
+ /// </param>
+ /// <param name="evt" type="Sys.UI.DomEvent">
+ /// </param>
+ /// <param name="ajaxOptions" type="Sys.Mvc.AjaxOptions">
+ /// </param>
+ evt.preventDefault();
+ Sys.Mvc.MvcHelpers._asyncRequest(anchor.href, 'post', '', anchor, ajaxOptions);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.MvcHelpers
+
+Sys.Mvc.MvcHelpers = function Sys_Mvc_MvcHelpers() {
+}
+Sys.Mvc.MvcHelpers._serializeSubmitButton = function Sys_Mvc_MvcHelpers$_serializeSubmitButton(element, offsetX, offsetY) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ /// <param name="offsetX" type="Number" integer="true">
+ /// </param>
+ /// <param name="offsetY" type="Number" integer="true">
+ /// </param>
+ /// <returns type="String"></returns>
+ if (element.disabled) {
+ return null;
+ }
+ var name = element.name;
+ if (name) {
+ var tagName = element.tagName.toUpperCase();
+ var encodedName = encodeURIComponent(name);
+ var inputElement = element;
+ if (tagName === 'INPUT') {
+ var type = inputElement.type;
+ if (type === 'submit') {
+ return encodedName + '=' + encodeURIComponent(inputElement.value);
+ }
+ else if (type === 'image') {
+ return encodedName + '.x=' + offsetX + '&' + encodedName + '.y=' + offsetY;
+ }
+ }
+ else if ((tagName === 'BUTTON') && (name.length) && (inputElement.type === 'submit')) {
+ return encodedName + '=' + encodeURIComponent(inputElement.value);
+ }
+ }
+ return null;
+}
+Sys.Mvc.MvcHelpers._serializeForm = function Sys_Mvc_MvcHelpers$_serializeForm(form) {
+ /// <param name="form" type="Object" domElement="true">
+ /// </param>
+ /// <returns type="String"></returns>
+ var formElements = form.elements;
+ var formBody = new Sys.StringBuilder();
+ var count = formElements.length;
+ for (var i = 0; i < count; i++) {
+ var element = formElements[i];
+ var name = element.name;
+ if (!name || !name.length) {
+ continue;
+ }
+ var tagName = element.tagName.toUpperCase();
+ if (tagName === 'INPUT') {
+ var inputElement = element;
+ var type = inputElement.type;
+ if ((type === 'text') || (type === 'password') || (type === 'hidden') || (((type === 'checkbox') || (type === 'radio')) && element.checked)) {
+ formBody.append(encodeURIComponent(name));
+ formBody.append('=');
+ formBody.append(encodeURIComponent(inputElement.value));
+ formBody.append('&');
+ }
+ }
+ else if (tagName === 'SELECT') {
+ var selectElement = element;
+ var optionCount = selectElement.options.length;
+ for (var j = 0; j < optionCount; j++) {
+ var optionElement = selectElement.options[j];
+ if (optionElement.selected) {
+ formBody.append(encodeURIComponent(name));
+ formBody.append('=');
+ formBody.append(encodeURIComponent(optionElement.value));
+ formBody.append('&');
+ }
+ }
+ }
+ else if (tagName === 'TEXTAREA') {
+ formBody.append(encodeURIComponent(name));
+ formBody.append('=');
+ formBody.append(encodeURIComponent((element.value)));
+ formBody.append('&');
+ }
+ }
+ var additionalInput = form._additionalInput;
+ if (additionalInput) {
+ formBody.append(additionalInput);
+ formBody.append('&');
+ }
+ return formBody.toString();
+}
+Sys.Mvc.MvcHelpers._asyncRequest = function Sys_Mvc_MvcHelpers$_asyncRequest(url, verb, body, triggerElement, ajaxOptions) {
+ /// <param name="url" type="String">
+ /// </param>
+ /// <param name="verb" type="String">
+ /// </param>
+ /// <param name="body" type="String">
+ /// </param>
+ /// <param name="triggerElement" type="Object" domElement="true">
+ /// </param>
+ /// <param name="ajaxOptions" type="Sys.Mvc.AjaxOptions">
+ /// </param>
+ if (ajaxOptions.confirm) {
+ if (!confirm(ajaxOptions.confirm)) {
+ return;
+ }
+ }
+ if (ajaxOptions.url) {
+ url = ajaxOptions.url;
+ }
+ if (ajaxOptions.httpMethod) {
+ verb = ajaxOptions.httpMethod;
+ }
+ if (body.length > 0 && !body.endsWith('&')) {
+ body += '&';
+ }
+ body += 'X-Requested-With=XMLHttpRequest';
+ var upperCaseVerb = verb.toUpperCase();
+ var isGetOrPost = (upperCaseVerb === 'GET' || upperCaseVerb === 'POST');
+ if (!isGetOrPost) {
+ body += '&';
+ body += 'X-HTTP-Method-Override=' + upperCaseVerb;
+ }
+ var requestBody = '';
+ if (upperCaseVerb === 'GET' || upperCaseVerb === 'DELETE') {
+ if (url.indexOf('?') > -1) {
+ if (!url.endsWith('&')) {
+ url += '&';
+ }
+ url += body;
+ }
+ else {
+ url += '?';
+ url += body;
+ }
+ }
+ else {
+ requestBody = body;
+ }
+ var request = new Sys.Net.WebRequest();
+ request.set_url(url);
+ if (isGetOrPost) {
+ request.set_httpVerb(verb);
+ }
+ else {
+ request.set_httpVerb('POST');
+ request.get_headers()['X-HTTP-Method-Override'] = upperCaseVerb;
+ }
+ request.set_body(requestBody);
+ if (verb.toUpperCase() === 'PUT') {
+ request.get_headers()['Content-Type'] = 'application/x-www-form-urlencoded;';
+ }
+ request.get_headers()['X-Requested-With'] = 'XMLHttpRequest';
+ var updateElement = null;
+ if (ajaxOptions.updateTargetId) {
+ updateElement = $get(ajaxOptions.updateTargetId);
+ }
+ var loadingElement = null;
+ if (ajaxOptions.loadingElementId) {
+ loadingElement = $get(ajaxOptions.loadingElementId);
+ }
+ var ajaxContext = new Sys.Mvc.AjaxContext(request, updateElement, loadingElement, ajaxOptions.insertionMode);
+ var continueRequest = true;
+ if (ajaxOptions.onBegin) {
+ continueRequest = ajaxOptions.onBegin(ajaxContext) !== false;
+ }
+ if (loadingElement) {
+ Sys.UI.DomElement.setVisible(ajaxContext.get_loadingElement(), true);
+ }
+ if (continueRequest) {
+ request.add_completed(Function.createDelegate(null, function(executor) {
+ Sys.Mvc.MvcHelpers._onComplete(request, ajaxOptions, ajaxContext);
+ }));
+ request.invoke();
+ }
+}
+Sys.Mvc.MvcHelpers._onComplete = function Sys_Mvc_MvcHelpers$_onComplete(request, ajaxOptions, ajaxContext) {
+ /// <param name="request" type="Sys.Net.WebRequest">
+ /// </param>
+ /// <param name="ajaxOptions" type="Sys.Mvc.AjaxOptions">
+ /// </param>
+ /// <param name="ajaxContext" type="Sys.Mvc.AjaxContext">
+ /// </param>
+ ajaxContext.set_response(request.get_executor());
+ if (ajaxOptions.onComplete && ajaxOptions.onComplete(ajaxContext) === false) {
+ return;
+ }
+ var statusCode = ajaxContext.get_response().get_statusCode();
+ if ((statusCode >= 200 && statusCode < 300) || statusCode === 304 || statusCode === 1223) {
+ if (statusCode !== 204 && statusCode !== 304 && statusCode !== 1223) {
+ var contentType = ajaxContext.get_response().getResponseHeader('Content-Type');
+ if ((contentType) && (contentType.indexOf('application/x-javascript') !== -1)) {
+ eval(ajaxContext.get_data());
+ }
+ else {
+ Sys.Mvc.MvcHelpers.updateDomElement(ajaxContext.get_updateTarget(), ajaxContext.get_insertionMode(), ajaxContext.get_data());
+ }
+ }
+ if (ajaxOptions.onSuccess) {
+ ajaxOptions.onSuccess(ajaxContext);
+ }
+ }
+ else {
+ if (ajaxOptions.onFailure) {
+ ajaxOptions.onFailure(ajaxContext);
+ }
+ }
+ if (ajaxContext.get_loadingElement()) {
+ Sys.UI.DomElement.setVisible(ajaxContext.get_loadingElement(), false);
+ }
+}
+Sys.Mvc.MvcHelpers.updateDomElement = function Sys_Mvc_MvcHelpers$updateDomElement(target, insertionMode, content) {
+ /// <param name="target" type="Object" domElement="true">
+ /// </param>
+ /// <param name="insertionMode" type="Sys.Mvc.InsertionMode">
+ /// </param>
+ /// <param name="content" type="String">
+ /// </param>
+ if (target) {
+ switch (insertionMode) {
+ case Sys.Mvc.InsertionMode.replace:
+ target.innerHTML = content;
+ break;
+ case Sys.Mvc.InsertionMode.insertBefore:
+ if (content && content.length > 0) {
+ target.innerHTML = content + target.innerHTML.trimStart();
+ }
+ break;
+ case Sys.Mvc.InsertionMode.insertAfter:
+ if (content && content.length > 0) {
+ target.innerHTML = target.innerHTML.trimEnd() + content;
+ }
+ break;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.AsyncForm
+
+Sys.Mvc.AsyncForm = function Sys_Mvc_AsyncForm() {
+}
+Sys.Mvc.AsyncForm.handleClick = function Sys_Mvc_AsyncForm$handleClick(form, evt) {
+ /// <param name="form" type="Object" domElement="true">
+ /// </param>
+ /// <param name="evt" type="Sys.UI.DomEvent">
+ /// </param>
+ var additionalInput = Sys.Mvc.MvcHelpers._serializeSubmitButton(evt.target, evt.offsetX, evt.offsetY);
+ form._additionalInput = additionalInput;
+}
+Sys.Mvc.AsyncForm.handleSubmit = function Sys_Mvc_AsyncForm$handleSubmit(form, evt, ajaxOptions) {
+ /// <param name="form" type="Object" domElement="true">
+ /// </param>
+ /// <param name="evt" type="Sys.UI.DomEvent">
+ /// </param>
+ /// <param name="ajaxOptions" type="Sys.Mvc.AjaxOptions">
+ /// </param>
+ evt.preventDefault();
+ var validationCallbacks = form.validationCallbacks;
+ if (validationCallbacks) {
+ for (var i = 0; i < validationCallbacks.length; i++) {
+ var callback = validationCallbacks[i];
+ if (!callback()) {
+ return;
+ }
+ }
+ }
+ var body = Sys.Mvc.MvcHelpers._serializeForm(form);
+ Sys.Mvc.MvcHelpers._asyncRequest(form.action, form.method || 'post', body, form, ajaxOptions);
+}
+
+
+Sys.Mvc.AjaxContext.registerClass('Sys.Mvc.AjaxContext');
+Sys.Mvc.AsyncHyperlink.registerClass('Sys.Mvc.AsyncHyperlink');
+Sys.Mvc.MvcHelpers.registerClass('Sys.Mvc.MvcHelpers');
+Sys.Mvc.AsyncForm.registerClass('Sys.Mvc.AsyncForm');
+
+// ---- Do not remove this footer ----
+// Generated using Script# v0.5.0.0 (http://projects.nikhilk.net)
+// -----------------------------------
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcAjax.js b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcAjax.js
new file mode 100644
index 0000000..c5a6165
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcAjax.js
@@ -0,0 +1,25 @@
+//----------------------------------------------------------
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//----------------------------------------------------------
+// MicrosoftMvcAjax.js
+
+Type.registerNamespace('Sys.Mvc');Sys.Mvc.$create_AjaxOptions=function(){return {};}
+Sys.Mvc.InsertionMode=function(){};Sys.Mvc.InsertionMode.prototype = {replace:0,insertBefore:1,insertAfter:2}
+Sys.Mvc.InsertionMode.registerEnum('Sys.Mvc.InsertionMode',false);Sys.Mvc.AjaxContext=function(request,updateTarget,loadingElement,insertionMode){this.$3=request;this.$4=updateTarget;this.$1=loadingElement;this.$0=insertionMode;}
+Sys.Mvc.AjaxContext.prototype={$0:0,$1:null,$2:null,$3:null,$4:null,get_data:function(){if(this.$2){return this.$2.get_responseData();}else{return null;}},get_insertionMode:function(){return this.$0;},get_loadingElement:function(){return this.$1;},get_object:function(){var $0=this.get_response();return ($0)?$0.get_object():null;},get_response:function(){return this.$2;},set_response:function(value){this.$2=value;return value;},get_request:function(){return this.$3;},get_updateTarget:function(){return this.$4;}}
+Sys.Mvc.AsyncHyperlink=function(){}
+Sys.Mvc.AsyncHyperlink.handleClick=function(anchor,evt,ajaxOptions){evt.preventDefault();Sys.Mvc.MvcHelpers.$2(anchor.href,'post','',anchor,ajaxOptions);}
+Sys.Mvc.MvcHelpers=function(){}
+Sys.Mvc.MvcHelpers.$0=function($p0,$p1,$p2){if($p0.disabled){return null;}var $0=$p0.name;if($0){var $1=$p0.tagName.toUpperCase();var $2=encodeURIComponent($0);var $3=$p0;if($1==='INPUT'){var $4=$3.type;if($4==='submit'){return $2+'='+encodeURIComponent($3.value);}else if($4==='image'){return $2+'.x='+$p1+'&'+$2+'.y='+$p2;}}else if(($1==='BUTTON')&&($0.length)&&($3.type==='submit')){return $2+'='+encodeURIComponent($3.value);}}return null;}
+Sys.Mvc.MvcHelpers.$1=function($p0){var $0=$p0.elements;var $1=new Sys.StringBuilder();var $2=$0.length;for(var $4=0;$4<$2;$4++){var $5=$0[$4];var $6=$5.name;if(!$6||!$6.length){continue;}var $7=$5.tagName.toUpperCase();if($7==='INPUT'){var $8=$5;var $9=$8.type;if(($9==='text')||($9==='password')||($9==='hidden')||((($9==='checkbox')||($9==='radio'))&&$5.checked)){$1.append(encodeURIComponent($6));$1.append('=');$1.append(encodeURIComponent($8.value));$1.append('&');}}else if($7==='SELECT'){var $A=$5;var $B=$A.options.length;for(var $C=0;$C<$B;$C++){var $D=$A.options[$C];if($D.selected){$1.append(encodeURIComponent($6));$1.append('=');$1.append(encodeURIComponent($D.value));$1.append('&');}}}else if($7==='TEXTAREA'){$1.append(encodeURIComponent($6));$1.append('=');$1.append(encodeURIComponent(($5.value)));$1.append('&');}}var $3=$p0._additionalInput;if($3){$1.append($3);$1.append('&');}return $1.toString();}
+Sys.Mvc.MvcHelpers.$2=function($p0,$p1,$p2,$p3,$p4){if($p4.confirm){if(!confirm($p4.confirm)){return;}}if($p4.url){$p0=$p4.url;}if($p4.httpMethod){$p1=$p4.httpMethod;}if($p2.length>0&&!$p2.endsWith('&')){$p2+='&';}$p2+='X-Requested-With=XMLHttpRequest';var $0=$p1.toUpperCase();var $1=($0==='GET'||$0==='POST');if(!$1){$p2+='&';$p2+='X-HTTP-Method-Override='+$0;}var $2='';if($0==='GET'||$0==='DELETE'){if($p0.indexOf('?')>-1){if(!$p0.endsWith('&')){$p0+='&';}$p0+=$p2;}else{$p0+='?';$p0+=$p2;}}else{$2=$p2;}var $3=new Sys.Net.WebRequest();$3.set_url($p0);if($1){$3.set_httpVerb($p1);}else{$3.set_httpVerb('POST');$3.get_headers()['X-HTTP-Method-Override']=$0;}$3.set_body($2);if($p1.toUpperCase()==='PUT'){$3.get_headers()['Content-Type']='application/x-www-form-urlencoded;';}$3.get_headers()['X-Requested-With']='XMLHttpRequest';var $4=null;if($p4.updateTargetId){$4=$get($p4.updateTargetId);}var $5=null;if($p4.loadingElementId){$5=$get($p4.loadingElementId);}var $6=new Sys.Mvc.AjaxContext($3,$4,$5,$p4.insertionMode);var $7=true;if($p4.onBegin){$7=$p4.onBegin($6)!==false;}if($5){Sys.UI.DomElement.setVisible($6.get_loadingElement(),true);}if($7){$3.add_completed(Function.createDelegate(null,function($p1_0){
+Sys.Mvc.MvcHelpers.$3($3,$p4,$6);}));$3.invoke();}}
+Sys.Mvc.MvcHelpers.$3=function($p0,$p1,$p2){$p2.set_response($p0.get_executor());if($p1.onComplete&&$p1.onComplete($p2)===false){return;}var $0=$p2.get_response().get_statusCode();if(($0>=200&&$0<300)||$0===304||$0===1223){if($0!==204&&$0!==304&&$0!==1223){var $1=$p2.get_response().getResponseHeader('Content-Type');if(($1)&&($1.indexOf('application/x-javascript')!==-1)){eval($p2.get_data());}else{Sys.Mvc.MvcHelpers.updateDomElement($p2.get_updateTarget(),$p2.get_insertionMode(),$p2.get_data());}}if($p1.onSuccess){$p1.onSuccess($p2);}}else{if($p1.onFailure){$p1.onFailure($p2);}}if($p2.get_loadingElement()){Sys.UI.DomElement.setVisible($p2.get_loadingElement(),false);}}
+Sys.Mvc.MvcHelpers.updateDomElement=function(target,insertionMode,content){if(target){switch(insertionMode){case 0:target.innerHTML=content;break;case 1:if(content&&content.length>0){target.innerHTML=content+target.innerHTML.trimStart();}break;case 2:if(content&&content.length>0){target.innerHTML=target.innerHTML.trimEnd()+content;}break;}}}
+Sys.Mvc.AsyncForm=function(){}
+Sys.Mvc.AsyncForm.handleClick=function(form,evt){var $0=Sys.Mvc.MvcHelpers.$0(evt.target,evt.offsetX,evt.offsetY);form._additionalInput = $0;}
+Sys.Mvc.AsyncForm.handleSubmit=function(form,evt,ajaxOptions){evt.preventDefault();var $0=form.validationCallbacks;if($0){for(var $2=0;$2<$0.length;$2++){var $3=$0[$2];if(!$3()){return;}}}var $1=Sys.Mvc.MvcHelpers.$1(form);Sys.Mvc.MvcHelpers.$2(form.action,form.method||'post',$1,form,ajaxOptions);}
+Sys.Mvc.AjaxContext.registerClass('Sys.Mvc.AjaxContext');Sys.Mvc.AsyncHyperlink.registerClass('Sys.Mvc.AsyncHyperlink');Sys.Mvc.MvcHelpers.registerClass('Sys.Mvc.MvcHelpers');Sys.Mvc.AsyncForm.registerClass('Sys.Mvc.AsyncForm');
+// ---- Do not remove this footer ----
+// Generated using Script# v0.5.0.0 (http://projects.nikhilk.net)
+// -----------------------------------
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcValidation.debug.js b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcValidation.debug.js
new file mode 100644
index 0000000..9896f90
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcValidation.debug.js
@@ -0,0 +1,881 @@
+//!----------------------------------------------------------
+//! Copyright (C) Microsoft Corporation. All rights reserved.
+//!----------------------------------------------------------
+//! MicrosoftMvcValidation.js
+
+
+Type.registerNamespace('Sys.Mvc');
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.Validation
+
+Sys.Mvc.$create_Validation = function Sys_Mvc_Validation() { return {}; }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.JsonValidationField
+
+Sys.Mvc.$create_JsonValidationField = function Sys_Mvc_JsonValidationField() { return {}; }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.JsonValidationOptions
+
+Sys.Mvc.$create_JsonValidationOptions = function Sys_Mvc_JsonValidationOptions() { return {}; }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.JsonValidationRule
+
+Sys.Mvc.$create_JsonValidationRule = function Sys_Mvc_JsonValidationRule() { return {}; }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.ValidationContext
+
+Sys.Mvc.$create_ValidationContext = function Sys_Mvc_ValidationContext() { return {}; }
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.NumberValidator
+
+Sys.Mvc.NumberValidator = function Sys_Mvc_NumberValidator() {
+}
+Sys.Mvc.NumberValidator.create = function Sys_Mvc_NumberValidator$create(rule) {
+ /// <param name="rule" type="Sys.Mvc.JsonValidationRule">
+ /// </param>
+ /// <returns type="Sys.Mvc.Validator"></returns>
+ return Function.createDelegate(new Sys.Mvc.NumberValidator(), new Sys.Mvc.NumberValidator().validate);
+}
+Sys.Mvc.NumberValidator.prototype = {
+
+ validate: function Sys_Mvc_NumberValidator$validate(value, context) {
+ /// <param name="value" type="String">
+ /// </param>
+ /// <param name="context" type="Sys.Mvc.ValidationContext">
+ /// </param>
+ /// <returns type="Object"></returns>
+ if (Sys.Mvc._validationUtil.stringIsNullOrEmpty(value)) {
+ return true;
+ }
+ var n = Number.parseLocale(value);
+ return (!isNaN(n));
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.FormContext
+
+Sys.Mvc.FormContext = function Sys_Mvc_FormContext(formElement, validationSummaryElement) {
+ /// <param name="formElement" type="Object" domElement="true">
+ /// </param>
+ /// <param name="validationSummaryElement" type="Object" domElement="true">
+ /// </param>
+ /// <field name="_validationSummaryErrorCss" type="String" static="true">
+ /// </field>
+ /// <field name="_validationSummaryValidCss" type="String" static="true">
+ /// </field>
+ /// <field name="_formValidationTag" type="String" static="true">
+ /// </field>
+ /// <field name="_onClickHandler" type="Sys.UI.DomEventHandler">
+ /// </field>
+ /// <field name="_onSubmitHandler" type="Sys.UI.DomEventHandler">
+ /// </field>
+ /// <field name="_errors" type="Array">
+ /// </field>
+ /// <field name="_submitButtonClicked" type="Object" domElement="true">
+ /// </field>
+ /// <field name="_validationSummaryElement" type="Object" domElement="true">
+ /// </field>
+ /// <field name="_validationSummaryULElement" type="Object" domElement="true">
+ /// </field>
+ /// <field name="fields" type="Array" elementType="FieldContext">
+ /// </field>
+ /// <field name="_formElement" type="Object" domElement="true">
+ /// </field>
+ /// <field name="replaceValidationSummary" type="Boolean">
+ /// </field>
+ this._errors = [];
+ this.fields = new Array(0);
+ this._formElement = formElement;
+ this._validationSummaryElement = validationSummaryElement;
+ formElement[Sys.Mvc.FormContext._formValidationTag] = this;
+ if (validationSummaryElement) {
+ var ulElements = validationSummaryElement.getElementsByTagName('ul');
+ if (ulElements.length > 0) {
+ this._validationSummaryULElement = ulElements[0];
+ }
+ }
+ this._onClickHandler = Function.createDelegate(this, this._form_OnClick);
+ this._onSubmitHandler = Function.createDelegate(this, this._form_OnSubmit);
+}
+Sys.Mvc.FormContext._Application_Load = function Sys_Mvc_FormContext$_Application_Load() {
+ var allFormOptions = window.mvcClientValidationMetadata;
+ if (allFormOptions) {
+ while (allFormOptions.length > 0) {
+ var thisFormOptions = allFormOptions.pop();
+ Sys.Mvc.FormContext._parseJsonOptions(thisFormOptions);
+ }
+ }
+}
+Sys.Mvc.FormContext._getFormElementsWithName = function Sys_Mvc_FormContext$_getFormElementsWithName(formElement, name) {
+ /// <param name="formElement" type="Object" domElement="true">
+ /// </param>
+ /// <param name="name" type="String">
+ /// </param>
+ /// <returns type="Array" elementType="Object" elementDomElement="true"></returns>
+ var allElementsWithNameInForm = [];
+ var allElementsWithName = document.getElementsByName(name);
+ for (var i = 0; i < allElementsWithName.length; i++) {
+ var thisElement = allElementsWithName[i];
+ if (Sys.Mvc.FormContext._isElementInHierarchy(formElement, thisElement)) {
+ Array.add(allElementsWithNameInForm, thisElement);
+ }
+ }
+ return allElementsWithNameInForm;
+}
+Sys.Mvc.FormContext.getValidationForForm = function Sys_Mvc_FormContext$getValidationForForm(formElement) {
+ /// <param name="formElement" type="Object" domElement="true">
+ /// </param>
+ /// <returns type="Sys.Mvc.FormContext"></returns>
+ return formElement[Sys.Mvc.FormContext._formValidationTag];
+}
+Sys.Mvc.FormContext._isElementInHierarchy = function Sys_Mvc_FormContext$_isElementInHierarchy(parent, child) {
+ /// <param name="parent" type="Object" domElement="true">
+ /// </param>
+ /// <param name="child" type="Object" domElement="true">
+ /// </param>
+ /// <returns type="Boolean"></returns>
+ while (child) {
+ if (parent === child) {
+ return true;
+ }
+ child = child.parentNode;
+ }
+ return false;
+}
+Sys.Mvc.FormContext._parseJsonOptions = function Sys_Mvc_FormContext$_parseJsonOptions(options) {
+ /// <param name="options" type="Sys.Mvc.JsonValidationOptions">
+ /// </param>
+ /// <returns type="Sys.Mvc.FormContext"></returns>
+ var formElement = $get(options.FormId);
+ var validationSummaryElement = (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(options.ValidationSummaryId)) ? $get(options.ValidationSummaryId) : null;
+ var formContext = new Sys.Mvc.FormContext(formElement, validationSummaryElement);
+ formContext.enableDynamicValidation();
+ formContext.replaceValidationSummary = options.ReplaceValidationSummary;
+ for (var i = 0; i < options.Fields.length; i++) {
+ var field = options.Fields[i];
+ var fieldElements = Sys.Mvc.FormContext._getFormElementsWithName(formElement, field.FieldName);
+ var validationMessageElement = (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(field.ValidationMessageId)) ? $get(field.ValidationMessageId) : null;
+ var fieldContext = new Sys.Mvc.FieldContext(formContext);
+ Array.addRange(fieldContext.elements, fieldElements);
+ fieldContext.validationMessageElement = validationMessageElement;
+ fieldContext.replaceValidationMessageContents = field.ReplaceValidationMessageContents;
+ for (var j = 0; j < field.ValidationRules.length; j++) {
+ var rule = field.ValidationRules[j];
+ var validator = Sys.Mvc.ValidatorRegistry.getValidator(rule);
+ if (validator) {
+ var validation = Sys.Mvc.$create_Validation();
+ validation.fieldErrorMessage = rule.ErrorMessage;
+ validation.validator = validator;
+ Array.add(fieldContext.validations, validation);
+ }
+ }
+ fieldContext.enableDynamicValidation();
+ Array.add(formContext.fields, fieldContext);
+ }
+ var registeredValidatorCallbacks = formElement.validationCallbacks;
+ if (!registeredValidatorCallbacks) {
+ registeredValidatorCallbacks = [];
+ formElement.validationCallbacks = registeredValidatorCallbacks;
+ }
+ registeredValidatorCallbacks.push(Function.createDelegate(null, function() {
+ return Sys.Mvc._validationUtil.arrayIsNullOrEmpty(formContext.validate('submit'));
+ }));
+ return formContext;
+}
+Sys.Mvc.FormContext.prototype = {
+ _onClickHandler: null,
+ _onSubmitHandler: null,
+ _submitButtonClicked: null,
+ _validationSummaryElement: null,
+ _validationSummaryULElement: null,
+ _formElement: null,
+ replaceValidationSummary: false,
+
+ addError: function Sys_Mvc_FormContext$addError(message) {
+ /// <param name="message" type="String">
+ /// </param>
+ this.addErrors([ message ]);
+ },
+
+ addErrors: function Sys_Mvc_FormContext$addErrors(messages) {
+ /// <param name="messages" type="Array" elementType="String">
+ /// </param>
+ if (!Sys.Mvc._validationUtil.arrayIsNullOrEmpty(messages)) {
+ Array.addRange(this._errors, messages);
+ this._onErrorCountChanged();
+ }
+ },
+
+ clearErrors: function Sys_Mvc_FormContext$clearErrors() {
+ Array.clear(this._errors);
+ this._onErrorCountChanged();
+ },
+
+ _displayError: function Sys_Mvc_FormContext$_displayError() {
+ if (this._validationSummaryElement) {
+ if (this._validationSummaryULElement) {
+ Sys.Mvc._validationUtil.removeAllChildren(this._validationSummaryULElement);
+ for (var i = 0; i < this._errors.length; i++) {
+ var liElement = document.createElement('li');
+ Sys.Mvc._validationUtil.setInnerText(liElement, this._errors[i]);
+ this._validationSummaryULElement.appendChild(liElement);
+ }
+ }
+ Sys.UI.DomElement.removeCssClass(this._validationSummaryElement, Sys.Mvc.FormContext._validationSummaryValidCss);
+ Sys.UI.DomElement.addCssClass(this._validationSummaryElement, Sys.Mvc.FormContext._validationSummaryErrorCss);
+ }
+ },
+
+ _displaySuccess: function Sys_Mvc_FormContext$_displaySuccess() {
+ var validationSummaryElement = this._validationSummaryElement;
+ if (validationSummaryElement) {
+ var validationSummaryULElement = this._validationSummaryULElement;
+ if (validationSummaryULElement) {
+ validationSummaryULElement.innerHTML = '';
+ }
+ Sys.UI.DomElement.removeCssClass(validationSummaryElement, Sys.Mvc.FormContext._validationSummaryErrorCss);
+ Sys.UI.DomElement.addCssClass(validationSummaryElement, Sys.Mvc.FormContext._validationSummaryValidCss);
+ }
+ },
+
+ enableDynamicValidation: function Sys_Mvc_FormContext$enableDynamicValidation() {
+ Sys.UI.DomEvent.addHandler(this._formElement, 'click', this._onClickHandler);
+ Sys.UI.DomEvent.addHandler(this._formElement, 'submit', this._onSubmitHandler);
+ },
+
+ _findSubmitButton: function Sys_Mvc_FormContext$_findSubmitButton(element) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ /// <returns type="Object" domElement="true"></returns>
+ if (element.disabled) {
+ return null;
+ }
+ var tagName = element.tagName.toUpperCase();
+ var inputElement = element;
+ if (tagName === 'INPUT') {
+ var type = inputElement.type;
+ if (type === 'submit' || type === 'image') {
+ return inputElement;
+ }
+ }
+ else if ((tagName === 'BUTTON') && (inputElement.type === 'submit')) {
+ return inputElement;
+ }
+ return null;
+ },
+
+ _form_OnClick: function Sys_Mvc_FormContext$_form_OnClick(e) {
+ /// <param name="e" type="Sys.UI.DomEvent">
+ /// </param>
+ this._submitButtonClicked = this._findSubmitButton(e.target);
+ },
+
+ _form_OnSubmit: function Sys_Mvc_FormContext$_form_OnSubmit(e) {
+ /// <param name="e" type="Sys.UI.DomEvent">
+ /// </param>
+ var form = e.target;
+ var submitButton = this._submitButtonClicked;
+ if (submitButton && submitButton.disableValidation) {
+ return;
+ }
+ var errorMessages = this.validate('submit');
+ if (!Sys.Mvc._validationUtil.arrayIsNullOrEmpty(errorMessages)) {
+ e.preventDefault();
+ }
+ },
+
+ _onErrorCountChanged: function Sys_Mvc_FormContext$_onErrorCountChanged() {
+ if (!this._errors.length) {
+ this._displaySuccess();
+ }
+ else {
+ this._displayError();
+ }
+ },
+
+ validate: function Sys_Mvc_FormContext$validate(eventName) {
+ /// <param name="eventName" type="String">
+ /// </param>
+ /// <returns type="Array" elementType="String"></returns>
+ var fields = this.fields;
+ var errors = [];
+ for (var i = 0; i < fields.length; i++) {
+ var field = fields[i];
+ var thisErrors = field.validate(eventName);
+ if (thisErrors) {
+ Array.addRange(errors, thisErrors);
+ }
+ }
+ if (this.replaceValidationSummary) {
+ this.clearErrors();
+ this.addErrors(errors);
+ }
+ return errors;
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.FieldContext
+
+Sys.Mvc.FieldContext = function Sys_Mvc_FieldContext(formContext) {
+ /// <param name="formContext" type="Sys.Mvc.FormContext">
+ /// </param>
+ /// <field name="_hasTextChangedTag" type="String" static="true">
+ /// </field>
+ /// <field name="_hasValidationFiredTag" type="String" static="true">
+ /// </field>
+ /// <field name="_inputElementErrorCss" type="String" static="true">
+ /// </field>
+ /// <field name="_inputElementValidCss" type="String" static="true">
+ /// </field>
+ /// <field name="_validationMessageErrorCss" type="String" static="true">
+ /// </field>
+ /// <field name="_validationMessageValidCss" type="String" static="true">
+ /// </field>
+ /// <field name="_onBlurHandler" type="Sys.UI.DomEventHandler">
+ /// </field>
+ /// <field name="_onChangeHandler" type="Sys.UI.DomEventHandler">
+ /// </field>
+ /// <field name="_onInputHandler" type="Sys.UI.DomEventHandler">
+ /// </field>
+ /// <field name="_onPropertyChangeHandler" type="Sys.UI.DomEventHandler">
+ /// </field>
+ /// <field name="_errors" type="Array">
+ /// </field>
+ /// <field name="defaultErrorMessage" type="String">
+ /// </field>
+ /// <field name="elements" type="Array" elementType="Object" elementDomElement="true">
+ /// </field>
+ /// <field name="formContext" type="Sys.Mvc.FormContext">
+ /// </field>
+ /// <field name="replaceValidationMessageContents" type="Boolean">
+ /// </field>
+ /// <field name="validationMessageElement" type="Object" domElement="true">
+ /// </field>
+ /// <field name="validations" type="Array" elementType="Validation">
+ /// </field>
+ this._errors = [];
+ this.elements = new Array(0);
+ this.validations = new Array(0);
+ this.formContext = formContext;
+ this._onBlurHandler = Function.createDelegate(this, this._element_OnBlur);
+ this._onChangeHandler = Function.createDelegate(this, this._element_OnChange);
+ this._onInputHandler = Function.createDelegate(this, this._element_OnInput);
+ this._onPropertyChangeHandler = Function.createDelegate(this, this._element_OnPropertyChange);
+}
+Sys.Mvc.FieldContext.prototype = {
+ _onBlurHandler: null,
+ _onChangeHandler: null,
+ _onInputHandler: null,
+ _onPropertyChangeHandler: null,
+ defaultErrorMessage: null,
+ formContext: null,
+ replaceValidationMessageContents: false,
+ validationMessageElement: null,
+
+ addError: function Sys_Mvc_FieldContext$addError(message) {
+ /// <param name="message" type="String">
+ /// </param>
+ this.addErrors([ message ]);
+ },
+
+ addErrors: function Sys_Mvc_FieldContext$addErrors(messages) {
+ /// <param name="messages" type="Array" elementType="String">
+ /// </param>
+ if (!Sys.Mvc._validationUtil.arrayIsNullOrEmpty(messages)) {
+ Array.addRange(this._errors, messages);
+ this._onErrorCountChanged();
+ }
+ },
+
+ clearErrors: function Sys_Mvc_FieldContext$clearErrors() {
+ Array.clear(this._errors);
+ this._onErrorCountChanged();
+ },
+
+ _displayError: function Sys_Mvc_FieldContext$_displayError() {
+ var validationMessageElement = this.validationMessageElement;
+ if (validationMessageElement) {
+ if (this.replaceValidationMessageContents) {
+ Sys.Mvc._validationUtil.setInnerText(validationMessageElement, this._errors[0]);
+ }
+ Sys.UI.DomElement.removeCssClass(validationMessageElement, Sys.Mvc.FieldContext._validationMessageValidCss);
+ Sys.UI.DomElement.addCssClass(validationMessageElement, Sys.Mvc.FieldContext._validationMessageErrorCss);
+ }
+ var elements = this.elements;
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ Sys.UI.DomElement.removeCssClass(element, Sys.Mvc.FieldContext._inputElementValidCss);
+ Sys.UI.DomElement.addCssClass(element, Sys.Mvc.FieldContext._inputElementErrorCss);
+ }
+ },
+
+ _displaySuccess: function Sys_Mvc_FieldContext$_displaySuccess() {
+ var validationMessageElement = this.validationMessageElement;
+ if (validationMessageElement) {
+ if (this.replaceValidationMessageContents) {
+ Sys.Mvc._validationUtil.setInnerText(validationMessageElement, '');
+ }
+ Sys.UI.DomElement.removeCssClass(validationMessageElement, Sys.Mvc.FieldContext._validationMessageErrorCss);
+ Sys.UI.DomElement.addCssClass(validationMessageElement, Sys.Mvc.FieldContext._validationMessageValidCss);
+ }
+ var elements = this.elements;
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ Sys.UI.DomElement.removeCssClass(element, Sys.Mvc.FieldContext._inputElementErrorCss);
+ Sys.UI.DomElement.addCssClass(element, Sys.Mvc.FieldContext._inputElementValidCss);
+ }
+ },
+
+ _element_OnBlur: function Sys_Mvc_FieldContext$_element_OnBlur(e) {
+ /// <param name="e" type="Sys.UI.DomEvent">
+ /// </param>
+ if (e.target[Sys.Mvc.FieldContext._hasTextChangedTag] || e.target[Sys.Mvc.FieldContext._hasValidationFiredTag]) {
+ this.validate('blur');
+ }
+ },
+
+ _element_OnChange: function Sys_Mvc_FieldContext$_element_OnChange(e) {
+ /// <param name="e" type="Sys.UI.DomEvent">
+ /// </param>
+ e.target[Sys.Mvc.FieldContext._hasTextChangedTag] = true;
+ },
+
+ _element_OnInput: function Sys_Mvc_FieldContext$_element_OnInput(e) {
+ /// <param name="e" type="Sys.UI.DomEvent">
+ /// </param>
+ e.target[Sys.Mvc.FieldContext._hasTextChangedTag] = true;
+ if (e.target[Sys.Mvc.FieldContext._hasValidationFiredTag]) {
+ this.validate('input');
+ }
+ },
+
+ _element_OnPropertyChange: function Sys_Mvc_FieldContext$_element_OnPropertyChange(e) {
+ /// <param name="e" type="Sys.UI.DomEvent">
+ /// </param>
+ if (e.rawEvent.propertyName === 'value') {
+ e.target[Sys.Mvc.FieldContext._hasTextChangedTag] = true;
+ if (e.target[Sys.Mvc.FieldContext._hasValidationFiredTag]) {
+ this.validate('input');
+ }
+ }
+ },
+
+ enableDynamicValidation: function Sys_Mvc_FieldContext$enableDynamicValidation() {
+ var elements = this.elements;
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ if (Sys.Mvc._validationUtil.elementSupportsEvent(element, 'onpropertychange')) {
+ var compatMode = document.documentMode;
+ if (compatMode && compatMode >= 8) {
+ Sys.UI.DomEvent.addHandler(element, 'propertychange', this._onPropertyChangeHandler);
+ }
+ }
+ else {
+ Sys.UI.DomEvent.addHandler(element, 'input', this._onInputHandler);
+ }
+ Sys.UI.DomEvent.addHandler(element, 'change', this._onChangeHandler);
+ Sys.UI.DomEvent.addHandler(element, 'blur', this._onBlurHandler);
+ }
+ },
+
+ _getErrorString: function Sys_Mvc_FieldContext$_getErrorString(validatorReturnValue, fieldErrorMessage) {
+ /// <param name="validatorReturnValue" type="Object">
+ /// </param>
+ /// <param name="fieldErrorMessage" type="String">
+ /// </param>
+ /// <returns type="String"></returns>
+ var fallbackErrorMessage = fieldErrorMessage || this.defaultErrorMessage;
+ if (Boolean.isInstanceOfType(validatorReturnValue)) {
+ return (validatorReturnValue) ? null : fallbackErrorMessage;
+ }
+ if (String.isInstanceOfType(validatorReturnValue)) {
+ return ((validatorReturnValue).length) ? validatorReturnValue : fallbackErrorMessage;
+ }
+ return null;
+ },
+
+ _getStringValue: function Sys_Mvc_FieldContext$_getStringValue() {
+ /// <returns type="String"></returns>
+ var elements = this.elements;
+ return (elements.length > 0) ? elements[0].value : null;
+ },
+
+ _markValidationFired: function Sys_Mvc_FieldContext$_markValidationFired() {
+ var elements = this.elements;
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ element[Sys.Mvc.FieldContext._hasValidationFiredTag] = true;
+ }
+ },
+
+ _onErrorCountChanged: function Sys_Mvc_FieldContext$_onErrorCountChanged() {
+ if (!this._errors.length) {
+ this._displaySuccess();
+ }
+ else {
+ this._displayError();
+ }
+ },
+
+ validate: function Sys_Mvc_FieldContext$validate(eventName) {
+ /// <param name="eventName" type="String">
+ /// </param>
+ /// <returns type="Array" elementType="String"></returns>
+ var validations = this.validations;
+ var errors = [];
+ var value = this._getStringValue();
+ for (var i = 0; i < validations.length; i++) {
+ var validation = validations[i];
+ var context = Sys.Mvc.$create_ValidationContext();
+ context.eventName = eventName;
+ context.fieldContext = this;
+ context.validation = validation;
+ var retVal = validation.validator(value, context);
+ var errorMessage = this._getErrorString(retVal, validation.fieldErrorMessage);
+ if (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(errorMessage)) {
+ Array.add(errors, errorMessage);
+ }
+ }
+ this._markValidationFired();
+ this.clearErrors();
+ this.addErrors(errors);
+ return errors;
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.RangeValidator
+
+Sys.Mvc.RangeValidator = function Sys_Mvc_RangeValidator(minimum, maximum) {
+ /// <param name="minimum" type="Number">
+ /// </param>
+ /// <param name="maximum" type="Number">
+ /// </param>
+ /// <field name="_minimum" type="Number">
+ /// </field>
+ /// <field name="_maximum" type="Number">
+ /// </field>
+ this._minimum = minimum;
+ this._maximum = maximum;
+}
+Sys.Mvc.RangeValidator.create = function Sys_Mvc_RangeValidator$create(rule) {
+ /// <param name="rule" type="Sys.Mvc.JsonValidationRule">
+ /// </param>
+ /// <returns type="Sys.Mvc.Validator"></returns>
+ var min = rule.ValidationParameters['minimum'];
+ var max = rule.ValidationParameters['maximum'];
+ return Function.createDelegate(new Sys.Mvc.RangeValidator(min, max), new Sys.Mvc.RangeValidator(min, max).validate);
+}
+Sys.Mvc.RangeValidator.prototype = {
+ _minimum: null,
+ _maximum: null,
+
+ validate: function Sys_Mvc_RangeValidator$validate(value, context) {
+ /// <param name="value" type="String">
+ /// </param>
+ /// <param name="context" type="Sys.Mvc.ValidationContext">
+ /// </param>
+ /// <returns type="Object"></returns>
+ if (Sys.Mvc._validationUtil.stringIsNullOrEmpty(value)) {
+ return true;
+ }
+ var n = Number.parseLocale(value);
+ return (!isNaN(n) && this._minimum <= n && n <= this._maximum);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.RegularExpressionValidator
+
+Sys.Mvc.RegularExpressionValidator = function Sys_Mvc_RegularExpressionValidator(pattern) {
+ /// <param name="pattern" type="String">
+ /// </param>
+ /// <field name="_pattern" type="String">
+ /// </field>
+ this._pattern = pattern;
+}
+Sys.Mvc.RegularExpressionValidator.create = function Sys_Mvc_RegularExpressionValidator$create(rule) {
+ /// <param name="rule" type="Sys.Mvc.JsonValidationRule">
+ /// </param>
+ /// <returns type="Sys.Mvc.Validator"></returns>
+ var pattern = rule.ValidationParameters['pattern'];
+ return Function.createDelegate(new Sys.Mvc.RegularExpressionValidator(pattern), new Sys.Mvc.RegularExpressionValidator(pattern).validate);
+}
+Sys.Mvc.RegularExpressionValidator.prototype = {
+ _pattern: null,
+
+ validate: function Sys_Mvc_RegularExpressionValidator$validate(value, context) {
+ /// <param name="value" type="String">
+ /// </param>
+ /// <param name="context" type="Sys.Mvc.ValidationContext">
+ /// </param>
+ /// <returns type="Object"></returns>
+ if (Sys.Mvc._validationUtil.stringIsNullOrEmpty(value)) {
+ return true;
+ }
+ var regExp = new RegExp(this._pattern);
+ var matches = regExp.exec(value);
+ return (!Sys.Mvc._validationUtil.arrayIsNullOrEmpty(matches) && matches[0].length === value.length);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.RequiredValidator
+
+Sys.Mvc.RequiredValidator = function Sys_Mvc_RequiredValidator() {
+}
+Sys.Mvc.RequiredValidator.create = function Sys_Mvc_RequiredValidator$create(rule) {
+ /// <param name="rule" type="Sys.Mvc.JsonValidationRule">
+ /// </param>
+ /// <returns type="Sys.Mvc.Validator"></returns>
+ return Function.createDelegate(new Sys.Mvc.RequiredValidator(), new Sys.Mvc.RequiredValidator().validate);
+}
+Sys.Mvc.RequiredValidator._isRadioInputElement = function Sys_Mvc_RequiredValidator$_isRadioInputElement(element) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ /// <returns type="Boolean"></returns>
+ if (element.tagName.toUpperCase() === 'INPUT') {
+ var inputType = (element.type).toUpperCase();
+ if (inputType === 'RADIO') {
+ return true;
+ }
+ }
+ return false;
+}
+Sys.Mvc.RequiredValidator._isSelectInputElement = function Sys_Mvc_RequiredValidator$_isSelectInputElement(element) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ /// <returns type="Boolean"></returns>
+ if (element.tagName.toUpperCase() === 'SELECT') {
+ return true;
+ }
+ return false;
+}
+Sys.Mvc.RequiredValidator._isTextualInputElement = function Sys_Mvc_RequiredValidator$_isTextualInputElement(element) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ /// <returns type="Boolean"></returns>
+ if (element.tagName.toUpperCase() === 'INPUT') {
+ var inputType = (element.type).toUpperCase();
+ switch (inputType) {
+ case 'TEXT':
+ case 'PASSWORD':
+ case 'FILE':
+ return true;
+ }
+ }
+ if (element.tagName.toUpperCase() === 'TEXTAREA') {
+ return true;
+ }
+ return false;
+}
+Sys.Mvc.RequiredValidator._validateRadioInput = function Sys_Mvc_RequiredValidator$_validateRadioInput(elements) {
+ /// <param name="elements" type="Array" elementType="Object" elementDomElement="true">
+ /// </param>
+ /// <returns type="Object"></returns>
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ if (element.checked) {
+ return true;
+ }
+ }
+ return false;
+}
+Sys.Mvc.RequiredValidator._validateSelectInput = function Sys_Mvc_RequiredValidator$_validateSelectInput(optionElements) {
+ /// <param name="optionElements" type="DOMElementCollection">
+ /// </param>
+ /// <returns type="Object"></returns>
+ for (var i = 0; i < optionElements.length; i++) {
+ var element = optionElements[i];
+ if (element.selected) {
+ if (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(element.value)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+Sys.Mvc.RequiredValidator._validateTextualInput = function Sys_Mvc_RequiredValidator$_validateTextualInput(element) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ /// <returns type="Object"></returns>
+ return (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(element.value));
+}
+Sys.Mvc.RequiredValidator.prototype = {
+
+ validate: function Sys_Mvc_RequiredValidator$validate(value, context) {
+ /// <param name="value" type="String">
+ /// </param>
+ /// <param name="context" type="Sys.Mvc.ValidationContext">
+ /// </param>
+ /// <returns type="Object"></returns>
+ var elements = context.fieldContext.elements;
+ if (!elements.length) {
+ return true;
+ }
+ var sampleElement = elements[0];
+ if (Sys.Mvc.RequiredValidator._isTextualInputElement(sampleElement)) {
+ return Sys.Mvc.RequiredValidator._validateTextualInput(sampleElement);
+ }
+ if (Sys.Mvc.RequiredValidator._isRadioInputElement(sampleElement)) {
+ return Sys.Mvc.RequiredValidator._validateRadioInput(elements);
+ }
+ if (Sys.Mvc.RequiredValidator._isSelectInputElement(sampleElement)) {
+ return Sys.Mvc.RequiredValidator._validateSelectInput((sampleElement).options);
+ }
+ return true;
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.StringLengthValidator
+
+Sys.Mvc.StringLengthValidator = function Sys_Mvc_StringLengthValidator(minLength, maxLength) {
+ /// <param name="minLength" type="Number" integer="true">
+ /// </param>
+ /// <param name="maxLength" type="Number" integer="true">
+ /// </param>
+ /// <field name="_maxLength" type="Number" integer="true">
+ /// </field>
+ /// <field name="_minLength" type="Number" integer="true">
+ /// </field>
+ this._minLength = minLength;
+ this._maxLength = maxLength;
+}
+Sys.Mvc.StringLengthValidator.create = function Sys_Mvc_StringLengthValidator$create(rule) {
+ /// <param name="rule" type="Sys.Mvc.JsonValidationRule">
+ /// </param>
+ /// <returns type="Sys.Mvc.Validator"></returns>
+ var minLength = rule.ValidationParameters['minimumLength'];
+ var maxLength = rule.ValidationParameters['maximumLength'];
+ return Function.createDelegate(new Sys.Mvc.StringLengthValidator(minLength, maxLength), new Sys.Mvc.StringLengthValidator(minLength, maxLength).validate);
+}
+Sys.Mvc.StringLengthValidator.prototype = {
+ _maxLength: 0,
+ _minLength: 0,
+
+ validate: function Sys_Mvc_StringLengthValidator$validate(value, context) {
+ /// <param name="value" type="String">
+ /// </param>
+ /// <param name="context" type="Sys.Mvc.ValidationContext">
+ /// </param>
+ /// <returns type="Object"></returns>
+ if (Sys.Mvc._validationUtil.stringIsNullOrEmpty(value)) {
+ return true;
+ }
+ return (this._minLength <= value.length && value.length <= this._maxLength);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc._validationUtil
+
+Sys.Mvc._validationUtil = function Sys_Mvc__validationUtil() {
+}
+Sys.Mvc._validationUtil.arrayIsNullOrEmpty = function Sys_Mvc__validationUtil$arrayIsNullOrEmpty(array) {
+ /// <param name="array" type="Array" elementType="Object">
+ /// </param>
+ /// <returns type="Boolean"></returns>
+ return (!array || !array.length);
+}
+Sys.Mvc._validationUtil.stringIsNullOrEmpty = function Sys_Mvc__validationUtil$stringIsNullOrEmpty(value) {
+ /// <param name="value" type="String">
+ /// </param>
+ /// <returns type="Boolean"></returns>
+ return (!value || !value.length);
+}
+Sys.Mvc._validationUtil.elementSupportsEvent = function Sys_Mvc__validationUtil$elementSupportsEvent(element, eventAttributeName) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ /// <param name="eventAttributeName" type="String">
+ /// </param>
+ /// <returns type="Boolean"></returns>
+ return (eventAttributeName in element);
+}
+Sys.Mvc._validationUtil.removeAllChildren = function Sys_Mvc__validationUtil$removeAllChildren(element) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+}
+Sys.Mvc._validationUtil.setInnerText = function Sys_Mvc__validationUtil$setInnerText(element, innerText) {
+ /// <param name="element" type="Object" domElement="true">
+ /// </param>
+ /// <param name="innerText" type="String">
+ /// </param>
+ var textNode = document.createTextNode(innerText);
+ Sys.Mvc._validationUtil.removeAllChildren(element);
+ element.appendChild(textNode);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Sys.Mvc.ValidatorRegistry
+
+Sys.Mvc.ValidatorRegistry = function Sys_Mvc_ValidatorRegistry() {
+ /// <field name="validators" type="Object" static="true">
+ /// </field>
+}
+Sys.Mvc.ValidatorRegistry.getValidator = function Sys_Mvc_ValidatorRegistry$getValidator(rule) {
+ /// <param name="rule" type="Sys.Mvc.JsonValidationRule">
+ /// </param>
+ /// <returns type="Sys.Mvc.Validator"></returns>
+ var creator = Sys.Mvc.ValidatorRegistry.validators[rule.ValidationType];
+ return (creator) ? creator(rule) : null;
+}
+Sys.Mvc.ValidatorRegistry._getDefaultValidators = function Sys_Mvc_ValidatorRegistry$_getDefaultValidators() {
+ /// <returns type="Object"></returns>
+ return { required: Function.createDelegate(null, Sys.Mvc.RequiredValidator.create), stringLength: Function.createDelegate(null, Sys.Mvc.StringLengthValidator.create), regularExpression: Function.createDelegate(null, Sys.Mvc.RegularExpressionValidator.create), range: Function.createDelegate(null, Sys.Mvc.RangeValidator.create), number: Function.createDelegate(null, Sys.Mvc.NumberValidator.create) };
+}
+
+
+Sys.Mvc.NumberValidator.registerClass('Sys.Mvc.NumberValidator');
+Sys.Mvc.FormContext.registerClass('Sys.Mvc.FormContext');
+Sys.Mvc.FieldContext.registerClass('Sys.Mvc.FieldContext');
+Sys.Mvc.RangeValidator.registerClass('Sys.Mvc.RangeValidator');
+Sys.Mvc.RegularExpressionValidator.registerClass('Sys.Mvc.RegularExpressionValidator');
+Sys.Mvc.RequiredValidator.registerClass('Sys.Mvc.RequiredValidator');
+Sys.Mvc.StringLengthValidator.registerClass('Sys.Mvc.StringLengthValidator');
+Sys.Mvc._validationUtil.registerClass('Sys.Mvc._validationUtil');
+Sys.Mvc.ValidatorRegistry.registerClass('Sys.Mvc.ValidatorRegistry');
+Sys.Mvc.FormContext._validationSummaryErrorCss = 'validation-summary-errors';
+Sys.Mvc.FormContext._validationSummaryValidCss = 'validation-summary-valid';
+Sys.Mvc.FormContext._formValidationTag = '__MVC_FormValidation';
+Sys.Mvc.FieldContext._hasTextChangedTag = '__MVC_HasTextChanged';
+Sys.Mvc.FieldContext._hasValidationFiredTag = '__MVC_HasValidationFired';
+Sys.Mvc.FieldContext._inputElementErrorCss = 'input-validation-error';
+Sys.Mvc.FieldContext._inputElementValidCss = 'input-validation-valid';
+Sys.Mvc.FieldContext._validationMessageErrorCss = 'field-validation-error';
+Sys.Mvc.FieldContext._validationMessageValidCss = 'field-validation-valid';
+Sys.Mvc.ValidatorRegistry.validators = Sys.Mvc.ValidatorRegistry._getDefaultValidators();
+
+// ---- Do not remove this footer ----
+// Generated using Script# v0.5.0.0 (http://projects.nikhilk.net)
+// -----------------------------------
+
+// register validation
+Sys.Application.add_load(function() {
+ Sys.Application.remove_load(arguments.callee);
+ Sys.Mvc.FormContext._Application_Load();
+});
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcValidation.js b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcValidation.js
new file mode 100644
index 0000000..2d1789d
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/MicrosoftMvcValidation.js
@@ -0,0 +1,55 @@
+//----------------------------------------------------------
+// Copyright (C) Microsoft Corporation. All rights reserved.
+//----------------------------------------------------------
+// MicrosoftMvcValidation.js
+
+Type.registerNamespace('Sys.Mvc');Sys.Mvc.$create_Validation=function(){return {};}
+Sys.Mvc.$create_JsonValidationField=function(){return {};}
+Sys.Mvc.$create_JsonValidationOptions=function(){return {};}
+Sys.Mvc.$create_JsonValidationRule=function(){return {};}
+Sys.Mvc.$create_ValidationContext=function(){return {};}
+Sys.Mvc.NumberValidator=function(){}
+Sys.Mvc.NumberValidator.create=function(rule){return Function.createDelegate(new Sys.Mvc.NumberValidator(),new Sys.Mvc.NumberValidator().validate);}
+Sys.Mvc.NumberValidator.prototype={validate:function(value,context){if(Sys.Mvc._ValidationUtil.$1(value)){return true;}var $0=Number.parseLocale(value);return (!isNaN($0));}}
+Sys.Mvc.FormContext=function(formElement,validationSummaryElement){this.$5=[];this.fields=new Array(0);this.$9=formElement;this.$7=validationSummaryElement;formElement['__MVC_FormValidation'] = this;if(validationSummaryElement){var $0=validationSummaryElement.getElementsByTagName('ul');if($0.length>0){this.$8=$0[0];}}this.$3=Function.createDelegate(this,this.$D);this.$4=Function.createDelegate(this,this.$E);}
+Sys.Mvc.FormContext._Application_Load=function(){var $0=window.mvcClientValidationMetadata;if($0){while($0.length>0){var $1=$0.pop();Sys.Mvc.FormContext.$12($1);}}}
+Sys.Mvc.FormContext.$F=function($p0,$p1){var $0=[];var $1=document.getElementsByName($p1);for(var $2=0;$2<$1.length;$2++){var $3=$1[$2];if(Sys.Mvc.FormContext.$10($p0,$3)){Array.add($0,$3);}}return $0;}
+Sys.Mvc.FormContext.getValidationForForm=function(formElement){return formElement['__MVC_FormValidation'];}
+Sys.Mvc.FormContext.$10=function($p0,$p1){while($p1){if($p0===$p1){return true;}$p1=$p1.parentNode;}return false;}
+Sys.Mvc.FormContext.$12=function($p0){var $0=$get($p0.FormId);var $1=(!Sys.Mvc._ValidationUtil.$1($p0.ValidationSummaryId))?$get($p0.ValidationSummaryId):null;var $2=new Sys.Mvc.FormContext($0,$1);$2.enableDynamicValidation();$2.replaceValidationSummary=$p0.ReplaceValidationSummary;for(var $4=0;$4<$p0.Fields.length;$4++){var $5=$p0.Fields[$4];var $6=Sys.Mvc.FormContext.$F($0,$5.FieldName);var $7=(!Sys.Mvc._ValidationUtil.$1($5.ValidationMessageId))?$get($5.ValidationMessageId):null;var $8=new Sys.Mvc.FieldContext($2);Array.addRange($8.elements,$6);$8.validationMessageElement=$7;$8.replaceValidationMessageContents=$5.ReplaceValidationMessageContents;for(var $9=0;$9<$5.ValidationRules.length;$9++){var $A=$5.ValidationRules[$9];var $B=Sys.Mvc.ValidatorRegistry.getValidator($A);if($B){var $C=Sys.Mvc.$create_Validation();$C.fieldErrorMessage=$A.ErrorMessage;$C.validator=$B;Array.add($8.validations,$C);}}$8.enableDynamicValidation();Array.add($2.fields,$8);}var $3=$0.validationCallbacks;if(!$3){$3=[];$0.validationCallbacks = $3;}$3.push(Function.createDelegate(null,function(){
+return Sys.Mvc._ValidationUtil.$0($2.validate('submit'));}));return $2;}
+Sys.Mvc.FormContext.prototype={$3:null,$4:null,$6:null,$7:null,$8:null,$9:null,replaceValidationSummary:false,addError:function(message){this.addErrors([message]);},addErrors:function(messages){if(!Sys.Mvc._ValidationUtil.$0(messages)){Array.addRange(this.$5,messages);this.$11();}},clearErrors:function(){Array.clear(this.$5);this.$11();},$A:function(){if(this.$7){if(this.$8){Sys.Mvc._ValidationUtil.$3(this.$8);for(var $0=0;$0<this.$5.length;$0++){var $1=document.createElement('li');Sys.Mvc._ValidationUtil.$4($1,this.$5[$0]);this.$8.appendChild($1);}}Sys.UI.DomElement.removeCssClass(this.$7,'validation-summary-valid');Sys.UI.DomElement.addCssClass(this.$7,'validation-summary-errors');}},$B:function(){var $0=this.$7;if($0){var $1=this.$8;if($1){$1.innerHTML='';}Sys.UI.DomElement.removeCssClass($0,'validation-summary-errors');Sys.UI.DomElement.addCssClass($0,'validation-summary-valid');}},enableDynamicValidation:function(){Sys.UI.DomEvent.addHandler(this.$9,'click',this.$3);Sys.UI.DomEvent.addHandler(this.$9,'submit',this.$4);},$C:function($p0){if($p0.disabled){return null;}var $0=$p0.tagName.toUpperCase();var $1=$p0;if($0==='INPUT'){var $2=$1.type;if($2==='submit'||$2==='image'){return $1;}}else if(($0==='BUTTON')&&($1.type==='submit')){return $1;}return null;},$D:function($p0){this.$6=this.$C($p0.target);},$E:function($p0){var $0=$p0.target;var $1=this.$6;if($1&&$1.disableValidation){return;}var $2=this.validate('submit');if(!Sys.Mvc._ValidationUtil.$0($2)){$p0.preventDefault();}},$11:function(){if(!this.$5.length){this.$B();}else{this.$A();}},validate:function(eventName){var $0=this.fields;var $1=[];for(var $2=0;$2<$0.length;$2++){var $3=$0[$2];var $4=$3.validate(eventName);if($4){Array.addRange($1,$4);}}if(this.replaceValidationSummary){this.clearErrors();this.addErrors($1);}return $1;}}
+Sys.Mvc.FieldContext=function(formContext){this.$A=[];this.elements=new Array(0);this.validations=new Array(0);this.formContext=formContext;this.$6=Function.createDelegate(this,this.$D);this.$7=Function.createDelegate(this,this.$E);this.$8=Function.createDelegate(this,this.$F);this.$9=Function.createDelegate(this,this.$10);}
+Sys.Mvc.FieldContext.prototype={$6:null,$7:null,$8:null,$9:null,defaultErrorMessage:null,formContext:null,replaceValidationMessageContents:false,validationMessageElement:null,addError:function(message){this.addErrors([message]);},addErrors:function(messages){if(!Sys.Mvc._ValidationUtil.$0(messages)){Array.addRange(this.$A,messages);this.$14();}},clearErrors:function(){Array.clear(this.$A);this.$14();},$B:function(){var $0=this.validationMessageElement;if($0){if(this.replaceValidationMessageContents){Sys.Mvc._ValidationUtil.$4($0,this.$A[0]);}Sys.UI.DomElement.removeCssClass($0,'field-validation-valid');Sys.UI.DomElement.addCssClass($0,'field-validation-error');}var $1=this.elements;for(var $2=0;$2<$1.length;$2++){var $3=$1[$2];Sys.UI.DomElement.removeCssClass($3,'input-validation-valid');Sys.UI.DomElement.addCssClass($3,'input-validation-error');}},$C:function(){var $0=this.validationMessageElement;if($0){if(this.replaceValidationMessageContents){Sys.Mvc._ValidationUtil.$4($0,'');}Sys.UI.DomElement.removeCssClass($0,'field-validation-error');Sys.UI.DomElement.addCssClass($0,'field-validation-valid');}var $1=this.elements;for(var $2=0;$2<$1.length;$2++){var $3=$1[$2];Sys.UI.DomElement.removeCssClass($3,'input-validation-error');Sys.UI.DomElement.addCssClass($3,'input-validation-valid');}},$D:function($p0){if($p0.target['__MVC_HasTextChanged']||$p0.target['__MVC_HasValidationFired']){this.validate('blur');}},$E:function($p0){$p0.target['__MVC_HasTextChanged'] = true;},$F:function($p0){$p0.target['__MVC_HasTextChanged'] = true;if($p0.target['__MVC_HasValidationFired']){this.validate('input');}},$10:function($p0){if($p0.rawEvent.propertyName==='value'){$p0.target['__MVC_HasTextChanged'] = true;if($p0.target['__MVC_HasValidationFired']){this.validate('input');}}},enableDynamicValidation:function(){var $0=this.elements;for(var $1=0;$1<$0.length;$1++){var $2=$0[$1];if(Sys.Mvc._ValidationUtil.$2($2,'onpropertychange')){var $3=document.documentMode;if($3&&$3>=8){Sys.UI.DomEvent.addHandler($2,'propertychange',this.$9);}}else{Sys.UI.DomEvent.addHandler($2,'input',this.$8);}Sys.UI.DomEvent.addHandler($2,'change',this.$7);Sys.UI.DomEvent.addHandler($2,'blur',this.$6);}},$11:function($p0,$p1){var $0=$p1||this.defaultErrorMessage;if(Boolean.isInstanceOfType($p0)){return ($p0)?null:$0;}if(String.isInstanceOfType($p0)){return (($p0).length)?$p0:$0;}return null;},$12:function(){var $0=this.elements;return ($0.length>0)?$0[0].value:null;},$13:function(){var $0=this.elements;for(var $1=0;$1<$0.length;$1++){var $2=$0[$1];$2['__MVC_HasValidationFired'] = true;}},$14:function(){if(!this.$A.length){this.$C();}else{this.$B();}},validate:function(eventName){var $0=this.validations;var $1=[];var $2=this.$12();for(var $3=0;$3<$0.length;$3++){var $4=$0[$3];var $5=Sys.Mvc.$create_ValidationContext();$5.eventName=eventName;$5.fieldContext=this;$5.validation=$4;var $6=$4.validator($2,$5);var $7=this.$11($6,$4.fieldErrorMessage);if(!Sys.Mvc._ValidationUtil.$1($7)){Array.add($1,$7);}}this.$13();this.clearErrors();this.addErrors($1);return $1;}}
+Sys.Mvc.RangeValidator=function(minimum,maximum){this.$0=minimum;this.$1=maximum;}
+Sys.Mvc.RangeValidator.create=function(rule){var $0=rule.ValidationParameters['minimum'];var $1=rule.ValidationParameters['maximum'];return Function.createDelegate(new Sys.Mvc.RangeValidator($0,$1),new Sys.Mvc.RangeValidator($0,$1).validate);}
+Sys.Mvc.RangeValidator.prototype={$0:null,$1:null,validate:function(value,context){if(Sys.Mvc._ValidationUtil.$1(value)){return true;}var $0=Number.parseLocale(value);return (!isNaN($0)&&this.$0<=$0&&$0<=this.$1);}}
+Sys.Mvc.RegularExpressionValidator=function(pattern){this.$0=pattern;}
+Sys.Mvc.RegularExpressionValidator.create=function(rule){var $0=rule.ValidationParameters['pattern'];return Function.createDelegate(new Sys.Mvc.RegularExpressionValidator($0),new Sys.Mvc.RegularExpressionValidator($0).validate);}
+Sys.Mvc.RegularExpressionValidator.prototype={$0:null,validate:function(value,context){if(Sys.Mvc._ValidationUtil.$1(value)){return true;}var $0=new RegExp(this.$0);var $1=$0.exec(value);return (!Sys.Mvc._ValidationUtil.$0($1)&&$1[0].length===value.length);}}
+Sys.Mvc.RequiredValidator=function(){}
+Sys.Mvc.RequiredValidator.create=function(rule){return Function.createDelegate(new Sys.Mvc.RequiredValidator(),new Sys.Mvc.RequiredValidator().validate);}
+Sys.Mvc.RequiredValidator.$0=function($p0){if($p0.tagName.toUpperCase()==='INPUT'){var $0=($p0.type).toUpperCase();if($0==='RADIO'){return true;}}return false;}
+Sys.Mvc.RequiredValidator.$1=function($p0){if($p0.tagName.toUpperCase()==='SELECT'){return true;}return false;}
+Sys.Mvc.RequiredValidator.$2=function($p0){if($p0.tagName.toUpperCase()==='INPUT'){var $0=($p0.type).toUpperCase();switch($0){case 'TEXT':case 'PASSWORD':case 'FILE':return true;}}if($p0.tagName.toUpperCase()==='TEXTAREA'){return true;}return false;}
+Sys.Mvc.RequiredValidator.$3=function($p0){for(var $0=0;$0<$p0.length;$0++){var $1=$p0[$0];if($1.checked){return true;}}return false;}
+Sys.Mvc.RequiredValidator.$4=function($p0){for(var $0=0;$0<$p0.length;$0++){var $1=$p0[$0];if($1.selected){if(!Sys.Mvc._ValidationUtil.$1($1.value)){return true;}}}return false;}
+Sys.Mvc.RequiredValidator.$5=function($p0){return (!Sys.Mvc._ValidationUtil.$1($p0.value));}
+Sys.Mvc.RequiredValidator.prototype={validate:function(value,context){var $0=context.fieldContext.elements;if(!$0.length){return true;}var $1=$0[0];if(Sys.Mvc.RequiredValidator.$2($1)){return Sys.Mvc.RequiredValidator.$5($1);}if(Sys.Mvc.RequiredValidator.$0($1)){return Sys.Mvc.RequiredValidator.$3($0);}if(Sys.Mvc.RequiredValidator.$1($1)){return Sys.Mvc.RequiredValidator.$4(($1).options);}return true;}}
+Sys.Mvc.StringLengthValidator=function(minLength,maxLength){this.$1=minLength;this.$0=maxLength;}
+Sys.Mvc.StringLengthValidator.create=function(rule){var $0=rule.ValidationParameters['minimumLength'];var $1=rule.ValidationParameters['maximumLength'];return Function.createDelegate(new Sys.Mvc.StringLengthValidator($0,$1),new Sys.Mvc.StringLengthValidator($0,$1).validate);}
+Sys.Mvc.StringLengthValidator.prototype={$0:0,$1:0,validate:function(value,context){if(Sys.Mvc._ValidationUtil.$1(value)){return true;}return (this.$1<=value.length&&value.length<=this.$0);}}
+Sys.Mvc._ValidationUtil=function(){}
+Sys.Mvc._ValidationUtil.$0=function($p0){return (!$p0||!$p0.length);}
+Sys.Mvc._ValidationUtil.$1=function($p0){return (!$p0||!$p0.length);}
+Sys.Mvc._ValidationUtil.$2=function($p0,$p1){return ($p1 in $p0);}
+Sys.Mvc._ValidationUtil.$3=function($p0){while($p0.firstChild){$p0.removeChild($p0.firstChild);}}
+Sys.Mvc._ValidationUtil.$4=function($p0,$p1){var $0=document.createTextNode($p1);Sys.Mvc._ValidationUtil.$3($p0);$p0.appendChild($0);}
+Sys.Mvc.ValidatorRegistry=function(){}
+Sys.Mvc.ValidatorRegistry.getValidator=function(rule){var $0=Sys.Mvc.ValidatorRegistry.validators[rule.ValidationType];return ($0)?$0(rule):null;}
+Sys.Mvc.ValidatorRegistry.$0=function(){return {required:Function.createDelegate(null,Sys.Mvc.RequiredValidator.create),stringLength:Function.createDelegate(null,Sys.Mvc.StringLengthValidator.create),regularExpression:Function.createDelegate(null,Sys.Mvc.RegularExpressionValidator.create),range:Function.createDelegate(null,Sys.Mvc.RangeValidator.create),number:Function.createDelegate(null,Sys.Mvc.NumberValidator.create)};}
+Sys.Mvc.NumberValidator.registerClass('Sys.Mvc.NumberValidator');Sys.Mvc.FormContext.registerClass('Sys.Mvc.FormContext');Sys.Mvc.FieldContext.registerClass('Sys.Mvc.FieldContext');Sys.Mvc.RangeValidator.registerClass('Sys.Mvc.RangeValidator');Sys.Mvc.RegularExpressionValidator.registerClass('Sys.Mvc.RegularExpressionValidator');Sys.Mvc.RequiredValidator.registerClass('Sys.Mvc.RequiredValidator');Sys.Mvc.StringLengthValidator.registerClass('Sys.Mvc.StringLengthValidator');Sys.Mvc._ValidationUtil.registerClass('Sys.Mvc._ValidationUtil');Sys.Mvc.ValidatorRegistry.registerClass('Sys.Mvc.ValidatorRegistry');Sys.Mvc.ValidatorRegistry.validators=Sys.Mvc.ValidatorRegistry.$0();
+// ---- Do not remove this footer ----
+// Generated using Script# v0.5.0.0 (http://projects.nikhilk.net)
+// -----------------------------------
+Sys.Application.add_load(function(){Sys.Application.remove_load(arguments.callee);Sys.Mvc.FormContext._Application_Load();}); \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1-vsdoc.js b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1-vsdoc.js
new file mode 100644
index 0000000..681241d
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1-vsdoc.js
@@ -0,0 +1,8061 @@
+/*
+ * This file has been commented to support Visual Studio Intellisense.
+ * You should not use this file at runtime inside the browser--it is only
+ * intended to be used only for design-time IntelliSense. Please use the
+ * standard jQuery library for all production use.
+ *
+ * Comment version: 1.4.1a
+ */
+
+/*!
+ * jQuery JavaScript Library v1.4.1
+ * http://jquery.com/
+ *
+ * Distributed in whole under the terms of the MIT
+ *
+ * Copyright 2010, John Resig
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Jan 25 19:43:33 2010 -0500
+ */
+
+(function( window, undefined ) {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ /// <summary>
+ /// 1: $(expression, context) - This function accepts a string containing a CSS selector which is then used to match a set of elements.
+ /// 2: $(html) - Create DOM elements on-the-fly from the provided String of raw HTML.
+ /// 3: $(elements) - Wrap jQuery functionality around a single or multiple DOM Element(s).
+ /// 4: $(callback) - A shorthand for $(document).ready().
+ /// 5: $() - As of jQuery 1.4, if you pass no arguments in to the jQuery() method, an empty jQuery set will be returned.
+ /// </summary>
+ /// <param name="selector" type="String">
+ /// 1: expression - An expression to search with.
+ /// 2: html - A string of HTML to create on the fly.
+ /// 3: elements - DOM element(s) to be encapsulated by a jQuery object.
+ /// 4: callback - The function to execute when the DOM is ready.
+ /// </param>
+ /// <param name="context" type="jQuery">
+ /// 1: context - A DOM Element, Document or jQuery to use as context.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // Use the correct document accordingly with window argument (sandbox)
+ document = window.document,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
+
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // Has the ready events already been bound?
+ readyBound = false,
+
+ // The functions to execute on DOM ready
+ readyList = [],
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwnProperty = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ indexOf = Array.prototype.indexOf;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+ }
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ if ( elem ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $("TAG")
+ } else if ( !context && /^\w+$/.test( selector ) ) {
+ this.selector = selector;
+ this.context = document;
+ selector = document.getElementsByTagName( selector );
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return jQuery( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.isArray( selector ) ?
+ this.setArray( selector ) :
+ jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.4.1",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ /// <summary>
+ /// The number of elements currently matched.
+ /// Part of Core
+ /// </summary>
+ /// <returns type="Number" />
+
+ return this.length;
+ },
+
+ toArray: function() {
+ /// <summary>
+ /// Retrieve all the DOM elements contained in the jQuery set, as an array.
+ /// </summary>
+ /// <returns type="Array" />
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ /// <summary>
+ /// Access a single matched element. num is used to access the
+ /// Nth element matched.
+ /// Part of Core
+ /// </summary>
+ /// <returns type="Element" />
+ /// <param name="num" type="Number">
+ /// Access the element in the Nth position.
+ /// </param>
+
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ /// <summary>
+ /// Set the jQuery object to an array of elements, while maintaining
+ /// the stack.
+ /// Part of Core
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="elems" type="Elements">
+ /// An array of elements
+ /// </param>
+
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems || null );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ /// <summary>
+ /// Set the jQuery object to an array of elements. This operation is
+ /// completely destructive - be sure to use .pushStack() if you wish to maintain
+ /// the jQuery stack.
+ /// Part of Core
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="elems" type="Elements">
+ /// An array of elements
+ /// </param>
+
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ /// <summary>
+ /// Execute a function within the context of every matched element.
+ /// This means that every time the passed-in function is executed
+ /// (which is once for every element matched) the 'this' keyword
+ /// points to the specific element.
+ /// Additionally, the function, when executed, is passed a single
+ /// argument representing the position of the element in the matched
+ /// set.
+ /// Part of Core
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="callback" type="Function">
+ /// A function to execute
+ /// </param>
+
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ /// <summary>
+ /// Binds a function to be executed whenever the DOM is ready to be traversed and manipulated.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to be executed when the DOM is ready.</param>
+
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady ) {
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ } else if ( readyList ) {
+ // Add the function to the wait list
+ readyList.push( fn );
+ }
+
+ return this;
+ },
+
+ eq: function( i ) {
+ /// <summary>
+ /// Reduce the set of matched elements to a single element.
+ /// The position of the element in the set of matched elements
+ /// starts at 0 and goes to length - 1.
+ /// Part of Core
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="num" type="Number">
+ /// pos The index of the element that you wish to limit to.
+ /// </param>
+
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
+ },
+
+ first: function() {
+ /// <summary>
+ /// Reduce the set of matched elements to the first in the set.
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ /// <summary>
+ /// Reduce the set of matched elements to the final one in the set.
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ /// <summary>
+ /// Selects a subset of the matched elements. Behaves exactly like the built-in Array slice method.
+ /// </summary>
+ /// <param name="start" type="Number" integer="true">Where to start the subset (0-based).</param>
+ /// <param name="end" optional="true" type="Number" integer="true">Where to end the subset (not including the end element itself).
+ /// If omitted, ends at the end of the selection</param>
+ /// <returns type="jQuery">The sliced elements</returns>
+
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ /// <summary>
+ /// This member is internal.
+ /// </summary>
+ /// <private />
+ /// <returns type="jQuery" />
+
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ /// <summary>
+ /// End the most recent 'destructive' operation, reverting the list of matched elements
+ /// back to its previous state. After an end operation, the list of matched elements will
+ /// revert to the last state of matched elements.
+ /// If there was no destructive operation before, an empty set is returned.
+ /// Part of DOM/Traversing
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ return this.prevObject || jQuery(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ /// <summary>
+ /// Extend one object with one or more others, returning the original,
+ /// modified, object. This is a great utility for simple inheritance.
+ /// jQuery.extend(settings, options);
+ /// var settings = jQuery.extend({}, defaults, options);
+ /// Part of JavaScript
+ /// </summary>
+ /// <param name="target" type="Object">
+ /// The object to extend
+ /// </param>
+ /// <param name="prop1" type="Object">
+ /// The object that will be merged into the first.
+ /// </param>
+ /// <param name="propN" type="Object" optional="true" parameterArray="true">
+ /// (optional) More objects to merge into the first
+ /// </param>
+ /// <returns type="Object" />
+
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging object literal values or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
+ var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
+ : jQuery.isArray(copy) ? [] : {};
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ /// <summary>
+ /// Run this function to give control of the $ variable back
+ /// to whichever library first implemented it. This helps to make
+ /// sure that jQuery doesn't conflict with the $ object
+ /// of other libraries.
+ /// By using this function, you will only be able to access jQuery
+ /// using the 'jQuery' variable. For example, where you used to do
+ /// $(&quot;div p&quot;), you now must do jQuery(&quot;div p&quot;).
+ /// Part of Core
+ /// </summary>
+ /// <returns type="undefined" />
+
+ window.$ = _$;
+
+ if ( deep ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // Handle when the DOM is ready
+ ready: function() {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 13 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( readyList ) {
+ // Execute all of them
+ var fn, i = 0;
+ while ( (fn = readyList[ i++ ]) ) {
+ fn.call( document, jQuery );
+ }
+
+ // Reset the list of functions
+ readyList = null;
+ }
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.triggerHandler ) {
+ jQuery( document ).triggerHandler( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyBound ) {
+ return;
+ }
+
+ readyBound = true;
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ return jQuery.ready();
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", DOMContentLoaded);
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ /// <summary>
+ /// Determines if the parameter passed is a function.
+ /// </summary>
+ /// <param name="obj" type="Object">The object to check</param>
+ /// <returns type="Boolean">True if the parameter is a function; otherwise false.</returns>
+
+ return toString.call(obj) === "[object Function]";
+ },
+
+ isArray: function( obj ) {
+ /// <summary>
+ /// Determine if the parameter passed is an array.
+ /// </summary>
+ /// <param name="obj" type="Object">Object to test whether or not it is an array.</param>
+ /// <returns type="Boolean">True if the parameter is a function; otherwise false.</returns>
+
+ return toString.call(obj) === "[object Array]";
+ },
+
+ isPlainObject: function( obj ) {
+ /// <summary>
+ /// Check to see if an object is a plain object (created using "{}" or "new Object").
+ /// </summary>
+ /// <param name="obj" type="Object">
+ /// The object that will be checked to see if it's a plain object.
+ /// </param>
+ /// <returns type="Boolean" />
+
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor
+ && !hasOwnProperty.call(obj, "constructor")
+ && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwnProperty.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ /// <summary>
+ /// Check to see if an object is empty (contains no properties).
+ /// </summary>
+ /// <param name="obj" type="Object">
+ /// The object that will be checked to see if it's empty.
+ /// </param>
+ /// <returns type="Boolean" />
+
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+
+ // Try to use the native JSON parser first
+ return window.JSON && window.JSON.parse ?
+ window.JSON.parse( data ) :
+ (new Function("return " + data))();
+
+ } else {
+ jQuery.error( "Invalid JSON: " + data );
+ }
+ },
+
+ noop: function() {
+ /// <summary>
+ /// An empty function.
+ /// </summary>
+ /// <returns type="Function" />
+ },
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ /// <summary>
+ /// Internally evaluates a script in a global context.
+ /// </summary>
+ /// <private />
+
+ if ( data && rnotwhite.test(data) ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+
+ if ( jQuery.support.scriptEval ) {
+ script.appendChild( document.createTextNode( data ) );
+ } else {
+ script.text = data;
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ /// <summary>
+ /// Checks whether the specified element has the specified DOM node name.
+ /// </summary>
+ /// <param name="elem" type="Element">The element to examine</param>
+ /// <param name="name" type="String">The node name to check</param>
+ /// <returns type="Boolean">True if the specified node name matches the node's DOM node name; otherwise false</returns>
+
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ /// <summary>
+ /// A generic iterator function, which can be used to seemlessly
+ /// iterate over both objects and arrays. This function is not the same
+ /// as $().each() - which is used to iterate, exclusively, over a jQuery
+ /// object. This function can be used to iterate over anything.
+ /// The callback has two arguments:the key (objects) or index (arrays) as first
+ /// the first, and the value as the second.
+ /// Part of JavaScript
+ /// </summary>
+ /// <param name="obj" type="Object">
+ /// The object, or array, to iterate over.
+ /// </param>
+ /// <param name="fn" type="Function">
+ /// The function that will be executed on every object.
+ /// </param>
+ /// <returns type="Object" />
+
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction(object);
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+ }
+ }
+
+ return object;
+ },
+
+ trim: function( text ) {
+ /// <summary>
+ /// Remove the whitespace from the beginning and end of a string.
+ /// Part of JavaScript
+ /// </summary>
+ /// <returns type="String" />
+ /// <param name="text" type="String">
+ /// The string to trim.
+ /// </param>
+
+ return (text || "").replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ /// <summary>
+ /// Turns anything into a true array. This is an internal method.
+ /// </summary>
+ /// <param name="array" type="Object">Anything to turn into an actual Array</param>
+ /// <returns type="Array" />
+ /// <private />
+
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ if ( array.indexOf ) {
+ return array.indexOf( elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ /// <summary>
+ /// Merge two arrays together, removing all duplicates.
+ /// The new array is: All the results from the first array, followed
+ /// by the unique results from the second array.
+ /// Part of JavaScript
+ /// </summary>
+ /// <returns type="Array" />
+ /// <param name="first" type="Array">
+ /// The first array to merge.
+ /// </param>
+ /// <param name="second" type="Array">
+ /// The second array to merge.
+ /// </param>
+
+ var i = first.length, j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ /// <summary>
+ /// Filter items out of an array, by using a filter function.
+ /// The specified function will be passed two arguments: The
+ /// current array item and the index of the item in the array. The
+ /// function must return 'true' to keep the item in the array,
+ /// false to remove it.
+ /// });
+ /// Part of JavaScript
+ /// </summary>
+ /// <returns type="Array" />
+ /// <param name="elems" type="Array">
+ /// array The Array to find items in.
+ /// </param>
+ /// <param name="fn" type="Function">
+ /// The function to process each item against.
+ /// </param>
+ /// <param name="inv" type="Boolean">
+ /// Invert the selection - select the opposite of the function.
+ /// </param>
+
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ if ( !inv !== !callback( elems[ i ], i ) ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ /// <summary>
+ /// Translate all items in an array to another array of items.
+ /// The translation function that is provided to this method is
+ /// called for each item in the array and is passed one argument:
+ /// The item to be translated.
+ /// The function can then return the translated value, 'null'
+ /// (to remove the item), or an array of values - which will
+ /// be flattened into the full array.
+ /// Part of JavaScript
+ /// </summary>
+ /// <returns type="Array" />
+ /// <param name="elems" type="Array">
+ /// array The Array to translate.
+ /// </param>
+ /// <param name="fn" type="Function">
+ /// The function to process each item against.
+ /// </param>
+
+ var ret = [], value;
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ proxy: function( fn, proxy, thisObject ) {
+ /// <summary>
+ /// Takes a function and returns a new one that will always have a particular scope.
+ /// </summary>
+ /// <param name="fn" type="Function">
+ /// The function whose scope will be changed.
+ /// </param>
+ /// <param name="proxy" type="Object">
+ /// The object to which the scope of the function should be set.
+ /// </param>
+ /// <returns type="Function" />
+
+ if ( arguments.length === 2 ) {
+ if ( typeof proxy === "string" ) {
+ thisObject = fn;
+ fn = thisObject[ proxy ];
+ proxy = undefined;
+
+ } else if ( proxy && !jQuery.isFunction( proxy ) ) {
+ thisObject = proxy;
+ proxy = undefined;
+ }
+ }
+
+ if ( !proxy && fn ) {
+ proxy = function() {
+ return fn.apply( thisObject || this, arguments );
+ };
+ }
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ if ( fn ) {
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+ }
+
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+ /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
+ /(msie) ([\w.]+)/.exec( ua ) ||
+ !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ browser: {}
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+ jQuery.inArray = function( elem, array ) {
+ /// <summary>
+ /// Determines the index of the first parameter in the array.
+ /// </summary>
+ /// <param name="elem">The value to see if it exists in the array.</param>
+ /// <param name="array" type="Array">The array to look through for the value</param>
+ /// <returns type="Number" integer="true">The 0-based index of the item if it was found, otherwise -1.</returns>
+
+ return indexOf.call( array, elem );
+ };
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+function evalScript( i, elem ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+// Mutifunctional method to get and set values to a collection
+// The value/s can be optionally by executed if its a function
+function access( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : null;
+}
+
+function now() {
+ /// <summary>
+ /// Gets the current date.
+ /// </summary>
+ /// <returns type="Date">The current date.</returns>
+
+ return (new Date).getTime();
+}
+
+// [vsdoc] The following function has been modified for IntelliSense.
+// [vsdoc] Stubbing support properties to "false" for IntelliSense compat.
+(function() {
+
+ jQuery.support = {};
+
+ // var root = document.documentElement,
+ // script = document.createElement("script"),
+ // div = document.createElement("div"),
+ // id = "script" + now();
+
+ // div.style.display = "none";
+ // div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+ // var all = div.getElementsByTagName("*"),
+ // a = div.getElementsByTagName("a")[0];
+
+ // // Can't get basic test support
+ // if ( !all || !all.length || !a ) {
+ // return;
+ // }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: false,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: false,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: false,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: false,
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: false,
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: false,
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: false,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: false,
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: false,
+
+ // Will be defined later
+ checkClone: false,
+ scriptEval: false,
+ noCloneEvent: false,
+ boxModel: false
+ };
+
+ // script.type = "text/javascript";
+ // try {
+ // script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ // } catch(e) {}
+
+ // root.insertBefore( script, root.firstChild );
+
+ // // Make sure that the execution of code works by injecting a script
+ // // tag with appendChild/createTextNode
+ // // (IE doesn't support this, fails, and uses .text instead)
+ // if ( window[ id ] ) {
+ // jQuery.support.scriptEval = true;
+ // delete window[ id ];
+ // }
+
+ // root.removeChild( script );
+
+ // if ( div.attachEvent && div.fireEvent ) {
+ // div.attachEvent("onclick", function click() {
+ // // Cloning a node shouldn't copy over any
+ // // bound event handlers (IE does this)
+ // jQuery.support.noCloneEvent = false;
+ // div.detachEvent("onclick", click);
+ // });
+ // div.cloneNode(true).fireEvent("onclick");
+ // }
+
+ // div = document.createElement("div");
+ // div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+ // var fragment = document.createDocumentFragment();
+ // fragment.appendChild( div.firstChild );
+
+ // // WebKit doesn't clone checked state correctly in fragments
+ // jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+ // // Figure out if the W3C box model works as expected
+ // // document.body must exist before we can do this
+ // jQuery(function() {
+ // var div = document.createElement("div");
+ // div.style.width = div.style.paddingLeft = "1px";
+
+ // document.body.appendChild( div );
+ // jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ // document.body.removeChild( div ).style.display = 'none';
+ // div = null;
+ // });
+
+ // // Technique from Juriy Zaytsev
+ // // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ // var eventSupported = function( eventName ) {
+ // var el = document.createElement("div");
+ // eventName = "on" + eventName;
+
+ // var isSupported = (eventName in el);
+ // if ( !isSupported ) {
+ // el.setAttribute(eventName, "return;");
+ // isSupported = typeof el[eventName] === "function";
+ // }
+ // el = null;
+
+ // return isSupported;
+ // };
+
+ jQuery.support.submitBubbles = false;
+ jQuery.support.changeBubbles = false;
+
+ // // release memory in IE
+ // root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ tabindex: "tabIndex",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+};
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+var emptyObject = {};
+
+jQuery.extend({
+ cache: {},
+
+ expando:expando,
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ "object": true,
+ "applet": true
+ },
+
+ data: function( elem, name, data ) {
+ /// <summary>
+ /// Store arbitrary data associated with the specified element.
+ /// </summary>
+ /// <param name="elem" type="Element">
+ /// The DOM element to associate with the data.
+ /// </param>
+ /// <param name="name" type="String">
+ /// A string naming the piece of data to set.
+ /// </param>
+ /// <param name="value" type="Object">
+ /// The new data value.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache;
+
+ // Handle the case where there's no name immediately
+ if ( !name && !id ) {
+ return null;
+ }
+
+ // Compute a unique ID for the element
+ if ( !id ) {
+ id = ++uuid;
+ }
+
+ // Avoid generating a new cache unless none exists and we
+ // want to manipulate it.
+ if ( typeof name === "object" ) {
+ elem[ expando ] = id;
+ thisCache = cache[ id ] = jQuery.extend(true, {}, name);
+ } else if ( cache[ id ] ) {
+ thisCache = cache[ id ];
+ } else if ( typeof data === "undefined" ) {
+ thisCache = emptyObject;
+ } else {
+ thisCache = cache[ id ] = {};
+ }
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined ) {
+ elem[ expando ] = id;
+ thisCache[ name ] = data;
+ }
+
+ return typeof name === "string" ? thisCache[ name ] : thisCache;
+ },
+
+ removeData: function( elem, name ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( thisCache ) {
+ // Remove the section of cache data
+ delete thisCache[ name ];
+
+ // If we've removed all the data, remove the element's cache
+ if ( jQuery.isEmptyObject(thisCache) ) {
+ jQuery.removeData( elem );
+ }
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch( e ) {
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute ) {
+ elem.removeAttribute( expando );
+ }
+ }
+
+ // Completely remove the data cache
+ delete cache[ id ];
+ }
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ /// <summary>
+ /// Store arbitrary data associated with the matched elements.
+ /// </summary>
+ /// <param name="key" type="String">
+ /// A string naming the piece of data to set.
+ /// </param>
+ /// <param name="value" type="Object">
+ /// The new data value.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ if ( typeof key === "undefined" && this.length ) {
+ return jQuery.data( this[0] );
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ }
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else {
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
+ jQuery.data( this, key, value );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+jQuery.extend({
+ queue: function( elem, type, data ) {
+ if ( !elem ) {
+ return;
+ }
+
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( !data ) {
+ return q || [];
+ }
+
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+ } else {
+ q.push( data );
+ }
+
+ return q;
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ), fn = queue.shift();
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ /// <summary>
+ /// 1: queue() - Returns a reference to the first element's queue (which is an array of functions).
+ /// 2: queue(callback) - Adds a new function, to be executed, onto the end of the queue of all matched elements.
+ /// 3: queue(queue) - Replaces the queue of all matched element with this new queue (the array of functions).
+ /// </summary>
+ /// <param name="type" type="Function">The function to add to the queue.</param>
+ /// <returns type="jQuery" />
+
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function( i, elem ) {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ /// <summary>
+ /// Removes a queued function from the front of the queue and executes it.
+ /// </summary>
+ /// <param name="type" type="String" optional="true">The type of queue to access.</param>
+ /// <returns type="jQuery" />
+
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ /// <summary>
+ /// Set a timer to delay execution of subsequent items in the queue.
+ /// </summary>
+ /// <param name="time" type="Number">
+ /// An integer indicating the number of milliseconds to delay execution of the next item in the queue.
+ /// </param>
+ /// <param name="type" type="String">
+ /// A string containing the name of the queue. Defaults to fx, the standard effects queue.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+
+ clearQueue: function( type ) {
+ /// <summary>
+ /// Remove from the queue all items that have not yet been run.
+ /// </summary>
+ /// <param name="type" type="String" optional="true">
+ /// A string containing the name of the queue. Defaults to fx, the standard effects queue.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ return this.queue( type || "fx", [] );
+ }
+});
+var rclass = /[\n\t]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rspecialurl = /href|src|style/,
+ rtype = /(button|input)/i,
+ rfocusable = /(button|input|object|select|textarea)/i,
+ rclickable = /^(a|area)$/i,
+ rradiocheck = /radio|checkbox/;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ /// <summary>
+ /// Set a single property to a computed value, on all matched elements.
+ /// Instead of a value, a function is provided, that computes the value.
+ /// Part of DOM/Attributes
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="name" type="String">
+ /// The name of the property to set.
+ /// </param>
+ /// <param name="value" type="Function">
+ /// A function returning the value to set.
+ /// </param>
+
+ return access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name, fn ) {
+ /// <summary>
+ /// Remove an attribute from each of the matched elements.
+ /// Part of DOM/Attributes
+ /// </summary>
+ /// <param name="name" type="String">
+ /// An attribute to remove.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ return this.each(function(){
+ jQuery.attr( this, name, "" );
+ if ( this.nodeType === 1 ) {
+ this.removeAttribute( name );
+ }
+ });
+ },
+
+ addClass: function( value ) {
+ /// <summary>
+ /// Adds the specified class(es) to each of the set of matched elements.
+ /// Part of DOM/Attributes
+ /// </summary>
+ /// <param name="value" type="String">
+ /// One or more class names to be added to the class attribute of each matched element.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.addClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ var classNames = (value || "").split( rspace );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className ) {
+ elem.className = value;
+
+ } else {
+ var className = " " + elem.className + " ";
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+ elem.className += " " + classNames[c];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ /// <summary>
+ /// Removes all or the specified class(es) from the set of matched elements.
+ /// Part of DOM/Attributes
+ /// </summary>
+ /// <param name="value" type="String" optional="true">
+ /// (Optional) A class name to be removed from the class attribute of each matched element.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.removeClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ var classNames = (value || "").split(rspace);
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ var className = (" " + elem.className + " ").replace(rclass, " ");
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[c] + " ", " ");
+ }
+ elem.className = className.substring(1, className.length - 1);
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ /// <summary>
+ /// Add or remove a class from each element in the set of matched elements, depending
+ /// on either the class's presence or the value of the switch argument.
+ /// </summary>
+ /// <param name="value" type="Object">
+ /// A class name to be toggled for each element in the matched set.
+ /// </param>
+ /// <param name="stateVal" type="Object">
+ /// A boolean value to determine whether the class should be added or removed.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var type = typeof value, isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className, i = 0, self = jQuery(this),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery.data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ /// <summary>
+ /// Checks the current selection against a class and returns whether at least one selection has a given class.
+ /// </summary>
+ /// <param name="selector" type="String">The class to check against</param>
+ /// <returns type="Boolean">True if at least one element in the selection has the class, otherwise false.</returns>
+
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ /// <summary>
+ /// Set the value of every matched element.
+ /// Part of DOM/Attributes
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="value" type="String">
+ /// A string of text or an array of strings to set as the value property of each
+ /// matched element.
+ /// </param>
+
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if ( jQuery.nodeName( elem, "option" ) ) {
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+ }
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(rreturn, "");
+
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction(value);
+
+ return this.each(function(i) {
+ var self = jQuery(this), val = value;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call(this, i, self.val());
+ }
+
+ // Typecast each time if the value is a Function and the appended
+ // value is therefore different each time.
+ if ( typeof val === "number" ) {
+ val += "";
+ }
+
+ if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+ this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+ } else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(val);
+
+ jQuery( "option", this ).each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ this.selectedIndex = -1;
+ }
+
+ } else {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attr: function( elem, name, value, pass ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ // don't set attributes on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery(elem)[name](value);
+ }
+
+ var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ if ( elem.nodeType === 1 ) {
+ // These attributes require special treatment
+ var special = rspecialurl.test( name );
+
+ // Safari mis-reports the default selected property of an option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name === "selected" && !jQuery.support.optSelected ) {
+ var parent = elem.parentNode;
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ }
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+ return elem.getAttributeNode( name ).nodeValue;
+ }
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ if ( name === "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+ return attributeNode && attributeNode.specified ?
+ attributeNode.value :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name === "style" ) {
+ if ( set ) {
+ elem.style.cssText = "" + value;
+ }
+
+ return elem.style.cssText;
+ }
+
+ if ( set ) {
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special ?
+ // Some attributes require a special call on IE
+ elem.getAttribute( name, 2 ) :
+ elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+ // Using attr for specific style information is now deprecated. Use style insead.
+ return jQuery.style( elem, name, value );
+ }
+});
+var fcleanup = function( nm ) {
+ return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
+ return "\\" + ch;
+ });
+};
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
+ elem = window;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // if data is passed, bind to handler
+ if ( data !== undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = jQuery.proxy( fn );
+
+ // Store data in unique handler
+ handler.data = data;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ),
+ handle = jQuery.data( elem, "handle" ), eventHandle;
+
+ if ( !handle ) {
+ eventHandle = function() {
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+
+ handle = jQuery.data( elem, "handle", eventHandle );
+ }
+
+ // If no handle is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !handle ) {
+ return;
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split( /\s+/ );
+
+ var type, i = 0;
+
+ while ( (type = types[ i++ ]) ) {
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+
+ if ( i > 1 ) {
+ handler = jQuery.proxy( handler );
+
+ if ( data !== undefined ) {
+ handler.data = data;
+ }
+ }
+
+ handler.type = namespaces.slice(0).sort().join(".");
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = this.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, handle, false );
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, handle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers );
+ if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
+ modifiedHandler.guid = modifiedHandler.guid || handler.guid;
+ modifiedHandler.data = modifiedHandler.data || handler.data;
+ modifiedHandler.type = modifiedHandler.type || handler.type;
+ handler = modifiedHandler;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[ handler.guid ] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ this.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ var events = jQuery.data( elem, "events" ), ret, type, fn;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) {
+ for ( type in events ) {
+ this.remove( elem, type + (types || "") );
+ }
+ } else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(/\s+/);
+ var i = 0;
+ while ( (type = types[ i++ ]) ) {
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ var all = !namespaces.length,
+ cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ),
+ namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"),
+ special = this.special[ type ] || {};
+
+ if ( events[ type ] ) {
+ // remove the given handler for the given type
+ if ( handler ) {
+ fn = events[ type ][ handler.guid ];
+ delete events[ type ][ handler.guid ];
+
+ // remove all handlers for the given type
+ } else {
+ for ( var handle in events[ type ] ) {
+ // Handle the removal of namespaced events
+ if ( all || namespace.test( events[ type ][ handle ].type ) ) {
+ delete events[ type ][ handle ];
+ }
+ }
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, namespaces, fn);
+ }
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[ type ] ) {
+ break;
+ }
+ if ( !ret ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, jQuery.data( elem, "handle" ), false );
+ } else if ( elem.detachEvent ) {
+ elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) );
+ }
+ }
+ ret = null;
+ delete events[ type ];
+ }
+ }
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) {
+ break;
+ }
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) {
+ handle.elem = null;
+ }
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem /*, bubbling */ ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ // Event object or event type
+ var type = event.type || event,
+ bubbling = arguments[3];
+
+ if ( !bubbling ) {
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[ type ] ) {
+ jQuery.each( jQuery.cache, function() {
+ if ( this.events && this.events[type] ) {
+ jQuery.event.trigger( event, data, this.handle.elem );
+ }
+ });
+ }
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray( data );
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) {
+ handle.apply( elem, data );
+ }
+
+ var parent = elem.parentNode || elem.ownerDocument;
+
+ // Trigger an inline bound script
+ try {
+ if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+ if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+ event.result = false;
+ }
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (e) {}
+
+ if ( !event.isPropagationStopped() && parent ) {
+ jQuery.event.trigger( event, data, parent, true );
+
+ } else if ( !event.isDefaultPrevented() ) {
+ var target = event.target, old,
+ isClick = jQuery.nodeName(target, "a") && type === "click";
+
+ if ( !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+ try {
+ if ( target[ type ] ) {
+ // Make sure that we don't accidentally re-trigger the onFOO events
+ old = target[ "on" + type ];
+
+ if ( old ) {
+ target[ "on" + type ] = null;
+ }
+
+ this.triggered = true;
+ target[ type ]();
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (e) {}
+
+ if ( old ) {
+ target[ "on" + type ] = old;
+ }
+
+ this.triggered = false;
+ }
+ }
+ },
+
+ handle: function( event ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ // returned undefined or false
+ var all, handlers;
+
+ event = arguments[0] = jQuery.event.fix( event || window.event );
+ event.currentTarget = this;
+
+ // Namespaced event handlers
+ var namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+
+ // Cache this now, all = true means, any handler
+ all = !namespaces.length && !event.exclusive;
+
+ var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
+
+ handlers = ( jQuery.data(this, "events") || {} )[ event.type ];
+
+ for ( var j in handlers ) {
+ var handler = handlers[ j ];
+
+ // Filter the functions by class
+ if ( all || namespace.test(handler.type) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handler;
+ event.data = handler.data;
+
+ var ret = handler.apply( this, arguments );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+
+ }
+ }
+
+ return event.result;
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function( event ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ if ( event[ expando ] ) {
+ return event;
+ }
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ) {
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target ) {
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+ }
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement ) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
+ event.which = event.charCode || event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ // Deprecated, use jQuery.guid instead
+ guid: 1E8,
+
+ // Deprecated, use jQuery.proxy instead
+ proxy: jQuery.proxy,
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady,
+ teardown: jQuery.noop
+ },
+
+ live: {
+ add: function( proxy, data, namespaces, live ) {
+ jQuery.extend( proxy, data || {} );
+
+ proxy.guid += data.selector + data.live;
+ data.liveProxy = proxy;
+
+ jQuery.event.add( this, data.live, liveHandler, data );
+
+ },
+
+ remove: function( namespaces ) {
+ if ( namespaces.length ) {
+ var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
+
+ jQuery.each( (jQuery.data(this, "events").live || {}), function() {
+ if ( name.test(this.type) ) {
+ remove++;
+ }
+ });
+
+ if ( remove < 1 ) {
+ jQuery.event.remove( this, namespaces[0], liveHandler );
+ }
+ }
+ },
+ special: {}
+ },
+ beforeunload: {
+ setup: function( data, namespaces, fn ) {
+ // We only want to do this special case on windows
+ if ( this.setInterval ) {
+ this.onbeforeunload = fn;
+ }
+
+ return false;
+ },
+ teardown: function( namespaces, fn ) {
+ if ( this.onbeforeunload === fn ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ }
+};
+
+jQuery.Event = function( src ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !this.preventDefault ) {
+ return new jQuery.Event( src );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = now();
+
+ // Mark it as fixed
+ this[ expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+ }
+ // otherwise set the returnValue property of the original event to false (IE)
+ e.returnValue = false;
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+
+ // Traverse up the tree
+ while ( parent && parent !== this ) {
+ // Firefox sometimes assigns relatedTarget a XUL element
+ // which we cannot access the parentNode property of
+ try {
+ parent = parent.parentNode;
+
+ // assuming we've left the element since we most likely mousedover a xul element
+ } catch(e) {
+ break;
+ }
+ }
+
+ if ( parent !== this ) {
+ // set the correct event type
+ event.type = event.data;
+
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+ event.type = event.data;
+ jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ setup: function( data ) {
+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+ },
+ teardown: function( data ) {
+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+ }
+ };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+jQuery.event.special.submit = {
+ setup: function( data, namespaces, fn ) {
+ if ( this.nodeName.toLowerCase() !== "form" ) {
+ jQuery.event.add(this, "click.specialSubmit." + fn.guid, function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ jQuery.event.add(this, "keypress.specialSubmit." + fn.guid, function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ } else {
+ return false;
+ }
+ },
+
+ remove: function( namespaces, fn ) {
+ jQuery.event.remove( this, "click.specialSubmit" + (fn ? "."+fn.guid : "") );
+ jQuery.event.remove( this, "keypress.specialSubmit" + (fn ? "."+fn.guid : "") );
+ }
+};
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+var formElems = /textarea|input|select/i;
+
+function getVal( elem ) {
+ var type = elem.type, val = elem.value;
+
+ if ( type === "radio" || type === "checkbox" ) {
+ val = elem.checked;
+
+ } else if ( type === "select-multiple" ) {
+ val = elem.selectedIndex > -1 ?
+ jQuery.map( elem.options, function( elem ) {
+ return elem.selected;
+ }).join("-") :
+ "";
+
+ } else if ( elem.nodeName.toLowerCase() === "select" ) {
+ val = elem.selectedIndex;
+ }
+
+ return val;
+}
+
+function testChange( e ) {
+ var elem = e.target, data, val;
+
+ if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
+ return;
+ }
+
+ data = jQuery.data( elem, "_change_data" );
+ val = getVal(elem);
+
+ // the current data will be also retrieved by beforeactivate
+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
+ jQuery.data( elem, "_change_data", val );
+ }
+
+ if ( data === undefined || val === data ) {
+ return;
+ }
+
+ if ( data != null || val ) {
+ e.type = "change";
+ return jQuery.event.trigger( e, arguments[1], elem );
+ }
+}
+
+jQuery.event.special.change = {
+ filters: {
+ focusout: testChange,
+
+ click: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Change has to be called before submit
+ // Keydown will be called before keypress, which is used in submit-event delegation
+ keydown: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+ type === "select-multiple" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Beforeactivate happens also before the previous element is blurred
+ // with this event you can't trigger a change event, but you can store
+ // information/focus[in] is not needed anymore
+ beforeactivate: function( e ) {
+ var elem = e.target;
+
+ if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) {
+ jQuery.data( elem, "_change_data", getVal(elem) );
+ }
+ }
+ },
+ setup: function( data, namespaces, fn ) {
+ for ( var type in changeFilters ) {
+ jQuery.event.add( this, type + ".specialChange." + fn.guid, changeFilters[type] );
+ }
+
+ return formElems.test( this.nodeName );
+ },
+ remove: function( namespaces, fn ) {
+ for ( var type in changeFilters ) {
+ jQuery.event.remove( this, type + ".specialChange" + (fn ? "."+fn.guid : ""), changeFilters[type] );
+ }
+
+ return formElems.test( this.nodeName );
+ }
+};
+
+var changeFilters = jQuery.event.special.change.filters;
+
+}
+
+function trigger( type, elem, args ) {
+ args[0].type = type;
+ return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ this.addEventListener( orig, handler, true );
+ },
+ teardown: function() {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ this.removeEventListener( orig, handler, true );
+ }
+ };
+
+ function handler( e ) {
+ e = jQuery.event.fix( e );
+ e.type = fix;
+ return jQuery.event.handle.call( this, e );
+ }
+ });
+}
+
+// jQuery.each(["bind", "one"], function( i, name ) {
+// jQuery.fn[ name ] = function( type, data, fn ) {
+// // Handle object literals
+// if ( typeof type === "object" ) {
+// for ( var key in type ) {
+// this[ name ](key, data, type[key], fn);
+// }
+// return this;
+// }
+//
+// if ( jQuery.isFunction( data ) ) {
+// fn = data;
+// data = undefined;
+// }
+//
+// var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+// jQuery( this ).unbind( event, handler );
+// return fn.apply( this, arguments );
+// }) : fn;
+//
+// return type === "unload" && name !== "one" ?
+// this.one( type, data, fn ) :
+// this.each(function() {
+// jQuery.event.add( this, type, handler, data );
+// });
+// };
+// });
+
+jQuery.fn[ "bind" ] = function( type, data, fn ) {
+ /// <summary>
+ /// Binds a handler to one or more events for each matched element. Can also bind custom events.
+ /// </summary>
+ /// <param name="type" type="String">One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .</param>
+ /// <param name="data" optional="true" type="Object">Additional data passed to the event handler as event.data</param>
+ /// <param name="fn" type="Function">A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element.</param>
+
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ "bind" ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ var handler = "bind" === "one" ? jQuery.proxy( fn, function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ }) : fn;
+
+ return type === "unload" && "bind" !== "one" ?
+ this.one( type, data, fn ) :
+ this.each(function() {
+ jQuery.event.add( this, type, handler, data );
+ });
+};
+
+jQuery.fn[ "one" ] = function( type, data, fn ) {
+ /// <summary>
+ /// Binds a handler to one or more events to be executed exactly once for each matched element.
+ /// </summary>
+ /// <param name="type" type="String">One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .</param>
+ /// <param name="data" optional="true" type="Object">Additional data passed to the event handler as event.data</param>
+ /// <param name="fn" type="Function">A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element.</param>
+
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ "one" ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ var handler = "one" === "one" ? jQuery.proxy( fn, function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ }) : fn;
+
+ return type === "unload" && "one" !== "one" ?
+ this.one( type, data, fn ) :
+ this.each(function() {
+ jQuery.event.add( this, type, handler, data );
+ });
+};
+
+jQuery.fn.extend({
+ unbind: function( type, fn ) {
+ /// <summary>
+ /// Unbinds a handler from one or more events for each matched element.
+ /// </summary>
+ /// <param name="type" type="String">One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .</param>
+ /// <param name="fn" type="Function">A function to bind to the event on each of the set of matched elements. function callback(eventObject) such that this corresponds to the dom element.</param>
+
+ // Handle object literals
+ if ( typeof type === "object" && !type.preventDefault ) {
+ for ( var key in type ) {
+ this.unbind(key, type[key]);
+ }
+ return this;
+ }
+
+ return this.each(function() {
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+ trigger: function( type, data ) {
+ /// <summary>
+ /// Triggers a type of event on every matched element.
+ /// </summary>
+ /// <param name="type" type="String">One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .</param>
+ /// <param name="data" optional="true" type="Array">Additional data passed to the event handler as additional arguments.</param>
+ /// <param name="fn" type="Function">This parameter is undocumented.</param>
+
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ /// <summary>
+ /// Triggers all bound event handlers on an element for a specific event type without executing the browser's default actions.
+ /// </summary>
+ /// <param name="type" type="String">One or more event types separated by a space. Built-in event type values are: blur, focus, load, resize, scroll, unload, click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, mouseenter, mouseleave, change, select, submit, keydown, keypress, keyup, error .</param>
+ /// <param name="data" optional="true" type="Array">Additional data passed to the event handler as additional arguments.</param>
+ /// <param name="fn" type="Function">This parameter is undocumented.</param>
+
+ if ( this[0] ) {
+ var event = jQuery.Event( type );
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ /// <summary>
+ /// Toggles among two or more function calls every other click.
+ /// </summary>
+ /// <param name="fn" type="Function">The functions among which to toggle execution</param>
+
+ // Save reference to arguments for access in closure
+ var args = arguments, i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while ( i < args.length ) {
+ jQuery.proxy( fn, args[ i++ ] );
+ }
+
+ return this.click( jQuery.proxy( fn, function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function( fnOver, fnOut ) {
+ /// <summary>
+ /// Simulates hovering (moving the mouse on or off of an object).
+ /// </summary>
+ /// <param name="fnOver" type="Function">The function to fire when the mouse is moved over a matched element.</param>
+ /// <param name="fnOut" type="Function">The function to fire when the mouse is moved off of a matched element.</param>
+
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+// jQuery.each(["live", "die"], function( i, name ) {
+// jQuery.fn[ name ] = function( types, data, fn ) {
+// var type, i = 0;
+//
+// if ( jQuery.isFunction( data ) ) {
+// fn = data;
+// data = undefined;
+// }
+//
+// types = (types || "").split( /\s+/ );
+//
+// while ( (type = types[ i++ ]) != null ) {
+// type = type === "focus" ? "focusin" : // focus --> focusin
+// type === "blur" ? "focusout" : // blur --> focusout
+// type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support
+// type;
+//
+// if ( name === "live" ) {
+// // bind live handler
+// jQuery( this.context ).bind( liveConvert( type, this.selector ), {
+// data: data, selector: this.selector, live: type
+// }, fn );
+//
+// } else {
+// // unbind live handler
+// jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
+// }
+// }
+//
+// return this;
+// }
+// });
+
+jQuery.fn[ "live" ] = function( types, data, fn ) {
+ /// <summary>
+ /// Attach a handler to the event for all elements which match the current selector, now or
+ /// in the future.
+ /// </summary>
+ /// <param name="types" type="String">
+ /// A string containing a JavaScript event type, such as "click" or "keydown".
+ /// </param>
+ /// <param name="data" type="Object">
+ /// A map of data that will be passed to the event handler.
+ /// </param>
+ /// <param name="fn" type="Function">
+ /// A function to execute at the time the event is triggered.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var type, i = 0;
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ types = (types || "").split( /\s+/ );
+
+ while ( (type = types[ i++ ]) != null ) {
+ type = type === "focus" ? "focusin" : // focus --> focusin
+ type === "blur" ? "focusout" : // blur --> focusout
+ type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support
+ type;
+
+ if ( "live" === "live" ) {
+ // bind live handler
+ jQuery( this.context ).bind( liveConvert( type, this.selector ), {
+ data: data, selector: this.selector, live: type
+ }, fn );
+
+ } else {
+ // unbind live handler
+ jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
+ }
+ }
+
+ return this;
+}
+
+jQuery.fn[ "die" ] = function( types, data, fn ) {
+ /// <summary>
+ /// Remove all event handlers previously attached using .live() from the elements.
+ /// </summary>
+ /// <param name="types" type="String">
+ /// A string containing a JavaScript event type, such as click or keydown.
+ /// </param>
+ /// <param name="data" type="Object">
+ /// The function that is to be no longer executed.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var type, i = 0;
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ types = (types || "").split( /\s+/ );
+
+ while ( (type = types[ i++ ]) != null ) {
+ type = type === "focus" ? "focusin" : // focus --> focusin
+ type === "blur" ? "focusout" : // blur --> focusout
+ type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support
+ type;
+
+ if ( "die" === "live" ) {
+ // bind live handler
+ jQuery( this.context ).bind( liveConvert( type, this.selector ), {
+ data: data, selector: this.selector, live: type
+ }, fn );
+
+ } else {
+ // unbind live handler
+ jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
+ }
+ }
+
+ return this;
+}
+
+function liveHandler( event ) {
+ var stop, elems = [], selectors = [], args = arguments,
+ related, match, fn, elem, j, i, l, data,
+ live = jQuery.extend({}, jQuery.data( this, "events" ).live);
+
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861)
+ if ( event.button && event.type === "click" ) {
+ return;
+ }
+
+ for ( j in live ) {
+ fn = live[j];
+ if ( fn.live === event.type ||
+ fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) {
+
+ data = fn.data;
+ if ( !(data.beforeFilter && data.beforeFilter[event.type] &&
+ !data.beforeFilter[event.type](event)) ) {
+ selectors.push( fn.selector );
+ }
+ } else {
+ delete live[j];
+ }
+ }
+
+ match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+ for ( i = 0, l = match.length; i < l; i++ ) {
+ for ( j in live ) {
+ fn = live[j];
+ elem = match[i].elem;
+ related = null;
+
+ if ( match[i].selector === fn.selector ) {
+ // Those two events require additional checking
+ if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) {
+ related = jQuery( event.relatedTarget ).closest( fn.selector )[0];
+ }
+
+ if ( !related || related !== elem ) {
+ elems.push({ elem: elem, fn: fn });
+ }
+ }
+ }
+ }
+
+ for ( i = 0, l = elems.length; i < l; i++ ) {
+ match = elems[i];
+ event.currentTarget = match.elem;
+ event.data = match.fn.data;
+ if ( match.fn.apply( match.elem, args ) === false ) {
+ stop = false;
+ break;
+ }
+ }
+
+ return stop;
+}
+
+function liveConvert( type, selector ) {
+ return "live." + (type ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
+}
+
+// jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+// "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+// "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+//
+// // Handle event binding
+// jQuery.fn[ name ] = function( fn ) {
+// return fn ? this.bind( name, fn ) : this.trigger( name );
+// };
+//
+// if ( jQuery.attrFn ) {
+// jQuery.attrFn[ name ] = true;
+// }
+// });
+
+jQuery.fn[ "blur" ] = function( fn ) {
+ /// <summary>
+ /// 1: blur() - Triggers the blur event of each matched element.
+ /// 2: blur(fn) - Binds a function to the blur event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "blur", fn ) : this.trigger( "blur" );
+};
+
+jQuery.fn[ "focus" ] = function( fn ) {
+ /// <summary>
+ /// 1: focus() - Triggers the focus event of each matched element.
+ /// 2: focus(fn) - Binds a function to the focus event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "focus", fn ) : this.trigger( "focus" );
+};
+
+jQuery.fn[ "focusin" ] = function( fn ) {
+ /// <summary>
+ /// Bind an event handler to the "focusin" JavaScript event.
+ /// </summary>
+ /// <param name="fn" type="Function">
+ /// A function to execute each time the event is triggered.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "focusin", fn ) : this.trigger( "focusin" );
+};
+
+jQuery.fn[ "focusout" ] = function( fn ) {
+ /// <summary>
+ /// Bind an event handler to the "focusout" JavaScript event.
+ /// </summary>
+ /// <param name="fn" type="Function">
+ /// A function to execute each time the event is triggered.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "focusout", fn ) : this.trigger( "focusout" );
+};
+
+jQuery.fn[ "load" ] = function( fn ) {
+ /// <summary>
+ /// 1: load() - Triggers the load event of each matched element.
+ /// 2: load(fn) - Binds a function to the load event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "load", fn ) : this.trigger( "load" );
+};
+
+jQuery.fn[ "resize" ] = function( fn ) {
+ /// <summary>
+ /// 1: resize() - Triggers the resize event of each matched element.
+ /// 2: resize(fn) - Binds a function to the resize event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "resize", fn ) : this.trigger( "resize" );
+};
+
+jQuery.fn[ "scroll" ] = function( fn ) {
+ /// <summary>
+ /// 1: scroll() - Triggers the scroll event of each matched element.
+ /// 2: scroll(fn) - Binds a function to the scroll event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "scroll", fn ) : this.trigger( "scroll" );
+};
+
+jQuery.fn[ "unload" ] = function( fn ) {
+ /// <summary>
+ /// 1: unload() - Triggers the unload event of each matched element.
+ /// 2: unload(fn) - Binds a function to the unload event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "unload", fn ) : this.trigger( "unload" );
+};
+
+jQuery.fn[ "click" ] = function( fn ) {
+ /// <summary>
+ /// 1: click() - Triggers the click event of each matched element.
+ /// 2: click(fn) - Binds a function to the click event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "click", fn ) : this.trigger( "click" );
+};
+
+jQuery.fn[ "dblclick" ] = function( fn ) {
+ /// <summary>
+ /// 1: dblclick() - Triggers the dblclick event of each matched element.
+ /// 2: dblclick(fn) - Binds a function to the dblclick event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "dblclick", fn ) : this.trigger( "dblclick" );
+};
+
+jQuery.fn[ "mousedown" ] = function( fn ) {
+ /// <summary>
+ /// Binds a function to the mousedown event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "mousedown", fn ) : this.trigger( "mousedown" );
+};
+
+jQuery.fn[ "mouseup" ] = function( fn ) {
+ /// <summary>
+ /// Bind a function to the mouseup event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "mouseup", fn ) : this.trigger( "mouseup" );
+};
+
+jQuery.fn[ "mousemove" ] = function( fn ) {
+ /// <summary>
+ /// Bind a function to the mousemove event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "mousemove", fn ) : this.trigger( "mousemove" );
+};
+
+jQuery.fn[ "mouseover" ] = function( fn ) {
+ /// <summary>
+ /// Bind a function to the mouseover event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "mouseover", fn ) : this.trigger( "mouseover" );
+};
+
+jQuery.fn[ "mouseout" ] = function( fn ) {
+ /// <summary>
+ /// Bind a function to the mouseout event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "mouseout", fn ) : this.trigger( "mouseout" );
+};
+
+jQuery.fn[ "mouseenter" ] = function( fn ) {
+ /// <summary>
+ /// Bind a function to the mouseenter event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "mouseenter", fn ) : this.trigger( "mouseenter" );
+};
+
+jQuery.fn[ "mouseleave" ] = function( fn ) {
+ /// <summary>
+ /// Bind a function to the mouseleave event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "mouseleave", fn ) : this.trigger( "mouseleave" );
+};
+
+jQuery.fn[ "change" ] = function( fn ) {
+ /// <summary>
+ /// 1: change() - Triggers the change event of each matched element.
+ /// 2: change(fn) - Binds a function to the change event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "change", fn ) : this.trigger( "change" );
+};
+
+jQuery.fn[ "select" ] = function( fn ) {
+ /// <summary>
+ /// 1: select() - Triggers the select event of each matched element.
+ /// 2: select(fn) - Binds a function to the select event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "select", fn ) : this.trigger( "select" );
+};
+
+jQuery.fn[ "submit" ] = function( fn ) {
+ /// <summary>
+ /// 1: submit() - Triggers the submit event of each matched element.
+ /// 2: submit(fn) - Binds a function to the submit event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "submit", fn ) : this.trigger( "submit" );
+};
+
+jQuery.fn[ "keydown" ] = function( fn ) {
+ /// <summary>
+ /// 1: keydown() - Triggers the keydown event of each matched element.
+ /// 2: keydown(fn) - Binds a function to the keydown event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "keydown", fn ) : this.trigger( "keydown" );
+};
+
+jQuery.fn[ "keypress" ] = function( fn ) {
+ /// <summary>
+ /// 1: keypress() - Triggers the keypress event of each matched element.
+ /// 2: keypress(fn) - Binds a function to the keypress event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "keypress", fn ) : this.trigger( "keypress" );
+};
+
+jQuery.fn[ "keyup" ] = function( fn ) {
+ /// <summary>
+ /// 1: keyup() - Triggers the keyup event of each matched element.
+ /// 2: keyup(fn) - Binds a function to the keyup event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "keyup", fn ) : this.trigger( "keyup" );
+};
+
+jQuery.fn[ "error" ] = function( fn ) {
+ /// <summary>
+ /// 1: error() - Triggers the error event of each matched element.
+ /// 2: error(fn) - Binds a function to the error event of each matched element.
+ /// </summary>
+ /// <param name="fn" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return fn ? this.bind( "error", fn ) : this.trigger( "error" );
+};
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+ window.attachEvent("onunload", function() {
+ for ( var id in jQuery.cache ) {
+ if ( jQuery.cache[ id ].handle ) {
+ // Try/Catch is to handle iframes being unloaded, see #4280
+ try {
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+ } catch(e) {}
+ }
+ }
+ });
+}
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function(){
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ var origContext = context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+ }
+
+ if ( context ) {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context && context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function(results){
+ /// <summary>
+ /// Removes all duplicate elements from an array of elements.
+ /// </summary>
+ /// <param name="array" type="Array&lt;Element&gt;">The array to translate</param>
+ /// <returns type="Array&lt;Element&gt;">The array after translation.</returns>
+
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ var filter = Expr.filter[ type ], found, item, left = match[1];
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+ leftMatch: {},
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = part.toLowerCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = part.toLowerCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = part.toLowerCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ return match[1].toLowerCase();
+ },
+ CHILD: function(match){
+ if ( match[1] === "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ /// <summary>
+ /// Internal use only; use hasClass('class')
+ /// </summary>
+ /// <private />
+
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 === i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ Sizzle.error( "Syntax error, unrecognized expression: " + name );
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ if ( type === "first" ) {
+ return true;
+ }
+ node = elem;
+ case 'last':
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first === 0 ) {
+ return diff === 0;
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
+ return "\\" + (num - 0 + 1);
+ }));
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 );
+
+// Provide a fallback method if it does not work
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ if ( !a.sourceIndex || !b.sourceIndex ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.sourceIndex ? -1 : 1;
+ }
+
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ if ( !a.ownerDocument || !b.ownerDocument ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.ownerDocument ? -1 : 1;
+ }
+
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.setStart(a, 0);
+ aRange.setEnd(a, 0);
+ bRange.setStart(b, 0);
+ bRange.setEnd(b, 0);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+function getText( elems ) {
+ var ret = "", elem;
+
+ for ( var i = 0; elems[i]; i++ ) {
+ elem = elems[i];
+
+ // Get the text from text nodes and CDATA nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+ ret += elem.nodeValue;
+
+ // Traverse everything else, except comment nodes
+ } else if ( elem.nodeType !== 8 ) {
+ ret += getText( elem.childNodes );
+ }
+ }
+
+ return ret;
+}
+
+// [vsdoc] The following function has been modified for IntelliSense.
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ // var form = document.createElement("div"),
+ // id = "script" + (new Date).getTime();
+ // form.innerHTML = "<a name='" + id + "'/>";
+
+ // // Inject it into the root element, check its status, and remove it quickly
+ // var root = document.documentElement;
+ // root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ // if ( document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ // }
+
+ // root.removeChild( form );
+ root = form = null; // release memory in IE
+})();
+
+// [vsdoc] The following function has been modified for IntelliSense.
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ // var div = document.createElement("div");
+ // div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ // if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ // }
+
+ // Check to see if an attribute returns normalized href attributes
+ // div.innerHTML = "<a href='#'></a>";
+ // if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ // div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ // }
+
+ div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ div = null; // release memory in IE
+ })();
+}
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ /// <summary>
+ /// Check to see if a DOM node is within another DOM node.
+ /// </summary>
+ /// <param name="a" type="Object">
+ /// The DOM element that may contain the other element.
+ /// </param>
+ /// <param name="b" type="Object">
+ /// The DOM node that may be contained by the other element.
+ /// </param>
+ /// <returns type="Boolean" />
+
+ return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+ /// <summary>
+ /// Check to see if a DOM node is within another DOM node.
+ /// </summary>
+ /// <param name="a" type="Object">
+ /// The DOM element that may contain the other element.
+ /// </param>
+ /// <param name="b" type="Object">
+ /// The DOM node that may be contained by the other element.
+ /// </param>
+ /// <returns type="Boolean" />
+
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ /// <summary>
+ /// Determines if the parameter passed is an XML document.
+ /// </summary>
+ /// <param name="elem" type="Object">The object to test</param>
+ /// <returns type="Boolean">True if the parameter is an XML document; otherwise false.</returns>
+
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.getText = getText;
+jQuery.isXMLDoc = isXML;
+jQuery.contains = contains;
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ slice = Array.prototype.slice;
+
+// Implement the identical functionality for filter and not
+var winnow = function( elements, qualifier, keep ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+ });
+};
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ /// <summary>
+ /// Searches for all elements that match the specified expression.
+ /// This method is a good way to find additional descendant
+ /// elements with which to process.
+ /// All searching is done using a jQuery expression. The expression can be
+ /// written using CSS 1-3 Selector syntax, or basic XPath.
+ /// Part of DOM/Traversing
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="selector" type="String">
+ /// An expression to search with.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var ret = this.pushStack( "", "find", selector ), length = 0;
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( var n = length; n < ret.length; n++ ) {
+ for ( var r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ /// <summary>
+ /// Reduce the set of matched elements to those that have a descendant that matches the
+ /// selector or DOM element.
+ /// </summary>
+ /// <param name="target" type="String">
+ /// A string containing a selector expression to match elements against.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ /// <summary>
+ /// Removes any elements inside the array of elements from the set
+ /// of matched elements. This method is used to remove one or more
+ /// elements from a jQuery object.
+ /// Part of DOM/Traversing
+ /// </summary>
+ /// <param name="selector" type="jQuery">
+ /// A set of elements to remove from the jQuery set of matched elements.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ /// <summary>
+ /// Removes all elements from the set of matched elements that do not
+ /// pass the specified filter. This method is used to narrow down
+ /// the results of a search.
+ /// })
+ /// Part of DOM/Traversing
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="selector" type="Function">
+ /// A function to use for filtering
+ /// </param>
+ /// <returns type="jQuery" />
+
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ /// <summary>
+ /// Checks the current selection against an expression and returns true,
+ /// if at least one element of the selection fits the given expression.
+ /// Does return false, if no element fits or the expression is not valid.
+ /// filter(String) is used internally, therefore all rules that apply there
+ /// apply here, too.
+ /// Part of DOM/Traversing
+ /// </summary>
+ /// <returns type="Boolean" />
+ /// <param name="expr" type="String">
+ /// The expression with which to filter
+ /// </param>
+
+ return !!selector && jQuery.filter( selector, this ).length > 0;
+ },
+
+ closest: function( selectors, context ) {
+ /// <summary>
+ /// Get a set of elements containing the closest parent element that matches the specified selector, the starting element included.
+ /// </summary>
+ /// <param name="selectors" type="String">
+ /// A string containing a selector expression to match elements against.
+ /// </param>
+ /// <param name="context" type="Element">
+ /// A DOM element within which a matching element may be found. If no context is passed
+ /// in then the context of the jQuery set will be used instead.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ if ( jQuery.isArray( selectors ) ) {
+ var ret = [], cur = this[0], match, matches = {}, selector;
+
+ if ( cur && selectors.length ) {
+ for ( var i = 0, l = selectors.length; i < l; i++ ) {
+ selector = selectors[i];
+
+ if ( !matches[selector] ) {
+ matches[selector] = jQuery.expr.match.POS.test( selector ) ?
+ jQuery( selector, context || this.context ) :
+ selector;
+ }
+ }
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( selector in matches ) {
+ match = matches[selector];
+
+ if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+ ret.push({ selector: selector, elem: cur });
+ delete matches[selector];
+ }
+ }
+ cur = cur.parentNode;
+ }
+ }
+
+ return ret;
+ }
+
+ var pos = jQuery.expr.match.POS.test( selectors ) ?
+ jQuery( selectors, context || this.context ) : null;
+
+ return this.map(function( i, cur ) {
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
+ return cur;
+ }
+ cur = cur.parentNode;
+ }
+ return null;
+ });
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ /// <summary>
+ /// Searches every matched element for the object and returns
+ /// the index of the element, if found, starting with zero.
+ /// Returns -1 if the object wasn't found.
+ /// Part of Core
+ /// </summary>
+ /// <returns type="Number" />
+ /// <param name="elem" type="Element">
+ /// Object to search for
+ /// </param>
+
+ if ( !elem || typeof elem === "string" ) {
+ return jQuery.inArray( this[0],
+ // If it receives a string, the selector is used
+ // If it receives nothing, the siblings are used
+ elem ? jQuery( elem ) : this.parent().children() );
+ }
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ /// <summary>
+ /// Adds one or more Elements to the set of matched elements.
+ /// Part of DOM/Traversing
+ /// </summary>
+ /// <param name="selector" type="String">
+ /// A string containing a selector expression to match additional elements against.
+ /// </param>
+ /// <param name="context" type="Element">
+ /// Add some elements rooted against the specified context.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var set = typeof selector === "string" ?
+ jQuery( selector, context || this.context ) :
+ jQuery.makeArray( selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ /// <summary>
+ /// Adds the previous selection to the current selection.
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, slice.call(arguments).join(",") );
+ };
+});
+
+jQuery.fn[ "parentsUntil" ] = function( until, selector ) {
+ /// <summary>
+ /// Get the ancestors of each element in the current set of matched elements, up to but not
+ /// including the element matched by the selector.
+ /// </summary>
+ /// <param name="until" type="String">
+ /// A string containing a selector expression to indicate where to stop matching ancestor
+ /// elements.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var fn = function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ }
+
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( "parentsUntil" ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "parentsUntil" ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, "parentsUntil", slice.call(arguments).join(",") );
+};
+
+jQuery.fn[ "nextUntil" ] = function( until, selector ) {
+ /// <summary>
+ /// Get all following siblings of each element up to but not including the element matched
+ /// by the selector.
+ /// </summary>
+ /// <param name="until" type="String">
+ /// A string containing a selector expression to indicate where to stop matching following
+ /// sibling elements.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var fn = function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ }
+
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( "nextUntil" ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "nextUntil" ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, "nextUntil", slice.call(arguments).join(",") );
+};
+
+jQuery.fn[ "prevUntil" ] = function( until, selector ) {
+ /// <summary>
+ /// Get all preceding siblings of each element up to but not including the element matched
+ /// by the selector.
+ /// </summary>
+ /// <param name="until" type="String">
+ /// A string containing a selector expression to indicate where to stop matching preceding
+ /// sibling elements.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var fn = function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ }
+
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( "prevUntil" ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( "prevUntil" ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, "prevUntil", slice.call(arguments).join(",") );
+};
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ /// <summary>
+ /// This member is internal only.
+ /// </summary>
+ /// <private />
+
+ var matched = [], cur = elem[dir];
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ /// <summary>
+ /// This member is internal only.
+ /// </summary>
+ /// <private />
+
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ /// <summary>
+ /// This member is internal only.
+ /// </summary>
+ /// <private />
+
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
+ rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&\w+;/,
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)
+ fcloseTag = function( all, front, tag ) {
+ return rselfClosing.test( tag ) ?
+ all :
+ front + "></" + tag + ">";
+ },
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ /// <summary>
+ /// Set the text contents of all matched elements.
+ /// Similar to html(), but escapes HTML (replace &quot;&lt;&quot; and &quot;&gt;&quot; with their
+ /// HTML entities).
+ /// Part of DOM/Attributes
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="text" type="String">
+ /// The text value to set the contents of the element to.
+ /// </param>
+
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.getText( this );
+ },
+
+ wrapAll: function( html ) {
+ /// <summary>
+ /// Wrap all matched elements with a structure of other elements.
+ /// This wrapping process is most useful for injecting additional
+ /// stucture into a document, without ruining the original semantic
+ /// qualities of a document.
+ /// This works by going through the first element
+ /// provided and finding the deepest ancestor element within its
+ /// structure - it is that element that will en-wrap everything else.
+ /// This does not work with elements that contain text. Any necessary text
+ /// must be added after the wrapping is done.
+ /// Part of DOM/Manipulation
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="html" type="Element">
+ /// A DOM element that will be wrapped around the target.
+ /// </param>
+
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ /// <summary>
+ /// Wraps the inner child contents of each matched elemenht (including text nodes) with an HTML structure.
+ /// </summary>
+ /// <param name="html" type="String">
+ /// A string of HTML or a DOM element that will be wrapped around the target contents.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ), contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ /// <summary>
+ /// Wrap all matched elements with a structure of other elements.
+ /// This wrapping process is most useful for injecting additional
+ /// stucture into a document, without ruining the original semantic
+ /// qualities of a document.
+ /// This works by going through the first element
+ /// provided and finding the deepest ancestor element within its
+ /// structure - it is that element that will en-wrap everything else.
+ /// This does not work with elements that contain text. Any necessary text
+ /// must be added after the wrapping is done.
+ /// Part of DOM/Manipulation
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="html" type="Element">
+ /// A DOM element that will be wrapped around the target.
+ /// </param>
+
+ return this.each(function() {
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ unwrap: function() {
+ /// <summary>
+ /// Remove the parents of the set of matched elements from the DOM, leaving the matched
+ /// elements in their place.
+ /// </summary>
+ /// <returns type="jQuery" />
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ /// <summary>
+ /// Append content to the inside of every matched element.
+ /// This operation is similar to doing an appendChild to all the
+ /// specified elements, adding them into the document.
+ /// Part of DOM/Manipulation
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ /// <summary>
+ /// Prepend content to the inside of every matched element.
+ /// This operation is the best way to insert elements
+ /// inside, at the beginning, of all matched elements.
+ /// Part of DOM/Manipulation
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ /// <summary>
+ /// Insert content before each of the matched elements.
+ /// Part of DOM/Manipulation
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery(arguments[0]);
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ /// <summary>
+ /// Insert content after each of the matched elements.
+ /// Part of DOM/Manipulation
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery(arguments[0]).toArray() );
+ return set;
+ }
+ },
+
+ clone: function( events ) {
+ /// <summary>
+ /// Clone matched DOM Elements and select the clones.
+ /// This is useful for moving copies of the elements to another
+ /// location in the DOM.
+ /// Part of DOM/Manipulation
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="deep" type="Boolean" optional="true">
+ /// (Optional) Set to false if you don't want to clone all descendant nodes, in addition to the element itself.
+ /// </param>
+
+ // Do the clone
+ var ret = this.map(function() {
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var html = this.outerHTML, ownerDocument = this.ownerDocument;
+ if ( !html ) {
+ var div = ownerDocument.createElement("div");
+ div.appendChild( this.cloneNode(true) );
+ html = div.innerHTML;
+ }
+
+ return jQuery.clean([html.replace(rinlinejQuery, "")
+ .replace(rleadingWhitespace, "")], ownerDocument)[0];
+ } else {
+ return this.cloneNode(true);
+ }
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true ) {
+ cloneCopyEvent( this, ret );
+ cloneCopyEvent( this.find("*"), ret.find("*") );
+ }
+
+ // Return the cloned set
+ return ret;
+ },
+
+ html: function( value ) {
+ /// <summary>
+ /// Set the html contents of every matched element.
+ /// This property is not available on XML documents.
+ /// Part of DOM/Attributes
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="value" type="String">
+ /// A string of HTML to set as the content of each matched element.
+ /// </param>
+
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !/<script/i.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, fcloseTag);
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery(this), old = self.html();
+ self.empty().append(function(){
+ return value.call( this, i, old );
+ });
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ /// <summary>
+ /// Replaces all matched element with the specified HTML or DOM elements.
+ /// </summary>
+ /// <param name="value" type="Object">
+ /// The content to insert. May be an HTML string, DOM element, or jQuery object.
+ /// </param>
+ /// <returns type="jQuery">The element that was just replaced.</returns>
+
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( !jQuery.isFunction( value ) ) {
+ value = jQuery( value ).detach();
+
+ } else {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling, parent = this.parentNode;
+
+ jQuery(this).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+ }
+ },
+
+ detach: function( selector ) {
+ /// <summary>
+ /// Remove the set of matched elements from the DOM.
+ /// </summary>
+ /// <param name="selector" type="String">
+ /// A selector expression that filters the set of matched elements to be removed.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ /// <param name="args" type="Array">
+ /// Args
+ /// </param>
+ /// <param name="table" type="Boolean">
+ /// Insert TBODY in TABLEs if one is not found.
+ /// </param>
+ /// <param name="dir" type="Number">
+ /// If dir&lt;0, process args in reverse order.
+ /// </param>
+ /// <param name="fn" type="Function">
+ /// The function doing the DOM manipulation.
+ /// </param>
+ /// <returns type="jQuery" />
+ /// <summary>
+ /// Part of Core
+ /// </summary>
+
+ var results, first, value = args[0], scripts = [];
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ // If we're in a fragment, just use that instead of building a new one
+ if ( args[0] && args[0].parentNode && args[0].parentNode.nodeType === 11 ) {
+ results = { fragment: args[0].parentNode };
+ } else {
+ results = buildFragment( args, this, scripts );
+ }
+
+ first = results.fragment.firstChild;
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ results.cacheable || this.length > 1 || i > 0 ?
+ results.fragment.cloneNode(true) :
+ results.fragment
+ );
+ }
+ }
+
+ if ( scripts ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+
+ function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+ }
+ }
+});
+
+function cloneCopyEvent(orig, ret) {
+ var i = 0;
+
+ ret.each(function() {
+ if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+ return;
+ }
+
+ var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( var type in events ) {
+ for ( var handler in events[ type ] ) {
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ }
+ }
+ }
+ });
+}
+
+function buildFragment( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults, doc;
+
+ // webkit does not clone 'checked' attribute of radio inputs on cloneNode, so don't cache if string has a checked
+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+ cacheable = true;
+ cacheresults = jQuery.fragments[ args[0] ];
+ if ( cacheresults ) {
+ if ( cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+ }
+
+ if ( !fragment ) {
+ doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+}
+
+jQuery.fragments = {};
+
+// jQuery.each({
+// appendTo: "append",
+// prependTo: "prepend",
+// insertBefore: "before",
+// insertAfter: "after",
+// replaceAll: "replaceWith"
+// }, function( name, original ) {
+// jQuery.fn[ name ] = function( selector ) {
+// var ret = [], insert = jQuery( selector );
+
+// for ( var i = 0, l = insert.length; i < l; i++ ) {
+// var elems = (i > 0 ? this.clone(true) : this).get();
+// jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+// ret = ret.concat( elems );
+// }
+// return this.pushStack( ret, name, insert.selector );
+// };
+// });
+
+jQuery.fn[ "appendTo" ] = function( selector ) {
+ /// <summary>
+ /// Append all of the matched elements to another, specified, set of elements.
+ /// As of jQuery 1.3.2, returns all of the inserted elements.
+ /// This operation is, essentially, the reverse of doing a regular
+ /// $(A).append(B), in that instead of appending B to A, you're appending
+ /// A to B.
+ /// </summary>
+ /// <param name="selector" type="Selector">
+ /// target to which the content will be appended.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ "append" ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+ return this.pushStack( ret, "appendTo", insert.selector );
+};
+
+jQuery.fn[ "prependTo" ] = function( selector ) {
+ /// <summary>
+ /// Prepend all of the matched elements to another, specified, set of elements.
+ /// As of jQuery 1.3.2, returns all of the inserted elements.
+ /// This operation is, essentially, the reverse of doing a regular
+ /// $(A).prepend(B), in that instead of prepending B to A, you're prepending
+ /// A to B.
+ /// </summary>
+ /// <param name="selector" type="Selector">
+ /// target to which the content will be appended.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ "prepend" ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+ return this.pushStack( ret, "prependTo", insert.selector );
+};
+
+jQuery.fn[ "insertBefore" ] = function( selector ) {
+ /// <summary>
+ /// Insert all of the matched elements before another, specified, set of elements.
+ /// As of jQuery 1.3.2, returns all of the inserted elements.
+ /// This operation is, essentially, the reverse of doing a regular
+ /// $(A).before(B), in that instead of inserting B before A, you're inserting
+ /// A before B.
+ /// </summary>
+ /// <param name="content" type="String">
+ /// Content after which the selected element(s) is inserted.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ "before" ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+ return this.pushStack( ret, "insertBefore", insert.selector );
+};
+
+jQuery.fn[ "insertAfter" ] = function( selector ) {
+ /// <summary>
+ /// Insert all of the matched elements after another, specified, set of elements.
+ /// As of jQuery 1.3.2, returns all of the inserted elements.
+ /// This operation is, essentially, the reverse of doing a regular
+ /// $(A).after(B), in that instead of inserting B after A, you're inserting
+ /// A after B.
+ /// </summary>
+ /// <param name="content" type="String">
+ /// Content after which the selected element(s) is inserted.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ "after" ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+ return this.pushStack( ret, "insertAfter", insert.selector );
+};
+
+jQuery.fn[ "replaceAll" ] = function( selector ) {
+ /// <summary>
+ /// Replaces the elements matched by the specified selector with the matched elements.
+ /// As of jQuery 1.3.2, returns all of the inserted elements.
+ /// </summary>
+ /// <param name="selector" type="Selector">The elements to find and replace the matched elements with.</param>
+ /// <returns type="jQuery" />
+
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ "replaceWith" ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+ return this.pushStack( ret, "replaceAll", insert.selector );
+};
+
+jQuery.each({
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
+ if ( !keepData && this.nodeType === 1 ) {
+ jQuery.cleanData( this.getElementsByTagName("*") );
+ jQuery.cleanData( [ this ] );
+ }
+
+ if ( this.parentNode ) {
+ this.parentNode.removeChild( this );
+ }
+ }
+ },
+
+ empty: function() {
+ /// <summary>
+ /// Removes all child nodes from the set of matched elements.
+ /// Part of DOM/Manipulation
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ // Remove element nodes and prevent memory leaks
+ if ( this.nodeType === 1 ) {
+ jQuery.cleanData( this.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( this.firstChild ) {
+ this.removeChild( this.firstChild );
+ }
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function() {
+ return this.each( fn, arguments );
+ };
+});
+
+jQuery.extend({
+ clean: function( elems, context, fragment, scripts ) {
+ /// <summary>
+ /// This method is internal only.
+ /// </summary>
+ /// <private />
+
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [];
+
+ jQuery.each(elems, function( i, elem ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ return;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+
+ } else if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, fcloseTag);
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+
+ });
+
+ if ( fragment ) {
+ for ( var i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ for ( var i = 0, elem, id; (elem = elems[i]) != null; i++ ) {
+ jQuery.event.remove( elem );
+ jQuery.removeData( elem );
+ }
+ }
+});
+// exclude the following css properties to add px
+var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+ ralpha = /alpha\([^)]*\)/,
+ ropacity = /opacity=([^)]*)/,
+ rfloat = /float/i,
+ rdashAlpha = /-([a-z])/ig,
+ rupper = /([A-Z])/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+
+ cssShow = { position: "absolute", visibility: "hidden", display:"block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+
+ // cache check for defaultView.getComputedStyle
+ getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+ // normalize float css property
+ styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn.css = function( name, value ) {
+ /// <summary>
+ /// Set a single style property to a value, on all matched elements.
+ /// If a number is provided, it is automatically converted into a pixel value.
+ /// Part of CSS
+ /// </summary>
+ /// <returns type="jQuery" />
+ /// <param name="name" type="String">
+ /// A CSS property name.
+ /// </param>
+ /// <param name="value" type="String">
+ /// A value to set for the property.
+ /// </param>
+
+ return access( this, name, value, true, function( elem, name, value ) {
+ if ( value === undefined ) {
+ return jQuery.curCSS( elem, name );
+ }
+
+ if ( typeof value === "number" && !rexclude.test(name) ) {
+ value += "px";
+ }
+
+ jQuery.style( elem, name, value );
+ });
+};
+
+jQuery.extend({
+ style: function( elem, name, value ) {
+ // don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // ignore negative width and height values #1599
+ if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
+ value = undefined;
+ }
+
+ var style = elem.style || elem, set = value !== undefined;
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name === "opacity" ) {
+ if ( set ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
+ var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
+ style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
+ }
+
+ return style.filter && style.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
+ "";
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( rfloat.test( name ) ) {
+ name = styleFloat;
+ }
+
+ name = name.replace(rdashAlpha, fcamelCase);
+
+ if ( set ) {
+ style[ name ] = value;
+ }
+
+ return style[ name ];
+ },
+
+ css: function( elem, name, force, extra ) {
+ /// <summary>
+ /// This method is internal only.
+ /// </summary>
+ /// <private />
+
+ if ( name === "width" || name === "height" ) {
+ var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
+
+ function getWH() {
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" ) {
+ return;
+ }
+
+ jQuery.each( which, function() {
+ if ( !extra ) {
+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ }
+
+ if ( extra === "margin" ) {
+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+ } else {
+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ }
+ });
+ }
+
+ if ( elem.offsetWidth !== 0 ) {
+ getWH();
+ } else {
+ jQuery.swap( elem, props, getWH );
+ }
+
+ return Math.max(0, Math.round(val));
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ /// <summary>
+ /// This method is internal only.
+ /// </summary>
+ /// <private />
+
+ var ret, style = elem.style, filter;
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
+ ret = ropacity.test(elem.currentStyle.filter || "") ?
+ (parseFloat(RegExp.$1) / 100) + "" :
+ "";
+
+ return ret === "" ?
+ "1" :
+ ret;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( rfloat.test( name ) ) {
+ name = styleFloat;
+ }
+
+ if ( !force && style && style[ name ] ) {
+ ret = style[ name ];
+
+ } else if ( getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( rfloat.test( name ) ) {
+ name = "float";
+ }
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ var defaultView = elem.ownerDocument.defaultView;
+
+ if ( !defaultView ) {
+ return null;
+ }
+
+ var computedStyle = defaultView.getComputedStyle( elem, null );
+
+ if ( computedStyle ) {
+ ret = computedStyle.getPropertyValue( name );
+ }
+
+ // We should always get a number back from opacity
+ if ( name === "opacity" && ret === "" ) {
+ ret = "1";
+ }
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(rdashAlpha, fcamelCase);
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+ // Remember the original values
+ var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret;
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ /// <summary>
+ /// Swap in/out style options.
+ /// </summary>
+
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth, height = elem.offsetHeight,
+ skip = elem.nodeName.toLowerCase() === "tr";
+
+ return width === 0 && height === 0 && !skip ?
+ true :
+ width > 0 && height > 0 && !skip ?
+ false :
+ jQuery.curCSS(elem, "display") === "none";
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+var jsc = now(),
+ rscript = /<script(.|\s)*?\/script>/gi,
+ rselectTextarea = /select|textarea/i,
+ rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
+ jsre = /=\?(&|$)/,
+ rquery = /\?/,
+ rts = /(\?|&)_=.*?(&|$)/,
+ rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+ r20 = /%20/g;
+
+jQuery.fn.extend({
+ // Keep a copy of the old load
+ _load: jQuery.fn.load,
+
+ load: function( url, params, callback ) {
+ /// <summary>
+ /// Loads HTML from a remote file and injects it into the DOM. By default performs a GET request, but if parameters are included
+ /// then a POST will be performed.
+ /// </summary>
+ /// <param name="url" type="String">The URL of the HTML page to load.</param>
+ /// <param name="data" optional="true" type="Map">Key/value pairs that will be sent to the server.</param>
+ /// <param name="callback" optional="true" type="Function">The function called when the AJAX request is complete. It should map function(responseText, textStatus, XMLHttpRequest) such that this maps the injected DOM element.</param>
+ /// <returns type="jQuery" />
+
+ if ( typeof url !== "string" ) {
+ return this._load( url );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function( res, status ) {
+ // If successful, inject the HTML into all the matched elements
+ if ( status === "success" || status === "notmodified" ) {
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div />")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [res.responseText, status, res] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ /// <summary>
+ /// Serializes a set of input elements into a string of data.
+ /// </summary>
+ /// <returns type="String">The serialized result</returns>
+
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ /// <summary>
+ /// Serializes all forms and form elements but returns a JSON data structure.
+ /// </summary>
+ /// <returns type="String">A JSON data structure representing the serialized items.</returns>
+
+ return this.map(function() {
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function() {
+ return this.name && !this.disabled &&
+ (this.checked || rselectTextarea.test(this.nodeName) ||
+ rinput.test(this.type));
+ })
+ .map(function( i, elem ) {
+ var val = jQuery(this).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function( val, i ) {
+ return { name: elem.name, value: val };
+ }) :
+ { name: elem.name, value: val };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+// jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+// jQuery.fn[o] = function( f ) {
+// return this.bind(o, f);
+// };
+// });
+
+jQuery.fn["ajaxStart"] = function( f ) {
+ /// <summary>
+ /// Attach a function to be executed whenever an AJAX request begins and there is none already active. This is an Ajax Event.
+ /// </summary>
+ /// <param name="f" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return this.bind("ajaxStart", f);
+};
+
+jQuery.fn["ajaxStop"] = function( f ) {
+ /// <summary>
+ /// Attach a function to be executed whenever all AJAX requests have ended. This is an Ajax Event.
+ /// </summary>
+ /// <param name="f" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return this.bind("ajaxStop", f);
+};
+
+jQuery.fn["ajaxComplete"] = function( f ) {
+ /// <summary>
+ /// Attach a function to be executed whenever an AJAX request completes. This is an Ajax Event.
+ /// </summary>
+ /// <param name="f" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return this.bind("ajaxComplete", f);
+};
+
+jQuery.fn["ajaxError"] = function( f ) {
+ /// <summary>
+ /// Attach a function to be executed whenever an AJAX request fails. This is an Ajax Event.
+ /// </summary>
+ /// <param name="f" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return this.bind("ajaxError", f);
+};
+
+jQuery.fn["ajaxSuccess"] = function( f ) {
+ /// <summary>
+ /// Attach a function to be executed whenever an AJAX request completes successfully. This is an Ajax Event.
+ /// </summary>
+ /// <param name="f" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return this.bind("ajaxSuccess", f);
+};
+
+jQuery.fn["ajaxSend"] = function( f ) {
+ /// <summary>
+ /// Attach a function to be executed before an AJAX request is sent. This is an Ajax Event.
+ /// </summary>
+ /// <param name="f" type="Function">The function to execute.</param>
+ /// <returns type="jQuery" />
+
+ return this.bind("ajaxSend", f);
+};
+
+jQuery.extend({
+
+ get: function( url, data, callback, type ) {
+ /// <summary>
+ /// Loads a remote page using an HTTP GET request.
+ /// </summary>
+ /// <param name="url" type="String">The URL of the HTML page to load.</param>
+ /// <param name="data" optional="true" type="Map">Key/value pairs that will be sent to the server.</param>
+ /// <param name="callback" optional="true" type="Function">The function called when the AJAX request is complete. It should map function(responseText, textStatus) such that this maps the options for this AJAX request.</param>
+ /// <param name="type" optional="true" type="String">Type of data to be returned to callback function. Valid valiues are xml, html, script, json, text, _default.</param>
+ /// <returns type="XMLHttpRequest" />
+
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ /// <summary>
+ /// Loads and executes a local JavaScript file using an HTTP GET request.
+ /// </summary>
+ /// <param name="url" type="String">The URL of the script to load.</param>
+ /// <param name="callback" optional="true" type="Function">The function called when the AJAX request is complete. It should map function(data, textStatus) such that this maps the options for the AJAX request.</param>
+ /// <returns type="XMLHttpRequest" />
+
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ /// <summary>
+ /// Loads JSON data using an HTTP GET request.
+ /// </summary>
+ /// <param name="url" type="String">The URL of the JSON data to load.</param>
+ /// <param name="data" optional="true" type="Map">Key/value pairs that will be sent to the server.</param>
+ /// <param name="callback" optional="true" type="Function">The function called when the AJAX request is complete if the data is loaded successfully. It should map function(data, textStatus) such that this maps the options for this AJAX request.</param>
+ /// <returns type="XMLHttpRequest" />
+
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ /// <summary>
+ /// Loads a remote page using an HTTP POST request.
+ /// </summary>
+ /// <param name="url" type="String">The URL of the HTML page to load.</param>
+ /// <param name="data" optional="true" type="Map">Key/value pairs that will be sent to the server.</param>
+ /// <param name="callback" optional="true" type="Function">The function called when the AJAX request is complete. It should map function(responseText, textStatus) such that this maps the options for this AJAX request.</param>
+ /// <param name="type" optional="true" type="String">Type of data to be returned to callback function. Valid valiues are xml, html, script, json, text, _default.</param>
+ /// <returns type="XMLHttpRequest" />
+
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ /// <summary>
+ /// Sets up global settings for AJAX requests.
+ /// </summary>
+ /// <param name="settings" type="Options">A set of key/value pairs that configure the default Ajax request.</param>
+
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ traditional: false,
+ */
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7 (can't request local files),
+ // so we use the ActiveXObject when it is available
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
+ function() {
+ return new window.XMLHttpRequest();
+ } :
+ function() {
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch(e) {}
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ ajax: function( origSettings ) {
+ /// <summary>
+ /// Load a remote page using an HTTP request.
+ /// </summary>
+ /// <private />
+
+ var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
+
+ var jsonp, status, data,
+ callbackContext = origSettings && origSettings.context || s,
+ type = s.type.toUpperCase();
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType === "jsonp" ) {
+ if ( type === "GET" ) {
+ if ( !jsre.test( s.url ) ) {
+ s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ }
+ } else if ( !s.data || !jsre.test(s.data) ) {
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ }
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+ jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data ) {
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ }
+
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = window[ jsonp ] || function( tmp ) {
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+
+ try {
+ delete window[ jsonp ];
+ } catch(e) {}
+
+ if ( head ) {
+ head.removeChild( script );
+ }
+ };
+ }
+
+ if ( s.dataType === "script" && s.cache === null ) {
+ s.cache = false;
+ }
+
+ if ( s.cache === false && type === "GET" ) {
+ var ts = now();
+
+ // try replacing _= if it is there
+ var ret = s.url.replace(rts, "$1_=" + ts + "$2");
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && type === "GET" ) {
+ s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // Matches an absolute URL, and saves the domain
+ var parts = rurl.exec( s.url ),
+ remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType === "script" && type === "GET" && remote ) {
+ var head = document.getElementsByTagName("head")[0] || document.documentElement;
+ var script = document.createElement("script");
+ script.src = s.url;
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function() {
+ if ( !done && (!this.readyState ||
+ this.readyState === "loaded" || this.readyState === "complete") ) {
+ done = true;
+ success();
+ complete();
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+ }
+ };
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ if ( !xhr ) {
+ return;
+ }
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ } else {
+ xhr.open(type, s.url, s.async);
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data || origSettings && origSettings.contentType ) {
+ xhr.setRequestHeader("Content-Type", s.contentType);
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[s.url] ) {
+ xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+ }
+
+ if ( jQuery.etag[s.url] ) {
+ xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+ }
+ }
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ // Only send the header if it's not a remote XHR
+ if ( !remote ) {
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e) {}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global ) {
+ trigger("ajaxSend", [xhr, s]);
+ }
+
+ // Wait for a response to come back
+ var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+ // The request was aborted
+ if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+ // Opera doesn't call onreadystatechange before this point
+ // so we simulate the call
+ if ( !requestDone ) {
+ complete();
+ }
+
+ requestDone = true;
+ if ( xhr ) {
+ xhr.onreadystatechange = jQuery.noop;
+ }
+
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+ requestDone = true;
+ xhr.onreadystatechange = jQuery.noop;
+
+ status = isTimeout === "timeout" ?
+ "timeout" :
+ !jQuery.httpSuccess( xhr ) ?
+ "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+ "notmodified" :
+ "success";
+
+ var errMsg;
+
+ if ( status === "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch(err) {
+ status = "parsererror";
+ errMsg = err;
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status === "success" || status === "notmodified" ) {
+ // JSONP handles its own success callback
+ if ( !jsonp ) {
+ success();
+ }
+ } else {
+ jQuery.handleError(s, xhr, status, errMsg);
+ }
+
+ // Fire the complete handlers
+ complete();
+
+ if ( isTimeout === "timeout" ) {
+ xhr.abort();
+ }
+
+ // Stop memory leaks
+ if ( s.async ) {
+ xhr = null;
+ }
+ }
+ };
+
+ // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
+ // Opera doesn't fire onreadystatechange at all on abort
+ try {
+ var oldAbort = xhr.abort;
+ xhr.abort = function() {
+ if ( xhr ) {
+ oldAbort.call( xhr );
+ }
+
+ onreadystatechange( "abort" );
+ };
+ } catch(e) { }
+
+ // Timeout checker
+ if ( s.async && s.timeout > 0 ) {
+ setTimeout(function() {
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone ) {
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
+ } catch(e) {
+ jQuery.handleError(s, xhr, null, e);
+ // Fire the complete handlers
+ complete();
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async ) {
+ onreadystatechange();
+ }
+
+ function success() {
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success ) {
+ s.success.call( callbackContext, data, status, xhr );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ trigger( "ajaxSuccess", [xhr, s] );
+ }
+ }
+
+ function complete() {
+ // Process result
+ if ( s.complete ) {
+ s.complete.call( callbackContext, xhr, status);
+ }
+
+ // The request was completed
+ if ( s.global ) {
+ trigger( "ajaxComplete", [xhr, s] );
+ }
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+
+ function trigger(type, args) {
+ (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ handleError: function( s, xhr, status, e ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ // If a local callback was specified, fire it
+ if ( s.error ) {
+ s.error.call( s.context || s, xhr, status, e );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
+ }
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol === "file:" ||
+ // Opera returns 0 when status is 304
+ ( xhr.status >= 200 && xhr.status < 300 ) ||
+ xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
+ } catch(e) {}
+
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ var lastModified = xhr.getResponseHeader("Last-Modified"),
+ etag = xhr.getResponseHeader("Etag");
+
+ if ( lastModified ) {
+ jQuery.lastModified[url] = lastModified;
+ }
+
+ if ( etag ) {
+ jQuery.etag[url] = etag;
+ }
+
+ // Opera returns 0 when status is 304
+ return xhr.status === 304 || xhr.status === 0;
+ },
+
+ httpData: function( xhr, type, s ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ var ct = xhr.getResponseHeader("content-type") || "",
+ xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.nodeName === "parsererror" ) {
+ jQuery.error( "parsererror" );
+ }
+
+ // Allow a pre-filtering function to sanitize the response
+ // s is checked to keep backwards compatibility
+ if ( s && s.dataFilter ) {
+ data = s.dataFilter( data, type );
+ }
+
+ // The filter can actually parse the response
+ if ( typeof data === "string" ) {
+ // Get the JavaScript object, if JSON is used.
+ if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+ data = jQuery.parseJSON( data );
+
+ // If the type is "script", eval it in global context
+ } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+ jQuery.globalEval( data );
+ }
+ }
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ /// <summary>
+ /// Create a serialized representation of an array or object, suitable for use in a URL
+ /// query string or Ajax request.
+ /// </summary>
+ /// <param name="a" type="Object">
+ /// An array or object to serialize.
+ /// </param>
+ /// <param name="traditional" type="Boolean">
+ /// A Boolean indicating whether to perform a traditional "shallow" serialization.
+ /// </param>
+ /// <returns type="String" />
+
+ var s = [];
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray(a) || a.jquery ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[prefix] );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join("&").replace(r20, "+");
+
+ function buildParams( prefix, obj ) {
+ if ( jQuery.isArray(obj) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ // Serialize object item.
+ jQuery.each( obj, function( k, v ) {
+ buildParams( prefix + "[" + k + "]", v );
+ });
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+ }
+
+ function add( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction(value) ? value() : value;
+ s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+ }
+ }
+});
+var elemdisplay = {},
+ rfxtypes = /toggle|show|hide/,
+ rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+jQuery.fn.extend({
+ show: function( speed, callback ) {
+ /// <summary>
+ /// Show all matched elements using a graceful animation and firing an optional callback after completion.
+ /// </summary>
+ /// <param name="speed" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ if ( speed || speed === 0) {
+ return this.animate( genFx("show", 3), speed, callback);
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var old = jQuery.data(this[i], "olddisplay");
+
+ this[i].style.display = old || "";
+
+ if ( jQuery.css(this[i], "display") === "none" ) {
+ var nodeName = this[i].nodeName, display;
+
+ if ( elemdisplay[ nodeName ] ) {
+ display = elemdisplay[ nodeName ];
+
+ } else {
+ var elem = jQuery("<" + nodeName + " />").appendTo("body");
+
+ display = elem.css("display");
+
+ if ( display === "none" ) {
+ display = "block";
+ }
+
+ elem.remove();
+
+ elemdisplay[ nodeName ] = display;
+ }
+
+ jQuery.data(this[i], "olddisplay", display);
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var j = 0, k = this.length; j < k; j++ ) {
+ this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, callback ) {
+ /// <summary>
+ /// Hides all matched elements using a graceful animation and firing an optional callback after completion.
+ /// </summary>
+ /// <param name="speed" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, callback);
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var old = jQuery.data(this[i], "olddisplay");
+ if ( !old && old !== "none" ) {
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var j = 0, k = this.length; j < k; j++ ) {
+ this[j].style.display = "none";
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ) {
+ /// <summary>
+ /// Toggles displaying each of the set of matched elements.
+ /// </summary>
+ /// <returns type="jQuery" />
+
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, callback ) {
+ /// <summary>
+ /// Fades the opacity of all matched elements to a specified opacity.
+ /// </summary>
+ /// <param name="speed" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ /// <summary>
+ /// A function for making custom animations.
+ /// </summary>
+ /// <param name="prop" type="Options">A set of style attributes that you wish to animate and to what end.</param>
+ /// <param name="speed" optional="true" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="easing" optional="true" type="String">The name of the easing effect that you want to use. There are two built-in values, 'linear' and 'swing'.</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ var optall = jQuery.speed(speed, easing, callback);
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete );
+ }
+
+ return this[ optall.queue === false ? "each" : "queue" ](function() {
+ var opt = jQuery.extend({}, optall), p,
+ hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ var name = p.replace(rdashAlpha, fcamelCase);
+
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ p = name;
+ }
+
+ if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+ return opt.complete.call(this);
+ }
+
+ if ( ( p === "height" || p === "width" ) && this.style ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+
+ if ( jQuery.isArray( prop[p] ) ) {
+ // Create (if needed) and add to specialEasing
+ (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+ prop[p] = prop[p][0];
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function( name, val ) {
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( rfxtypes.test(val) ) {
+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
+ } else {
+ var parts = rfxnum.exec(val),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat( parts[2] ),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function( clearQueue, gotoEnd ) {
+ /// <summary>
+ /// Stops all currently animations on the specified elements.
+ /// </summary>
+ /// <param name="clearQueue" optional="true" type="Boolean">True to clear animations that are queued to run.</param>
+ /// <param name="gotoEnd" optional="true" type="Boolean">True to move the element value to the end of its animation target.</param>
+ /// <returns type="jQuery" />
+
+ var timers = jQuery.timers;
+
+ if ( clearQueue ) {
+ this.queue([]);
+ }
+
+ this.each(function() {
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- ) {
+ if ( timers[i].elem === this ) {
+ if (gotoEnd) {
+ // force the next step to be the last
+ timers[i](true);
+ }
+
+ timers.splice(i, 1);
+ }
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if ( !gotoEnd ) {
+ this.dequeue();
+ }
+
+ return this;
+ }
+
+});
+
+// Generate shortcuts for custom animations
+// jQuery.each({
+// slideDown: genFx("show", 1),
+// slideUp: genFx("hide", 1),
+// slideToggle: genFx("toggle", 1),
+// fadeIn: { opacity: "show" },
+// fadeOut: { opacity: "hide" }
+// }, function( name, props ) {
+// jQuery.fn[ name ] = function( speed, callback ) {
+// return this.animate( props, speed, callback );
+// };
+// });
+
+jQuery.fn[ "slideDown" ] = function( speed, callback ) {
+ /// <summary>
+ /// Reveal all matched elements by adjusting their height.
+ /// </summary>
+ /// <param name="speed" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ return this.animate( genFx("show", 1), speed, callback );
+};
+
+jQuery.fn[ "slideUp" ] = function( speed, callback ) {
+ /// <summary>
+ /// Hiding all matched elements by adjusting their height.
+ /// </summary>
+ /// <param name="speed" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ return this.animate( genFx("hide", 1), speed, callback );
+};
+
+jQuery.fn[ "slideToggle" ] = function( speed, callback ) {
+ /// <summary>
+ /// Toggles the visibility of all matched elements by adjusting their height.
+ /// </summary>
+ /// <param name="speed" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ return this.animate( genFx("toggle", 1), speed, callback );
+};
+
+jQuery.fn[ "fadeIn" ] = function( speed, callback ) {
+ /// <summary>
+ /// Fades in all matched elements by adjusting their opacity.
+ /// </summary>
+ /// <param name="speed" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ return this.animate( { opacity: "show" }, speed, callback );
+};
+
+jQuery.fn[ "fadeOut" ] = function( speed, callback ) {
+ /// <summary>
+ /// Fades the opacity of all matched elements to a specified opacity.
+ /// </summary>
+ /// <param name="speed" type="String">A string representing one of three predefined speeds ('slow', 'normal', or 'fast'), or
+ /// the number of milliseconds to run the animation</param>
+ /// <param name="callback" optional="true" type="Function">A function to be executed whenever the animation completes, once for each animated element. It should map function callback() such that this is the DOM element being animated.</param>
+ /// <returns type="jQuery" />
+
+ return this.animate( { opacity: "hide" }, speed, callback );
+};
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ /// <summary>
+ /// This member is internal.
+ /// </summary>
+ /// <private />
+
+ var opt = speed && typeof speed === "object" ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function() {
+ if ( opt.queue !== false ) {
+ jQuery(this).dequeue();
+ }
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ /// <summary>
+ /// This member is internal.
+ /// </summary>
+ /// <private />
+
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ /// <summary>
+ /// This member is internal.
+ /// </summary>
+ /// <private />
+
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ /// <summary>
+ /// This member is internal.
+ /// </summary>
+ /// <private />
+
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig ) {
+ options.orig = {};
+ }
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ /// <summary>
+ /// This member is internal.
+ /// </summary>
+ /// <private />
+
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
+ this.elem.style.display = "block";
+ }
+ },
+
+ // Get the current size
+ cur: function( force ) {
+ /// <summary>
+ /// This member is internal.
+ /// </summary>
+ /// <private />
+
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ this.startTime = now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ var self = this;
+ function t( gotoEnd ) {
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval(jQuery.fx.tick, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ /// <summary>
+ /// Displays each of the set of matched elements if they are hidden.
+ /// </summary>
+
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ /// <summary>
+ /// Hides each of the set of matched elements if they are shown.
+ /// </summary>
+
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ var t = now(), done = true;
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ for ( var i in this.options.curAnim ) {
+ if ( this.options.curAnim[i] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ var old = jQuery.data(this.elem, "olddisplay");
+ this.elem.style.display = old ? old : this.options.display;
+
+ if ( jQuery.css(this.elem, "display") === "none" ) {
+ this.elem.style.display = "block";
+ }
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide ) {
+ jQuery(this.elem).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show ) {
+ for ( var p in this.options.curAnim ) {
+ jQuery.style(this.elem, p, this.options.orig[p]);
+ }
+ }
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+ var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+ this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ ) {
+ if ( !timers[i]() ) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style(fx.elem, "opacity", fx.now);
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ /// <summary>
+ /// Set the current coordinates of every element in the set of matched elements,
+ /// relative to the document.
+ /// </summary>
+ /// <param name="options" type="Object">
+ /// An object containing the properties top and left, which are integers indicating the
+ /// new top and left coordinates for the elements.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
+ left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ /// <summary>
+ /// Set the current coordinates of every element in the set of matched elements,
+ /// relative to the document.
+ /// </summary>
+ /// <param name="options" type="Object">
+ /// An object containing the properties top and left, which are integers indicating the
+ /// new top and left coordinates for the elements.
+ /// </param>
+ /// <returns type="jQuery" />
+
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ jQuery.offset.initialize();
+
+ var offsetParent = elem.offsetParent, prevOffsetParent = elem,
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+ body = doc.body, defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop, left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+ initialize: function() {
+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
+ html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+ container.innerHTML = html;
+ body.insertBefore( container, body.firstChild );
+ innerDiv = container.firstChild;
+ checkDiv = innerDiv.firstChild;
+ td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
+ // safari subtracts parent border width here which is 5px
+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+ checkDiv.style.position = checkDiv.style.top = "";
+
+ innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+ body.removeChild( container );
+ body = container = innerDiv = checkDiv = table = td = null;
+ jQuery.offset.initialize = jQuery.noop;
+ },
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop, left = body.offsetLeft;
+
+ jQuery.offset.initialize();
+
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;
+ left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ // set position first, in-case top/left are set even on static elem
+ if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
+ elem.style.position = "relative";
+ }
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,
+ curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ var props = {
+ top: (options.top - curOffset.top) + curTop,
+ left: (options.left - curOffset.left) + curLeft
+ };
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ /// <summary>
+ /// Gets the top and left positions of an element relative to its offset parent.
+ /// </summary>
+ /// <returns type="Object">An object with two integer properties, 'top' and 'left'.</returns>
+
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;
+ offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;
+ parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ /// <summary>
+ /// This method is internal.
+ /// </summary>
+ /// <private />
+
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function(val) {
+ /// <summary>
+ /// Gets and optionally sets the scroll left offset of the first matched element.
+ /// </summary>
+ /// <param name="val" type="Number" integer="true" optional="true">A positive number representing the desired scroll left offset.</param>
+ /// <returns type="Number" integer="true">The scroll left offset of the first matched element.</returns>
+
+ var elem = this[0], win;
+
+ if ( !elem ) {
+ return null;
+ }
+
+ if ( val !== undefined ) {
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery(win).scrollLeft(),
+ i ? val : jQuery(win).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ } else {
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+ };
+});
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function(val) {
+ /// <summary>
+ /// Gets and optionally sets the scroll top offset of the first matched element.
+ /// </summary>
+ /// <param name="val" type="Number" integer="true" optional="true">A positive number representing the desired scroll top offset.</param>
+ /// <returns type="Number" integer="true">The scroll top offset of the first matched element.</returns>
+
+ var elem = this[0], win;
+
+ if ( !elem ) {
+ return null;
+ }
+
+ if ( val !== undefined ) {
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery(win).scrollLeft(),
+ i ? val : jQuery(win).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ } else {
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+ };
+});
+
+function getWindow( elem ) {
+ return ("scrollTo" in elem && elem.document) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function() {
+ /// <summary>
+ /// Gets the inner height of the first matched element, excluding border but including padding.
+ /// </summary>
+ /// <returns type="Number" integer="true">The outer height of the first matched element.</returns>
+
+ return this[0] ?
+ jQuery.css( this[0], type, false, "padding" ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function( margin ) {
+ /// <summary>
+ /// Gets the outer height of the first matched element, including border and padding by default.
+ /// </summary>
+ /// <param name="margins" type="Map">A set of key/value pairs that specify the options for the method.</param>
+ /// <returns type="Number" integer="true">The outer height of the first matched element.</returns>
+
+ return this[0] ?
+ jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ /// <summary>
+ /// Set the CSS height of every matched element. If no explicit unit
+ /// was specified (like 'em' or '%') then &quot;px&quot; is added to the width. If no parameter is specified, it gets
+ /// the current computed pixel height of the first matched element.
+ /// Part of CSS
+ /// </summary>
+ /// <returns type="jQuery" type="jQuery" />
+ /// <param name="cssProperty" type="String">
+ /// Set the CSS property to the specified value. Omit to get the value of the first matched element.
+ /// </param>
+
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+ elem.document.body[ "client" + name ] :
+
+ // Get document width or height
+ (elem.nodeType === 9) ? // is it a document
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ jQuery.css( elem, type ) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function() {
+ /// <summary>
+ /// Gets the inner width of the first matched element, excluding border but including padding.
+ /// </summary>
+ /// <returns type="Number" integer="true">The outer width of the first matched element.</returns>
+
+ return this[0] ?
+ jQuery.css( this[0], type, false, "padding" ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function( margin ) {
+ /// <summary>
+ /// Gets the outer width of the first matched element, including border and padding by default.
+ /// </summary>
+ /// <param name="margin" type="Map">A set of key/value pairs that specify the options for the method.</param>
+ /// <returns type="Number" integer="true">The outer width of the first matched element.</returns>
+
+ return this[0] ?
+ jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ /// <summary>
+ /// Set the CSS width of every matched element. If no explicit unit
+ /// was specified (like 'em' or '%') then &quot;px&quot; is added to the width. If no parameter is specified, it gets
+ /// the current computed pixel width of the first matched element.
+ /// Part of CSS
+ /// </summary>
+ /// <returns type="jQuery" type="jQuery" />
+ /// <param name="cssProperty" type="String">
+ /// Set the CSS property to the specified value. Omit to get the value of the first matched element.
+ /// </param>
+
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+ elem.document.body[ "client" + name ] :
+
+ // Get document width or height
+ (elem.nodeType === 9) ? // is it a document
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ jQuery.css( elem, type ) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});
+
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+})(window);
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1.js b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1.js
new file mode 100644
index 0000000..b5c779c
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1.js
@@ -0,0 +1,6111 @@
+/*!
+ * jQuery JavaScript Library v1.4.1
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * Date: Mon Jan 25 19:43:33 2010 -0500
+ */
+(function( window, undefined ) {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // Use the correct document accordingly with window argument (sandbox)
+ document = window.document,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,
+
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // Has the ready events already been bound?
+ readyBound = false,
+
+ // The functions to execute on DOM ready
+ readyList = [],
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwnProperty = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ indexOf = Array.prototype.indexOf;
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+ }
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ if ( elem ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $("TAG")
+ } else if ( !context && /^\w+$/.test( selector ) ) {
+ this.selector = selector;
+ this.context = document;
+ selector = document.getElementsByTagName( selector );
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return jQuery( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.isArray( selector ) ?
+ this.setArray( selector ) :
+ jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.4.1",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery( elems || null );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Force the current matched set of elements to become
+ // the specified array of elements (destroying the stack in the process)
+ // You should use pushStack() in order to do this, but maintain the stack
+ setArray: function( elems ) {
+ // Resetting the length to 0, then using the native Array push
+ // is a super-fast way to populate an object with array-like properties
+ this.length = 0;
+ push.apply( this, elems );
+
+ return this;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady ) {
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ } else if ( readyList ) {
+ // Add the function to the wait list
+ readyList.push( fn );
+ }
+
+ return this;
+ },
+
+ eq: function( i ) {
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || jQuery(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ // copy reference to target object
+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging object literal values or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
+ var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
+ : jQuery.isArray(copy) ? [] : {};
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // Handle when the DOM is ready
+ ready: function() {
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.isReady ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 13 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If there are functions bound, to execute
+ if ( readyList ) {
+ // Execute all of them
+ var fn, i = 0;
+ while ( (fn = readyList[ i++ ]) ) {
+ fn.call( document, jQuery );
+ }
+
+ // Reset the list of functions
+ readyList = null;
+ }
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.triggerHandler ) {
+ jQuery( document ).triggerHandler( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyBound ) {
+ return;
+ }
+
+ readyBound = true;
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ return jQuery.ready();
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", DOMContentLoaded);
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return toString.call(obj) === "[object Function]";
+ },
+
+ isArray: function( obj ) {
+ return toString.call(obj) === "[object Array]";
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor
+ && !hasOwnProperty.call(obj, "constructor")
+ && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwnProperty.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {
+
+ // Try to use the native JSON parser first
+ return window.JSON && window.JSON.parse ?
+ window.JSON.parse( data ) :
+ (new Function("return " + data))();
+
+ } else {
+ jQuery.error( "Invalid JSON: " + data );
+ }
+ },
+
+ noop: function() {},
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ if ( data && rnotwhite.test(data) ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+
+ if ( jQuery.support.scriptEval ) {
+ script.appendChild( document.createTextNode( data ) );
+ } else {
+ script.text = data;
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction(object);
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+ }
+ }
+
+ return object;
+ },
+
+ trim: function( text ) {
+ return (text || "").replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ if ( array.indexOf ) {
+ return array.indexOf( elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length, j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [];
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ if ( !inv !== !callback( elems[ i ], i ) ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var ret = [], value;
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ proxy: function( fn, proxy, thisObject ) {
+ if ( arguments.length === 2 ) {
+ if ( typeof proxy === "string" ) {
+ thisObject = fn;
+ fn = thisObject[ proxy ];
+ proxy = undefined;
+
+ } else if ( proxy && !jQuery.isFunction( proxy ) ) {
+ thisObject = proxy;
+ proxy = undefined;
+ }
+ }
+
+ if ( !proxy && fn ) {
+ proxy = function() {
+ return fn.apply( thisObject || this, arguments );
+ };
+ }
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ if ( fn ) {
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+ }
+
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
+ /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||
+ /(msie) ([\w.]+)/.exec( ua ) ||
+ !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ browser: {}
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+ jQuery.inArray = function( elem, array ) {
+ return indexOf.call( array, elem );
+ };
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch( error ) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+// Mutifunctional method to get and set values to a collection
+// The value/s can be optionally by executed if its a function
+function access( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : null;
+}
+
+function now() {
+ return (new Date).getTime();
+}
+(function() {
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + now();
+
+ div.style.display = "none";
+ div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType === 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55$/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,
+
+ // Will be defined later
+ checkClone: false,
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null
+ };
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e) {}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function click() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", click);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ div = document.createElement("div");
+ div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild( div.firstChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function() {
+ var div = document.createElement("div");
+ div.style.width = div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+ document.body.removeChild( div ).style.display = 'none';
+ div = null;
+ });
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ var eventSupported = function( eventName ) {
+ var el = document.createElement("div");
+ eventName = "on" + eventName;
+
+ var isSupported = (eventName in el);
+ if ( !isSupported ) {
+ el.setAttribute(eventName, "return;");
+ isSupported = typeof el[eventName] === "function";
+ }
+ el = null;
+
+ return isSupported;
+ };
+
+ jQuery.support.submitBubbles = eventSupported("submit");
+ jQuery.support.changeBubbles = eventSupported("change");
+
+ // release memory in IE
+ root = script = div = all = a = null;
+})();
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ tabindex: "tabIndex",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+};
+var expando = "jQuery" + now(), uuid = 0, windowData = {};
+var emptyObject = {};
+
+jQuery.extend({
+ cache: {},
+
+ expando:expando,
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ "object": true,
+ "applet": true
+ },
+
+ data: function( elem, name, data ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache;
+
+ // Handle the case where there's no name immediately
+ if ( !name && !id ) {
+ return null;
+ }
+
+ // Compute a unique ID for the element
+ if ( !id ) {
+ id = ++uuid;
+ }
+
+ // Avoid generating a new cache unless none exists and we
+ // want to manipulate it.
+ if ( typeof name === "object" ) {
+ elem[ expando ] = id;
+ thisCache = cache[ id ] = jQuery.extend(true, {}, name);
+ } else if ( cache[ id ] ) {
+ thisCache = cache[ id ];
+ } else if ( typeof data === "undefined" ) {
+ thisCache = emptyObject;
+ } else {
+ thisCache = cache[ id ] = {};
+ }
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined ) {
+ elem[ expando ] = id;
+ thisCache[ name ] = data;
+ }
+
+ return typeof name === "string" ? thisCache[ name ] : thisCache;
+ },
+
+ removeData: function( elem, name ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( thisCache ) {
+ // Remove the section of cache data
+ delete thisCache[ name ];
+
+ // If we've removed all the data, remove the element's cache
+ if ( jQuery.isEmptyObject(thisCache) ) {
+ jQuery.removeData( elem );
+ }
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ // Clean up the element expando
+ try {
+ delete elem[ expando ];
+ } catch( e ) {
+ // IE has trouble directly removing the expando
+ // but it's ok with using removeAttribute
+ if ( elem.removeAttribute ) {
+ elem.removeAttribute( expando );
+ }
+ }
+
+ // Completely remove the data cache
+ delete cache[ id ];
+ }
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ if ( typeof key === "undefined" && this.length ) {
+ return jQuery.data( this[0] );
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ }
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+ } else {
+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {
+ jQuery.data( this, key, value );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+jQuery.extend({
+ queue: function( elem, type, data ) {
+ if ( !elem ) {
+ return;
+ }
+
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( !data ) {
+ return q || [];
+ }
+
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+ } else {
+ q.push( data );
+ }
+
+ return q;
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ), fn = queue.shift();
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function( i, elem ) {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ }
+});
+var rclass = /[\n\t]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rspecialurl = /href|src|style/,
+ rtype = /(button|input)/i,
+ rfocusable = /(button|input|object|select|textarea)/i,
+ rclickable = /^(a|area)$/i,
+ rradiocheck = /radio|checkbox/;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name, fn ) {
+ return this.each(function(){
+ jQuery.attr( this, name, "" );
+ if ( this.nodeType === 1 ) {
+ this.removeAttribute( name );
+ }
+ });
+ },
+
+ addClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.addClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ var classNames = (value || "").split( rspace );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className ) {
+ elem.className = value;
+
+ } else {
+ var className = " " + elem.className + " ";
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+ elem.className += " " + classNames[c];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.removeClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ var classNames = (value || "").split(rspace);
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ var className = (" " + elem.className + " ").replace(rclass, " ");
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[c] + " ", " ");
+ }
+ elem.className = className.substring(1, className.length - 1);
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value, isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className, i = 0, self = jQuery(this),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery.data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ if ( value === undefined ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if ( jQuery.nodeName( elem, "option" ) ) {
+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;
+ }
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ if ( option.selected ) {
+ // Get the specifc value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(rreturn, "");
+
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction(value);
+
+ return this.each(function(i) {
+ var self = jQuery(this), val = value;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call(this, i, self.val());
+ }
+
+ // Typecast each time if the value is a Function and the appended
+ // value is therefore different each time.
+ if ( typeof val === "number" ) {
+ val += "";
+ }
+
+ if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+ this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+ } else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(val);
+
+ jQuery( "option", this ).each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ this.selectedIndex = -1;
+ }
+
+ } else {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attr: function( elem, name, value, pass ) {
+ // don't set attributes on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery(elem)[name](value);
+ }
+
+ var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // Only do all the following if this is a node (faster for style)
+ if ( elem.nodeType === 1 ) {
+ // These attributes require special treatment
+ var special = rspecialurl.test( name );
+
+ // Safari mis-reports the default selected property of an option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name === "selected" && !jQuery.support.optSelected ) {
+ var parent = elem.parentNode;
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+
+ // If applicable, access the attribute via the DOM 0 way
+ if ( name in elem && notxml && !special ) {
+ if ( set ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ }
+
+ elem[ name ] = value;
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+ return elem.getAttributeNode( name ).nodeValue;
+ }
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ if ( name === "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+ return attributeNode && attributeNode.specified ?
+ attributeNode.value :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name === "style" ) {
+ if ( set ) {
+ elem.style.cssText = "" + value;
+ }
+
+ return elem.style.cssText;
+ }
+
+ if ( set ) {
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special ?
+ // Some attributes require a special call on IE
+ elem.getAttribute( name, 2 ) :
+ elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+
+ // elem is actually elem.style ... set the style
+ // Using attr for specific style information is now deprecated. Use style insead.
+ return jQuery.style( elem, name, value );
+ }
+});
+var fcleanup = function( nm ) {
+ return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {
+ return "\\" + ch;
+ });
+};
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {
+ elem = window;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // if data is passed, bind to handler
+ if ( data !== undefined ) {
+ // Create temporary function pointer to original handler
+ var fn = handler;
+
+ // Create unique handler function, wrapped around original handler
+ handler = jQuery.proxy( fn );
+
+ // Store data in unique handler
+ handler.data = data;
+ }
+
+ // Init the element's event structure
+ var events = jQuery.data( elem, "events" ) || jQuery.data( elem, "events", {} ),
+ handle = jQuery.data( elem, "handle" ), eventHandle;
+
+ if ( !handle ) {
+ eventHandle = function() {
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+
+ handle = jQuery.data( elem, "handle", eventHandle );
+ }
+
+ // If no handle is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !handle ) {
+ return;
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native
+ // event in IE.
+ handle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split( /\s+/ );
+
+ var type, i = 0;
+
+ while ( (type = types[ i++ ]) ) {
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+
+ if ( i > 1 ) {
+ handler = jQuery.proxy( handler );
+
+ if ( data !== undefined ) {
+ handler.data = data;
+ }
+ }
+
+ handler.type = namespaces.slice(0).sort().join(".");
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = this.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = {};
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, handler) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, handle, false );
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, handle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ var modifiedHandler = special.add.call( elem, handler, data, namespaces, handlers );
+ if ( modifiedHandler && jQuery.isFunction( modifiedHandler ) ) {
+ modifiedHandler.guid = modifiedHandler.guid || handler.guid;
+ modifiedHandler.data = modifiedHandler.data || handler.data;
+ modifiedHandler.type = modifiedHandler.type || handler.type;
+ handler = modifiedHandler;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers[ handler.guid ] = handler;
+
+ // Keep track of which events have been used, for global triggering
+ this.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler ) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ var events = jQuery.data( elem, "events" ), ret, type, fn;
+
+ if ( events ) {
+ // Unbind all events for the element
+ if ( types === undefined || (typeof types === "string" && types.charAt(0) === ".") ) {
+ for ( type in events ) {
+ this.remove( elem, type + (types || "") );
+ }
+ } else {
+ // types is actually an event object here
+ if ( types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(/\s+/);
+ var i = 0;
+ while ( (type = types[ i++ ]) ) {
+ // Namespaced event handlers
+ var namespaces = type.split(".");
+ type = namespaces.shift();
+ var all = !namespaces.length,
+ cleaned = jQuery.map( namespaces.slice(0).sort(), fcleanup ),
+ namespace = new RegExp("(^|\\.)" + cleaned.join("\\.(?:.*\\.)?") + "(\\.|$)"),
+ special = this.special[ type ] || {};
+
+ if ( events[ type ] ) {
+ // remove the given handler for the given type
+ if ( handler ) {
+ fn = events[ type ][ handler.guid ];
+ delete events[ type ][ handler.guid ];
+
+ // remove all handlers for the given type
+ } else {
+ for ( var handle in events[ type ] ) {
+ // Handle the removal of namespaced events
+ if ( all || namespace.test( events[ type ][ handle ].type ) ) {
+ delete events[ type ][ handle ];
+ }
+ }
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, namespaces, fn);
+ }
+
+ // remove generic event handler if no more handlers exist
+ for ( ret in events[ type ] ) {
+ break;
+ }
+ if ( !ret ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, jQuery.data( elem, "handle" ), false );
+ } else if ( elem.detachEvent ) {
+ elem.detachEvent( "on" + type, jQuery.data( elem, "handle" ) );
+ }
+ }
+ ret = null;
+ delete events[ type ];
+ }
+ }
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ for ( ret in events ) {
+ break;
+ }
+ if ( !ret ) {
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) {
+ handle.elem = null;
+ }
+ jQuery.removeData( elem, "events" );
+ jQuery.removeData( elem, "handle" );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem /*, bubbling */ ) {
+ // Event object or event type
+ var type = event.type || event,
+ bubbling = arguments[3];
+
+ if ( !bubbling ) {
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[expando] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+
+ // Only trigger if we've ever bound an event for it
+ if ( this.global[ type ] ) {
+ jQuery.each( jQuery.cache, function() {
+ if ( this.events && this.events[type] ) {
+ jQuery.event.trigger( event, data, this.handle.elem );
+ }
+ });
+ }
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray( data );
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = jQuery.data( elem, "handle" );
+ if ( handle ) {
+ handle.apply( elem, data );
+ }
+
+ var parent = elem.parentNode || elem.ownerDocument;
+
+ // Trigger an inline bound script
+ try {
+ if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+ if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+ event.result = false;
+ }
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (e) {}
+
+ if ( !event.isPropagationStopped() && parent ) {
+ jQuery.event.trigger( event, data, parent, true );
+
+ } else if ( !event.isDefaultPrevented() ) {
+ var target = event.target, old,
+ isClick = jQuery.nodeName(target, "a") && type === "click";
+
+ if ( !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+ try {
+ if ( target[ type ] ) {
+ // Make sure that we don't accidentally re-trigger the onFOO events
+ old = target[ "on" + type ];
+
+ if ( old ) {
+ target[ "on" + type ] = null;
+ }
+
+ this.triggered = true;
+ target[ type ]();
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (e) {}
+
+ if ( old ) {
+ target[ "on" + type ] = old;
+ }
+
+ this.triggered = false;
+ }
+ }
+ },
+
+ handle: function( event ) {
+ // returned undefined or false
+ var all, handlers;
+
+ event = arguments[0] = jQuery.event.fix( event || window.event );
+ event.currentTarget = this;
+
+ // Namespaced event handlers
+ var namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+
+ // Cache this now, all = true means, any handler
+ all = !namespaces.length && !event.exclusive;
+
+ var namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
+
+ handlers = ( jQuery.data(this, "events") || {} )[ event.type ];
+
+ for ( var j in handlers ) {
+ var handler = handlers[ j ];
+
+ // Filter the functions by class
+ if ( all || namespace.test(handler.type) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handler;
+ event.data = handler.data;
+
+ var ret = handler.apply( this, arguments );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+
+ }
+ }
+
+ return event.result;
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function( event ) {
+ if ( event[ expando ] ) {
+ return event;
+ }
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ) {
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target ) {
+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+ }
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement ) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement, body = document.body;
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {
+ event.which = event.charCode || event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ // Deprecated, use jQuery.guid instead
+ guid: 1E8,
+
+ // Deprecated, use jQuery.proxy instead
+ proxy: jQuery.proxy,
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady,
+ teardown: jQuery.noop
+ },
+
+ live: {
+ add: function( proxy, data, namespaces, live ) {
+ jQuery.extend( proxy, data || {} );
+
+ proxy.guid += data.selector + data.live;
+ data.liveProxy = proxy;
+
+ jQuery.event.add( this, data.live, liveHandler, data );
+
+ },
+
+ remove: function( namespaces ) {
+ if ( namespaces.length ) {
+ var remove = 0, name = new RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)");
+
+ jQuery.each( (jQuery.data(this, "events").live || {}), function() {
+ if ( name.test(this.type) ) {
+ remove++;
+ }
+ });
+
+ if ( remove < 1 ) {
+ jQuery.event.remove( this, namespaces[0], liveHandler );
+ }
+ }
+ },
+ special: {}
+ },
+ beforeunload: {
+ setup: function( data, namespaces, fn ) {
+ // We only want to do this special case on windows
+ if ( this.setInterval ) {
+ this.onbeforeunload = fn;
+ }
+
+ return false;
+ },
+ teardown: function( namespaces, fn ) {
+ if ( this.onbeforeunload === fn ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ }
+};
+
+jQuery.Event = function( src ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !this.preventDefault ) {
+ return new jQuery.Event( src );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = now();
+
+ // Mark it as fixed
+ this[ expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+ }
+ // otherwise set the returnValue property of the original event to false (IE)
+ e.returnValue = false;
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+
+ // Traverse up the tree
+ while ( parent && parent !== this ) {
+ // Firefox sometimes assigns relatedTarget a XUL element
+ // which we cannot access the parentNode property of
+ try {
+ parent = parent.parentNode;
+
+ // assuming we've left the element since we most likely mousedover a xul element
+ } catch(e) {
+ break;
+ }
+ }
+
+ if ( parent !== this ) {
+ // set the correct event type
+ event.type = event.data;
+
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+ event.type = event.data;
+ jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ setup: function( data ) {
+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+ },
+ teardown: function( data ) {
+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+ }
+ };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+jQuery.event.special.submit = {
+ setup: function( data, namespaces, fn ) {
+ if ( this.nodeName.toLowerCase() !== "form" ) {
+ jQuery.event.add(this, "click.specialSubmit." + fn.guid, function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ jQuery.event.add(this, "keypress.specialSubmit." + fn.guid, function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ } else {
+ return false;
+ }
+ },
+
+ remove: function( namespaces, fn ) {
+ jQuery.event.remove( this, "click.specialSubmit" + (fn ? "."+fn.guid : "") );
+ jQuery.event.remove( this, "keypress.specialSubmit" + (fn ? "."+fn.guid : "") );
+ }
+};
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+var formElems = /textarea|input|select/i;
+
+function getVal( elem ) {
+ var type = elem.type, val = elem.value;
+
+ if ( type === "radio" || type === "checkbox" ) {
+ val = elem.checked;
+
+ } else if ( type === "select-multiple" ) {
+ val = elem.selectedIndex > -1 ?
+ jQuery.map( elem.options, function( elem ) {
+ return elem.selected;
+ }).join("-") :
+ "";
+
+ } else if ( elem.nodeName.toLowerCase() === "select" ) {
+ val = elem.selectedIndex;
+ }
+
+ return val;
+}
+
+function testChange( e ) {
+ var elem = e.target, data, val;
+
+ if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {
+ return;
+ }
+
+ data = jQuery.data( elem, "_change_data" );
+ val = getVal(elem);
+
+ // the current data will be also retrieved by beforeactivate
+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
+ jQuery.data( elem, "_change_data", val );
+ }
+
+ if ( data === undefined || val === data ) {
+ return;
+ }
+
+ if ( data != null || val ) {
+ e.type = "change";
+ return jQuery.event.trigger( e, arguments[1], elem );
+ }
+}
+
+jQuery.event.special.change = {
+ filters: {
+ focusout: testChange,
+
+ click: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Change has to be called before submit
+ // Keydown will be called before keypress, which is used in submit-event delegation
+ keydown: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+ type === "select-multiple" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Beforeactivate happens also before the previous element is blurred
+ // with this event you can't trigger a change event, but you can store
+ // information/focus[in] is not needed anymore
+ beforeactivate: function( e ) {
+ var elem = e.target;
+
+ if ( elem.nodeName.toLowerCase() === "input" && elem.type === "radio" ) {
+ jQuery.data( elem, "_change_data", getVal(elem) );
+ }
+ }
+ },
+ setup: function( data, namespaces, fn ) {
+ for ( var type in changeFilters ) {
+ jQuery.event.add( this, type + ".specialChange." + fn.guid, changeFilters[type] );
+ }
+
+ return formElems.test( this.nodeName );
+ },
+ remove: function( namespaces, fn ) {
+ for ( var type in changeFilters ) {
+ jQuery.event.remove( this, type + ".specialChange" + (fn ? "."+fn.guid : ""), changeFilters[type] );
+ }
+
+ return formElems.test( this.nodeName );
+ }
+};
+
+var changeFilters = jQuery.event.special.change.filters;
+
+}
+
+function trigger( type, elem, args ) {
+ args[0].type = type;
+ return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ this.addEventListener( orig, handler, true );
+ },
+ teardown: function() {
+ this.removeEventListener( orig, handler, true );
+ }
+ };
+
+ function handler( e ) {
+ e = jQuery.event.fix( e );
+ e.type = fix;
+ return jQuery.event.handle.call( this, e );
+ }
+ });
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+ jQuery.fn[ name ] = function( type, data, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ name ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ }) : fn;
+
+ return type === "unload" && name !== "one" ?
+ this.one( type, data, fn ) :
+ this.each(function() {
+ jQuery.event.add( this, type, handler, data );
+ });
+ };
+});
+
+jQuery.fn.extend({
+ unbind: function( type, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" && !type.preventDefault ) {
+ for ( var key in type ) {
+ this.unbind(key, type[key]);
+ }
+ return this;
+ }
+
+ return this.each(function() {
+ jQuery.event.remove( this, type, fn );
+ });
+ },
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if ( this[0] ) {
+ var event = jQuery.Event( type );
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments, i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while ( i < args.length ) {
+ jQuery.proxy( fn, args[ i++ ] );
+ }
+
+ return this.click( jQuery.proxy( fn, function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+jQuery.each(["live", "die"], function( i, name ) {
+ jQuery.fn[ name ] = function( types, data, fn ) {
+ var type, i = 0;
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ types = (types || "").split( /\s+/ );
+
+ while ( (type = types[ i++ ]) != null ) {
+ type = type === "focus" ? "focusin" : // focus --> focusin
+ type === "blur" ? "focusout" : // blur --> focusout
+ type === "hover" ? types.push("mouseleave") && "mouseenter" : // hover support
+ type;
+
+ if ( name === "live" ) {
+ // bind live handler
+ jQuery( this.context ).bind( liveConvert( type, this.selector ), {
+ data: data, selector: this.selector, live: type
+ }, fn );
+
+ } else {
+ // unbind live handler
+ jQuery( this.context ).unbind( liveConvert( type, this.selector ), fn ? { guid: fn.guid + this.selector + type } : null );
+ }
+ }
+
+ return this;
+ }
+});
+
+function liveHandler( event ) {
+ var stop, elems = [], selectors = [], args = arguments,
+ related, match, fn, elem, j, i, l, data,
+ live = jQuery.extend({}, jQuery.data( this, "events" ).live);
+
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861)
+ if ( event.button && event.type === "click" ) {
+ return;
+ }
+
+ for ( j in live ) {
+ fn = live[j];
+ if ( fn.live === event.type ||
+ fn.altLive && jQuery.inArray(event.type, fn.altLive) > -1 ) {
+
+ data = fn.data;
+ if ( !(data.beforeFilter && data.beforeFilter[event.type] &&
+ !data.beforeFilter[event.type](event)) ) {
+ selectors.push( fn.selector );
+ }
+ } else {
+ delete live[j];
+ }
+ }
+
+ match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+ for ( i = 0, l = match.length; i < l; i++ ) {
+ for ( j in live ) {
+ fn = live[j];
+ elem = match[i].elem;
+ related = null;
+
+ if ( match[i].selector === fn.selector ) {
+ // Those two events require additional checking
+ if ( fn.live === "mouseenter" || fn.live === "mouseleave" ) {
+ related = jQuery( event.relatedTarget ).closest( fn.selector )[0];
+ }
+
+ if ( !related || related !== elem ) {
+ elems.push({ elem: elem, fn: fn });
+ }
+ }
+ }
+ }
+
+ for ( i = 0, l = elems.length; i < l; i++ ) {
+ match = elems[i];
+ event.currentTarget = match.elem;
+ event.data = match.fn.data;
+ if ( match.fn.apply( match.elem, args ) === false ) {
+ stop = false;
+ break;
+ }
+ }
+
+ return stop;
+}
+
+function liveConvert( type, selector ) {
+ return "live." + (type ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( fn ) {
+ return fn ? this.bind( name, fn ) : this.trigger( name );
+ };
+
+ if ( jQuery.attrFn ) {
+ jQuery.attrFn[ name ] = true;
+ }
+});
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+ window.attachEvent("onunload", function() {
+ for ( var id in jQuery.cache ) {
+ if ( jQuery.cache[ id ].handle ) {
+ // Try/Catch is to handle iframes being unloaded, see #4280
+ try {
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+ } catch(e) {}
+ }
+ }
+ });
+}
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * More information: http://sizzlejs.com/
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function(){
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function(selector, context, results, seed) {
+ results = results || [];
+ var origContext = context = context || document;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set );
+ }
+ }
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
+ }
+
+ if ( context ) {
+ var ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray(set);
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ var cur = parts.pop(), pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+ } else if ( context && context.nodeType === 1 ) {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+ } else {
+ for ( var i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function(results){
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort(sortOrder);
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[i-1] ) {
+ results.splice(i--, 1);
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function(expr, set){
+ return Sizzle(expr, null, null, set);
+};
+
+Sizzle.find = function(expr, context, isXML){
+ var set, match;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var type = Expr.order[i], match;
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName("*");
+ }
+
+ return {set: set, expr: expr};
+};
+
+Sizzle.filter = function(expr, set, inplace, not){
+ var old = expr, result = [], curLoop = set, match, anyFound,
+ isXMLFilter = set && set[0] && isXML(set[0]);
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ var filter = Expr.filter[ type ], found, item, left = match[1];
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+ } else {
+ curLoop[i] = false;
+ }
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+ leftMatch: {},
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+ attrHandle: {
+ href: function(elem){
+ return elem.getAttribute("href");
+ }
+ },
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test(part),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+ ">": function(checkSet, part){
+ var isPartStr = typeof part === "string";
+
+ if ( isPartStr && !/\W/.test(part) ) {
+ part = part.toLowerCase();
+
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+ } else {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+ "": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = part.toLowerCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
+ },
+ "~": function(checkSet, part, isXML){
+ var doneName = done++, checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ var nodeCheck = part = part.toLowerCase();
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
+ }
+ },
+ find: {
+ ID: function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? [m] : [];
+ }
+ },
+ NAME: function(match, context){
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [], results = context.getElementsByName(match[1]);
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+ TAG: function(match, context){
+ return context.getElementsByTagName(match[1]);
+ }
+ },
+ preFilter: {
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+ ID: function(match){
+ return match[1].replace(/\\/g, "");
+ },
+ TAG: function(match, curLoop){
+ return match[1].toLowerCase();
+ },
+ CHILD: function(match){
+ if ( match[1] === "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+ PSEUDO: function(match, curLoop, inplace, result, not){
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+ return false;
+ }
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+ POS: function(match){
+ match.unshift( true );
+ return match;
+ }
+ },
+ filters: {
+ enabled: function(elem){
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+ disabled: function(elem){
+ return elem.disabled === true;
+ },
+ checked: function(elem){
+ return elem.checked === true;
+ },
+ selected: function(elem){
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+ return elem.selected === true;
+ },
+ parent: function(elem){
+ return !!elem.firstChild;
+ },
+ empty: function(elem){
+ return !elem.firstChild;
+ },
+ has: function(elem, i, match){
+ return !!Sizzle( match[3], elem ).length;
+ },
+ header: function(elem){
+ return /h\d/i.test( elem.nodeName );
+ },
+ text: function(elem){
+ return "text" === elem.type;
+ },
+ radio: function(elem){
+ return "radio" === elem.type;
+ },
+ checkbox: function(elem){
+ return "checkbox" === elem.type;
+ },
+ file: function(elem){
+ return "file" === elem.type;
+ },
+ password: function(elem){
+ return "password" === elem.type;
+ },
+ submit: function(elem){
+ return "submit" === elem.type;
+ },
+ image: function(elem){
+ return "image" === elem.type;
+ },
+ reset: function(elem){
+ return "reset" === elem.type;
+ },
+ button: function(elem){
+ return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+ },
+ input: function(elem){
+ return /input|select|textarea|button/i.test(elem.nodeName);
+ }
+ },
+ setFilters: {
+ first: function(elem, i){
+ return i === 0;
+ },
+ last: function(elem, i, match, array){
+ return i === array.length - 1;
+ },
+ even: function(elem, i){
+ return i % 2 === 0;
+ },
+ odd: function(elem, i){
+ return i % 2 === 1;
+ },
+ lt: function(elem, i, match){
+ return i < match[3] - 0;
+ },
+ gt: function(elem, i, match){
+ return i > match[3] - 0;
+ },
+ nth: function(elem, i, match){
+ return match[3] - 0 === i;
+ },
+ eq: function(elem, i, match){
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function(elem, match, i, array){
+ var name = match[1], filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var i = 0, l = not.length; i < l; i++ ) {
+ if ( not[i] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+ } else {
+ Sizzle.error( "Syntax error, unrecognized expression: " + name );
+ }
+ },
+ CHILD: function(elem, match){
+ var type = match[1], node = elem;
+ switch (type) {
+ case 'only':
+ case 'first':
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ if ( type === "first" ) {
+ return true;
+ }
+ node = elem;
+ case 'last':
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+ return true;
+ case 'nth':
+ var first = match[2], last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+ if ( first === 0 ) {
+ return diff === 0;
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+ ID: function(elem, match){
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+ TAG: function(elem, match){
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+ },
+ CLASS: function(elem, match){
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+ ATTR: function(elem, match){
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+ POS: function(elem, match, i, array){
+ var name = match[2], filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS;
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){
+ return "\\" + (num - 0 + 1);
+ }));
+}
+
+var makeArray = function(array, results) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 );
+
+// Provide a fallback method if it does not work
+} catch(e){
+ makeArray = function(array, results) {
+ var ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var i = 0, l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+ } else {
+ for ( var i = 0; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( "sourceIndex" in document.documentElement ) {
+ sortOrder = function( a, b ) {
+ if ( !a.sourceIndex || !b.sourceIndex ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.sourceIndex ? -1 : 1;
+ }
+
+ var ret = a.sourceIndex - b.sourceIndex;
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+} else if ( document.createRange ) {
+ sortOrder = function( a, b ) {
+ if ( !a.ownerDocument || !b.ownerDocument ) {
+ if ( a == b ) {
+ hasDuplicate = true;
+ }
+ return a.ownerDocument ? -1 : 1;
+ }
+
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
+ aRange.setStart(a, 0);
+ aRange.setEnd(a, 0);
+ bRange.setStart(b, 0);
+ bRange.setEnd(b, 0);
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
+ if ( ret === 0 ) {
+ hasDuplicate = true;
+ }
+ return ret;
+ };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+function getText( elems ) {
+ var ret = "", elem;
+
+ for ( var i = 0; elems[i]; i++ ) {
+ elem = elems[i];
+
+ // Get the text from text nodes and CDATA nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+ ret += elem.nodeValue;
+
+ // Traverse everything else, except comment nodes
+ } else if ( elem.nodeType !== 8 ) {
+ ret += getText( elem.childNodes );
+ }
+ }
+
+ return ret;
+}
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date).getTime();
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ var root = document.documentElement;
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( document.getElementById( id ) ) {
+ Expr.find.ID = function(match, context, isXML){
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
+ }
+ };
+
+ Expr.filter.ID = function(elem, match){
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+ root = form = null; // release memory in IE
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function(match, context){
+ var results = context.getElementsByTagName(match[1]);
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+ Expr.attrHandle.href = function(elem){
+ return elem.getAttribute("href", 2);
+ };
+ }
+
+ div = null; // release memory in IE
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle, div = document.createElement("div");
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function(query, context, extra, seed){
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(e){}
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ div = null; // release memory in IE
+ })();
+}
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function(match, context, isXML) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ div = null; // release memory in IE
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+ if ( elem ) {
+ elem = elem[dir];
+ var match = false;
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+var contains = document.compareDocumentPosition ? function(a, b){
+ return a.compareDocumentPosition(b) & 16;
+} : function(a, b){
+ return a !== b && (a.contains ? a.contains(b) : true);
+};
+
+var isXML = function(elem){
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function(selector, context){
+ var tmpSet = [], later = "", match,
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.getText = getText;
+jQuery.isXMLDoc = isXML;
+jQuery.contains = contains;
+
+return;
+
+window.Sizzle = Sizzle;
+
+})();
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ slice = Array.prototype.slice;
+
+// Implement the identical functionality for filter and not
+var winnow = function( elements, qualifier, keep ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return !!qualifier.call( elem, i, elem ) === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+ });
+};
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var ret = this.pushStack( "", "find", selector ), length = 0;
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( var n = length; n < ret.length; n++ ) {
+ for ( var r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ return !!selector && jQuery.filter( selector, this ).length > 0;
+ },
+
+ closest: function( selectors, context ) {
+ if ( jQuery.isArray( selectors ) ) {
+ var ret = [], cur = this[0], match, matches = {}, selector;
+
+ if ( cur && selectors.length ) {
+ for ( var i = 0, l = selectors.length; i < l; i++ ) {
+ selector = selectors[i];
+
+ if ( !matches[selector] ) {
+ matches[selector] = jQuery.expr.match.POS.test( selector ) ?
+ jQuery( selector, context || this.context ) :
+ selector;
+ }
+ }
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( selector in matches ) {
+ match = matches[selector];
+
+ if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+ ret.push({ selector: selector, elem: cur });
+ delete matches[selector];
+ }
+ }
+ cur = cur.parentNode;
+ }
+ }
+
+ return ret;
+ }
+
+ var pos = jQuery.expr.match.POS.test( selectors ) ?
+ jQuery( selectors, context || this.context ) : null;
+
+ return this.map(function( i, cur ) {
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {
+ return cur;
+ }
+ cur = cur.parentNode;
+ }
+ return null;
+ });
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ if ( !elem || typeof elem === "string" ) {
+ return jQuery.inArray( this[0],
+ // If it receives a string, the selector is used
+ // If it receives nothing, the siblings are used
+ elem ? jQuery( elem ) : this.parent().children() );
+ }
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context || this.context ) :
+ jQuery.makeArray( selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, slice.call(arguments).join(",") );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [], cur = elem[dir];
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,
+ rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&\w+;/,
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)
+ fcloseTag = function( all, front, tag ) {
+ return rselfClosing.test( tag ) ?
+ all :
+ front + "></" + tag + ">";
+ },
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.getText( this );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ), contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function() {
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery(arguments[0]);
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery(arguments[0]).toArray() );
+ return set;
+ }
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function() {
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var html = this.outerHTML, ownerDocument = this.ownerDocument;
+ if ( !html ) {
+ var div = ownerDocument.createElement("div");
+ div.appendChild( this.cloneNode(true) );
+ html = div.innerHTML;
+ }
+
+ return jQuery.clean([html.replace(rinlinejQuery, "")
+ .replace(rleadingWhitespace, "")], ownerDocument)[0];
+ } else {
+ return this.cloneNode(true);
+ }
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true ) {
+ cloneCopyEvent( this, ret );
+ cloneCopyEvent( this.find("*"), ret.find("*") );
+ }
+
+ // Return the cloned set
+ return ret;
+ },
+
+ html: function( value ) {
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !/<script/i.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, fcloseTag);
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery(this), old = self.html();
+ self.empty().append(function(){
+ return value.call( this, i, old );
+ });
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( !jQuery.isFunction( value ) ) {
+ value = jQuery( value ).detach();
+
+ } else {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling, parent = this.parentNode;
+
+ jQuery(this).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+ }
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ var results, first, value = args[0], scripts = [];
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ // If we're in a fragment, just use that instead of building a new one
+ if ( args[0] && args[0].parentNode && args[0].parentNode.nodeType === 11 ) {
+ results = { fragment: args[0].parentNode };
+ } else {
+ results = buildFragment( args, this, scripts );
+ }
+
+ first = results.fragment.firstChild;
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ results.cacheable || this.length > 1 || i > 0 ?
+ results.fragment.cloneNode(true) :
+ results.fragment
+ );
+ }
+ }
+
+ if ( scripts ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+
+ function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+ }
+ }
+});
+
+function cloneCopyEvent(orig, ret) {
+ var i = 0;
+
+ ret.each(function() {
+ if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+ return;
+ }
+
+ var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( var type in events ) {
+ for ( var handler in events[ type ] ) {
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ }
+ }
+ }
+ });
+}
+
+function buildFragment( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults, doc;
+
+ // webkit does not clone 'checked' attribute of radio inputs on cloneNode, so don't cache if string has a checked
+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && args[0].indexOf("<option") < 0 && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+ cacheable = true;
+ cacheresults = jQuery.fragments[ args[0] ];
+ if ( cacheresults ) {
+ if ( cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+ }
+
+ if ( !fragment ) {
+ doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+}
+
+jQuery.fragments = {};
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [], insert = jQuery( selector );
+
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
+ ret = ret.concat( elems );
+ }
+ return this.pushStack( ret, name, insert.selector );
+ };
+});
+
+jQuery.each({
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
+ if ( !keepData && this.nodeType === 1 ) {
+ jQuery.cleanData( this.getElementsByTagName("*") );
+ jQuery.cleanData( [ this ] );
+ }
+
+ if ( this.parentNode ) {
+ this.parentNode.removeChild( this );
+ }
+ }
+ },
+
+ empty: function() {
+ // Remove element nodes and prevent memory leaks
+ if ( this.nodeType === 1 ) {
+ jQuery.cleanData( this.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( this.firstChild ) {
+ this.removeChild( this.firstChild );
+ }
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function() {
+ return this.each( fn, arguments );
+ };
+});
+
+jQuery.extend({
+ clean: function( elems, context, fragment, scripts ) {
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [];
+
+ jQuery.each(elems, function( i, elem ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ return;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+
+ } else if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, fcloseTag);
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = jQuery.makeArray( div.childNodes );
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+
+ });
+
+ if ( fragment ) {
+ for ( var i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ for ( var i = 0, elem, id; (elem = elems[i]) != null; i++ ) {
+ jQuery.event.remove( elem );
+ jQuery.removeData( elem );
+ }
+ }
+});
+// exclude the following css properties to add px
+var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
+ ralpha = /alpha\([^)]*\)/,
+ ropacity = /opacity=([^)]*)/,
+ rfloat = /float/i,
+ rdashAlpha = /-([a-z])/ig,
+ rupper = /([A-Z])/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+
+ cssShow = { position: "absolute", visibility: "hidden", display:"block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+
+ // cache check for defaultView.getComputedStyle
+ getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+ // normalize float css property
+ styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn.css = function( name, value ) {
+ return access( this, name, value, true, function( elem, name, value ) {
+ if ( value === undefined ) {
+ return jQuery.curCSS( elem, name );
+ }
+
+ if ( typeof value === "number" && !rexclude.test(name) ) {
+ value += "px";
+ }
+
+ jQuery.style( elem, name, value );
+ });
+};
+
+jQuery.extend({
+ style: function( elem, name, value ) {
+ // don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // ignore negative width and height values #1599
+ if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {
+ value = undefined;
+ }
+
+ var style = elem.style || elem, set = value !== undefined;
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name === "opacity" ) {
+ if ( set ) {
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";
+ var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";
+ style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;
+ }
+
+ return style.filter && style.filter.indexOf("opacity=") >= 0 ?
+ (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":
+ "";
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( rfloat.test( name ) ) {
+ name = styleFloat;
+ }
+
+ name = name.replace(rdashAlpha, fcamelCase);
+
+ if ( set ) {
+ style[ name ] = value;
+ }
+
+ return style[ name ];
+ },
+
+ css: function( elem, name, force, extra ) {
+ if ( name === "width" || name === "height" ) {
+ var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;
+
+ function getWH() {
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" ) {
+ return;
+ }
+
+ jQuery.each( which, function() {
+ if ( !extra ) {
+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
+ }
+
+ if ( extra === "margin" ) {
+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
+ } else {
+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
+ }
+ });
+ }
+
+ if ( elem.offsetWidth !== 0 ) {
+ getWH();
+ } else {
+ jQuery.swap( elem, props, getWH );
+ }
+
+ return Math.max(0, Math.round(val));
+ }
+
+ return jQuery.curCSS( elem, name, force );
+ },
+
+ curCSS: function( elem, name, force ) {
+ var ret, style = elem.style, filter;
+
+ // IE uses filters for opacity
+ if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {
+ ret = ropacity.test(elem.currentStyle.filter || "") ?
+ (parseFloat(RegExp.$1) / 100) + "" :
+ "";
+
+ return ret === "" ?
+ "1" :
+ ret;
+ }
+
+ // Make sure we're using the right name for getting the float value
+ if ( rfloat.test( name ) ) {
+ name = styleFloat;
+ }
+
+ if ( !force && style && style[ name ] ) {
+ ret = style[ name ];
+
+ } else if ( getComputedStyle ) {
+
+ // Only "float" is needed here
+ if ( rfloat.test( name ) ) {
+ name = "float";
+ }
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ var defaultView = elem.ownerDocument.defaultView;
+
+ if ( !defaultView ) {
+ return null;
+ }
+
+ var computedStyle = defaultView.getComputedStyle( elem, null );
+
+ if ( computedStyle ) {
+ ret = computedStyle.getPropertyValue( name );
+ }
+
+ // We should always get a number back from opacity
+ if ( name === "opacity" && ret === "" ) {
+ ret = "1";
+ }
+
+ } else if ( elem.currentStyle ) {
+ var camelCase = name.replace(rdashAlpha, fcamelCase);
+
+ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+ // Remember the original values
+ var left = style.left, rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = camelCase === "fontSize" ? "1em" : (ret || 0);
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret;
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( var name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth, height = elem.offsetHeight,
+ skip = elem.nodeName.toLowerCase() === "tr";
+
+ return width === 0 && height === 0 && !skip ?
+ true :
+ width > 0 && height > 0 && !skip ?
+ false :
+ jQuery.curCSS(elem, "display") === "none";
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+var jsc = now(),
+ rscript = /<script(.|\s)*?\/script>/gi,
+ rselectTextarea = /select|textarea/i,
+ rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,
+ jsre = /=\?(&|$)/,
+ rquery = /\?/,
+ rts = /(\?|&)_=.*?(&|$)/,
+ rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+ r20 = /%20/g;
+
+jQuery.fn.extend({
+ // Keep a copy of the old load
+ _load: jQuery.fn.load,
+
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" ) {
+ return this._load( url );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function( res, status ) {
+ // If successful, inject the HTML into all the matched elements
+ if ( status === "success" || status === "notmodified" ) {
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div />")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [res.responseText, status, res] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+ serializeArray: function() {
+ return this.map(function() {
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function() {
+ return this.name && !this.disabled &&
+ (this.checked || rselectTextarea.test(this.nodeName) ||
+ rinput.test(this.type));
+ })
+ .map(function( i, elem ) {
+ var val = jQuery(this).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function( val, i ) {
+ return { name: elem.name, value: val };
+ }) :
+ { name: elem.name, value: val };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+ jQuery.fn[o] = function( f ) {
+ return this.bind(o, f);
+ };
+});
+
+jQuery.extend({
+
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ traditional: false,
+ */
+ // Create the request object; Microsoft failed to properly
+ // implement the XMLHttpRequest in IE7 (can't request local files),
+ // so we use the ActiveXObject when it is available
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?
+ function() {
+ return new window.XMLHttpRequest();
+ } :
+ function() {
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch(e) {}
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ ajax: function( origSettings ) {
+ var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);
+
+ var jsonp, status, data,
+ callbackContext = origSettings && origSettings.context || s,
+ type = s.type.toUpperCase();
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType === "jsonp" ) {
+ if ( type === "GET" ) {
+ if ( !jsre.test( s.url ) ) {
+ s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ }
+ } else if ( !s.data || !jsre.test(s.data) ) {
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ }
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+ jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data ) {
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ }
+
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ window[ jsonp ] = window[ jsonp ] || function( tmp ) {
+ data = tmp;
+ success();
+ complete();
+ // Garbage collect
+ window[ jsonp ] = undefined;
+
+ try {
+ delete window[ jsonp ];
+ } catch(e) {}
+
+ if ( head ) {
+ head.removeChild( script );
+ }
+ };
+ }
+
+ if ( s.dataType === "script" && s.cache === null ) {
+ s.cache = false;
+ }
+
+ if ( s.cache === false && type === "GET" ) {
+ var ts = now();
+
+ // try replacing _= if it is there
+ var ret = s.url.replace(rts, "$1_=" + ts + "$2");
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for get requests
+ if ( s.data && type === "GET" ) {
+ s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && ! jQuery.active++ ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // Matches an absolute URL, and saves the domain
+ var parts = rurl.exec( s.url ),
+ remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType === "script" && type === "GET" && remote ) {
+ var head = document.getElementsByTagName("head")[0] || document.documentElement;
+ var script = document.createElement("script");
+ script.src = s.url;
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function() {
+ if ( !done && (!this.readyState ||
+ this.readyState === "loaded" || this.readyState === "complete") ) {
+ done = true;
+ success();
+ complete();
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+ }
+ };
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ if ( !xhr ) {
+ return;
+ }
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ } else {
+ xhr.open(type, s.url, s.async);
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set the correct header, if data is being sent
+ if ( s.data || origSettings && origSettings.contentType ) {
+ xhr.setRequestHeader("Content-Type", s.contentType);
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[s.url] ) {
+ xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+ }
+
+ if ( jQuery.etag[s.url] ) {
+ xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+ }
+ }
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ // Only send the header if it's not a remote XHR
+ if ( !remote ) {
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*" :
+ s.accepts._default );
+ } catch(e) {}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global ) {
+ trigger("ajaxSend", [xhr, s]);
+ }
+
+ // Wait for a response to come back
+ var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+ // The request was aborted
+ if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+ // Opera doesn't call onreadystatechange before this point
+ // so we simulate the call
+ if ( !requestDone ) {
+ complete();
+ }
+
+ requestDone = true;
+ if ( xhr ) {
+ xhr.onreadystatechange = jQuery.noop;
+ }
+
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+ requestDone = true;
+ xhr.onreadystatechange = jQuery.noop;
+
+ status = isTimeout === "timeout" ?
+ "timeout" :
+ !jQuery.httpSuccess( xhr ) ?
+ "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+ "notmodified" :
+ "success";
+
+ var errMsg;
+
+ if ( status === "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch(err) {
+ status = "parsererror";
+ errMsg = err;
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status === "success" || status === "notmodified" ) {
+ // JSONP handles its own success callback
+ if ( !jsonp ) {
+ success();
+ }
+ } else {
+ jQuery.handleError(s, xhr, status, errMsg);
+ }
+
+ // Fire the complete handlers
+ complete();
+
+ if ( isTimeout === "timeout" ) {
+ xhr.abort();
+ }
+
+ // Stop memory leaks
+ if ( s.async ) {
+ xhr = null;
+ }
+ }
+ };
+
+ // Override the abort handler, if we can (IE doesn't allow it, but that's OK)
+ // Opera doesn't fire onreadystatechange at all on abort
+ try {
+ var oldAbort = xhr.abort;
+ xhr.abort = function() {
+ if ( xhr ) {
+ oldAbort.call( xhr );
+ }
+
+ onreadystatechange( "abort" );
+ };
+ } catch(e) { }
+
+ // Timeout checker
+ if ( s.async && s.timeout > 0 ) {
+ setTimeout(function() {
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone ) {
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );
+ } catch(e) {
+ jQuery.handleError(s, xhr, null, e);
+ // Fire the complete handlers
+ complete();
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async ) {
+ onreadystatechange();
+ }
+
+ function success() {
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success ) {
+ s.success.call( callbackContext, data, status, xhr );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ trigger( "ajaxSuccess", [xhr, s] );
+ }
+ }
+
+ function complete() {
+ // Process result
+ if ( s.complete ) {
+ s.complete.call( callbackContext, xhr, status);
+ }
+
+ // The request was completed
+ if ( s.global ) {
+ trigger( "ajaxComplete", [xhr, s] );
+ }
+
+ // Handle the global AJAX counter
+ if ( s.global && ! --jQuery.active ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+
+ function trigger(type, args) {
+ (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ handleError: function( s, xhr, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) {
+ s.error.call( s.context || s, xhr, status, e );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );
+ }
+ },
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol === "file:" ||
+ // Opera returns 0 when status is 304
+ ( xhr.status >= 200 && xhr.status < 300 ) ||
+ xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;
+ } catch(e) {}
+
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ var lastModified = xhr.getResponseHeader("Last-Modified"),
+ etag = xhr.getResponseHeader("Etag");
+
+ if ( lastModified ) {
+ jQuery.lastModified[url] = lastModified;
+ }
+
+ if ( etag ) {
+ jQuery.etag[url] = etag;
+ }
+
+ // Opera returns 0 when status is 304
+ return xhr.status === 304 || xhr.status === 0;
+ },
+
+ httpData: function( xhr, type, s ) {
+ var ct = xhr.getResponseHeader("content-type") || "",
+ xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.nodeName === "parsererror" ) {
+ jQuery.error( "parsererror" );
+ }
+
+ // Allow a pre-filtering function to sanitize the response
+ // s is checked to keep backwards compatibility
+ if ( s && s.dataFilter ) {
+ data = s.dataFilter( data, type );
+ }
+
+ // The filter can actually parse the response
+ if ( typeof data === "string" ) {
+ // Get the JavaScript object, if JSON is used.
+ if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+ data = jQuery.parseJSON( data );
+
+ // If the type is "script", eval it in global context
+ } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+ jQuery.globalEval( data );
+ }
+ }
+
+ return data;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ var s = [];
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray(a) || a.jquery ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[prefix] );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join("&").replace(r20, "+");
+
+ function buildParams( prefix, obj ) {
+ if ( jQuery.isArray(obj) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ // Serialize object item.
+ jQuery.each( obj, function( k, v ) {
+ buildParams( prefix + "[" + k + "]", v );
+ });
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+ }
+
+ function add( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction(value) ? value() : value;
+ s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+ }
+ }
+});
+var elemdisplay = {},
+ rfxtypes = /toggle|show|hide/,
+ rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+jQuery.fn.extend({
+ show: function( speed, callback ) {
+ if ( speed || speed === 0) {
+ return this.animate( genFx("show", 3), speed, callback);
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var old = jQuery.data(this[i], "olddisplay");
+
+ this[i].style.display = old || "";
+
+ if ( jQuery.css(this[i], "display") === "none" ) {
+ var nodeName = this[i].nodeName, display;
+
+ if ( elemdisplay[ nodeName ] ) {
+ display = elemdisplay[ nodeName ];
+
+ } else {
+ var elem = jQuery("<" + nodeName + " />").appendTo("body");
+
+ display = elem.css("display");
+
+ if ( display === "none" ) {
+ display = "block";
+ }
+
+ elem.remove();
+
+ elemdisplay[ nodeName ] = display;
+ }
+
+ jQuery.data(this[i], "olddisplay", display);
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var j = 0, k = this.length; j < k; j++ ) {
+ this[j].style.display = jQuery.data(this[j], "olddisplay") || "";
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, callback ) {
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, callback);
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var old = jQuery.data(this[i], "olddisplay");
+ if ( !old && old !== "none" ) {
+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( var j = 0, k = this.length; j < k; j++ ) {
+ this[j].style.display = "none";
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2 ) {
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, callback ) {
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete );
+ }
+
+ return this[ optall.queue === false ? "each" : "queue" ](function() {
+ var opt = jQuery.extend({}, optall), p,
+ hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ var name = p.replace(rdashAlpha, fcamelCase);
+
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ p = name;
+ }
+
+ if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+ return opt.complete.call(this);
+ }
+
+ if ( ( p === "height" || p === "width" ) && this.style ) {
+ // Store display property
+ opt.display = jQuery.css(this, "display");
+
+ // Make sure that nothing sneaks out
+ opt.overflow = this.style.overflow;
+ }
+
+ if ( jQuery.isArray( prop[p] ) ) {
+ // Create (if needed) and add to specialEasing
+ (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+ prop[p] = prop[p][0];
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function( name, val ) {
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( rfxtypes.test(val) ) {
+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
+ } else {
+ var parts = rfxnum.exec(val),
+ start = e.cur(true) || 0;
+
+ if ( parts ) {
+ var end = parseFloat( parts[2] ),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ self.style[ name ] = (end || 1) + unit;
+ start = ((end || 1) / e.cur(true)) * start;
+ self.style[ name ] = start + unit;
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function( clearQueue, gotoEnd ) {
+ var timers = jQuery.timers;
+
+ if ( clearQueue ) {
+ this.queue([]);
+ }
+
+ this.each(function() {
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- ) {
+ if ( timers[i].elem === this ) {
+ if (gotoEnd) {
+ // force the next step to be the last
+ timers[i](true);
+ }
+
+ timers.splice(i, 1);
+ }
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if ( !gotoEnd ) {
+ this.dequeue();
+ }
+
+ return this;
+ }
+
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, callback ) {
+ return this.animate( props, speed, callback );
+ };
+});
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? speed : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function() {
+ if ( opt.queue !== false ) {
+ jQuery(this).dequeue();
+ }
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig ) {
+ options.orig = {};
+ }
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+
+ // Set display property to block for height/width animations
+ if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {
+ this.elem.style.display = "block";
+ }
+ },
+
+ // Get the current size
+ cur: function( force ) {
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var r = parseFloat(jQuery.css(this.elem, this.prop, force));
+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ this.startTime = now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ var self = this;
+ function t( gotoEnd ) {
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval(jQuery.fx.tick, 13);
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ var t = now(), done = true;
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ for ( var i in this.options.curAnim ) {
+ if ( this.options.curAnim[i] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ if ( this.options.display != null ) {
+ // Reset the overflow
+ this.elem.style.overflow = this.options.overflow;
+
+ // Reset the display
+ var old = jQuery.data(this.elem, "olddisplay");
+ this.elem.style.display = old ? old : this.options.display;
+
+ if ( jQuery.css(this.elem, "display") === "none" ) {
+ this.elem.style.display = "block";
+ }
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide ) {
+ jQuery(this.elem).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show ) {
+ for ( var p in this.options.curAnim ) {
+ jQuery.style(this.elem, p, this.options.orig[p]);
+ }
+ }
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+ var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+ this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ ) {
+ if ( !timers[i]() ) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style(fx.elem, "opacity", fx.now);
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,
+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,
+ left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ jQuery.offset.initialize();
+
+ var offsetParent = elem.offsetParent, prevOffsetParent = elem,
+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
+ body = doc.body, defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop, left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+ initialize: function() {
+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,
+ html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+ container.innerHTML = html;
+ body.insertBefore( container, body.firstChild );
+ innerDiv = container.firstChild;
+ checkDiv = innerDiv.firstChild;
+ td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ checkDiv.style.position = "fixed", checkDiv.style.top = "20px";
+ // safari subtracts parent border width here which is 5px
+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+ checkDiv.style.position = checkDiv.style.top = "";
+
+ innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+ body.removeChild( container );
+ body = container = innerDiv = checkDiv = table = td = null;
+ jQuery.offset.initialize = jQuery.noop;
+ },
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop, left = body.offsetLeft;
+
+ jQuery.offset.initialize();
+
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;
+ left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ // set position first, in-case top/left are set even on static elem
+ if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {
+ elem.style.position = "relative";
+ }
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,
+ curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ var props = {
+ top: (options.top - curOffset.top) + curTop,
+ left: (options.left - curOffset.left) + curLeft
+ };
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;
+ offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;
+ parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function(val) {
+ var elem = this[0], win;
+
+ if ( !elem ) {
+ return null;
+ }
+
+ if ( val !== undefined ) {
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery(win).scrollLeft(),
+ i ? val : jQuery(win).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ } else {
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+ };
+});
+
+function getWindow( elem ) {
+ return ("scrollTo" in elem && elem.document) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function() {
+ return this[0] ?
+ jQuery.css( this[0], type, false, "padding" ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function( margin ) {
+ return this[0] ?
+ jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+ elem.document.body[ "client" + name ] :
+
+ // Get document width or height
+ (elem.nodeType === 9) ? // is it a document
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ ) :
+
+ // Get or set width or height on the element
+ size === undefined ?
+ // Get width or height on the element
+ jQuery.css( elem, type ) :
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ this.css( type, typeof size === "string" ? size : size + "px" );
+ };
+
+});
+// Expose jQuery to the global object
+window.jQuery = window.$ = jQuery;
+
+})(window);
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1.min.js b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1.min.js
new file mode 100644
index 0000000..15b830c
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery-1.4.1.min.js
@@ -0,0 +1,167 @@
+/*!
+ * jQuery JavaScript Library v1.4.1
+ * http://jquery.com/
+ *
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Date: Mon Jan 25 19:43:33 2010 -0500
+ */
+(function(z,v){function la(){if(!c.isReady){try{r.documentElement.doScroll("left")}catch(a){setTimeout(la,1);return}c.ready()}}function Ma(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var n in b)X(a,n,b[n],f,e,d);return a}if(d!==v){f=!i&&f&&c.isFunction(d);for(n=0;n<j;n++)e(a[n],b,f?d.call(a[n],n,e(a[n],b)):d,i);return a}return j?
+e(a[0],b):null}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function ma(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function na(a){var b,d=[],f=[],e=arguments,i,j,n,o,m,s,x=c.extend({},c.data(this,"events").live);if(!(a.button&&a.type==="click")){for(o in x){j=x[o];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete x[o]}i=c(a.target).closest(f,
+a.currentTarget);m=0;for(s=i.length;m<s;m++)for(o in x){j=x[o];n=i[m].elem;f=null;if(i[m].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==n)d.push({elem:n,fn:j})}}m=0;for(s=d.length;m<s;m++){i=d[m];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}}function oa(a,b){return"live."+(a?a+".":"")+b.replace(/\./g,"`").replace(/ /g,"&")}function pa(a){return!a||!a.parentNode||a.parentNode.nodeType===
+11}function qa(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ra(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0&&(c.support.checkClone||!sa.test(a[0]))){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:r;f=b.createDocumentFragment();
+c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=i?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(ta.concat.apply([],ta.slice(0,b)),function(){d[this]=a});return d}function ua(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Na=z.jQuery,Oa=z.$,r=z.document,S,Pa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Qa=/^.[^:#\[\.,]*$/,Ra=/\S/,Sa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Ta=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,O=navigator.userAgent,
+va=false,P=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,Q=Array.prototype.slice,wa=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Pa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:r;if(a=Ta.exec(a))if(c.isPlainObject(b)){a=[r.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ra([d[1]],
+[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=r.getElementById(d[2])){if(b.id!==d[2])return S.find(a);this.length=1;this[0]=b}this.context=r;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=r;a=r.getElementsByTagName(a)}else return!b||b.jquery?(b||S).find(a):c(b).find(a);else if(c.isFunction(a))return S.ready(a);if(a.selector!==v){this.selector=a.selector;this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,
+this)},selector:"",jquery:"1.4.1",length:0,size:function(){return this.length},toArray:function(){return Q.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=0;ba.apply(this,a);return this},each:function(a,b){return c.each(this,
+a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(r,c);else P&&P.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Q.apply(this,arguments),"slice",Q.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};
+c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,n;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];n=e[i];if(a!==n)if(f&&n&&(c.isPlainObject(n)||c.isArray(n))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(n)?[]:{};a[i]=c.extend(f,j,n)}else if(n!==v)a[i]=n}return a};c.extend({noConflict:function(a){z.$=
+Oa;if(a)z.jQuery=Na;return c},isReady:false,ready:function(){if(!c.isReady){if(!r.body)return setTimeout(c.ready,13);c.isReady=true;if(P){for(var a,b=0;a=P[b++];)a.call(r,c);P=null}c.fn.triggerHandler&&c(r).triggerHandler("ready")}},bindReady:function(){if(!va){va=true;if(r.readyState==="complete")return c.ready();if(r.addEventListener){r.addEventListener("DOMContentLoaded",L,false);z.addEventListener("load",c.ready,false)}else if(r.attachEvent){r.attachEvent("onreadystatechange",L);z.attachEvent("onload",
+c.ready);var a=false;try{a=z.frameElement==null}catch(b){}r.documentElement.doScroll&&a&&la()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===v||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;
+return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return z.JSON&&z.JSON.parse?z.JSON.parse(a):(new Function("return "+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Ra.test(a)){var b=r.getElementsByTagName("head")[0]||
+r.documentElement,d=r.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(r.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===v||c.isFunction(a);if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=
+a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Sa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==
+v;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=v}else if(b&&!c.isFunction(b)){d=b;b=v}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},
+uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});O=c.uaMatch(O);if(O.browser){c.browser[O.browser]=true;c.browser.version=O.version}if(c.browser.webkit)c.browser.safari=true;if(wa)c.inArray=function(a,b){return wa.call(b,a)};S=c(r);if(r.addEventListener)L=function(){r.removeEventListener("DOMContentLoaded",
+L,false);c.ready()};else if(r.attachEvent)L=function(){if(r.readyState==="complete"){r.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=r.documentElement,b=r.createElement("script"),d=r.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support=
+{leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:r.createElement("select").appendChild(r.createElement("option")).selected,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};
+b.type="text/javascript";try{b.appendChild(r.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,a.firstChild);if(z[f]){c.support.scriptEval=true;delete z[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function n(){c.support.noCloneEvent=false;d.detachEvent("onclick",n)});d.cloneNode(true).fireEvent("onclick")}d=r.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=r.createDocumentFragment();a.appendChild(d.firstChild);
+c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var n=r.createElement("div");n.style.width=n.style.paddingLeft="1px";r.body.appendChild(n);c.boxModel=c.support.boxModel=n.offsetWidth===2;r.body.removeChild(n).style.display="none"});a=function(n){var o=r.createElement("div");n="on"+n;var m=n in o;if(!m){o.setAttribute(n,"return;");m=typeof o[n]==="function"}return m};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props=
+{"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ua=0,xa={},Va={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var f=a[G],e=c.cache;if(!b&&!f)return null;f||(f=++Ua);if(typeof b==="object"){a[G]=f;e=e[f]=c.extend(true,
+{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Va:(e[f]={});if(d!==v){a[G]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[G]}catch(i){a.removeAttribute&&a.removeAttribute(G)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,
+a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===v){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===v&&this.length)f=c.data(this[0],a);return f===v&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);
+return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===v)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||
+a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var ya=/[\n\t]/g,ca=/\s+/,Wa=/\r/g,Xa=/href|src|style/,Ya=/(button|input)/i,Za=/(button|input|object|select|textarea)/i,$a=/^(a|area)$/i,za=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=
+c(this);m.addClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,n=b.length;j<n;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=c(this);m.removeClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string"||a===v)for(var b=(a||"").split(ca),
+d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(ya," "),j=0,n=b.length;j<n;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),n=b,o=
+a.split(ca);e=o[i++];){n=f?n:!j.hasClass(e);j[n?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(ya," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===v){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||
+{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(za.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Wa,"")}return v}var n=c.isFunction(a);return this.each(function(o){var m=c(this),s=a;if(this.nodeType===1){if(n)s=a.call(this,o,m.val());
+if(typeof s==="number")s+="";if(c.isArray(s)&&za.test(this.type))this.checked=c.inArray(m.val(),s)>=0;else if(c.nodeName(this,"select")){var x=c.makeArray(s);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),x)>=0});if(!x.length)this.selectedIndex=-1}else this.value=s}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return v;if(f&&b in c.attrFn)return c(a)[b](d);
+f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==v;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Xa.test(b);if(b in a&&f&&!i){if(e){b==="type"&&Ya.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Za.test(a.nodeName)||$a.test(a.nodeName)&&a.href?0:v;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=
+""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?v:a}return c.style(a,b,d)}});var ab=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==z&&!a.frameElement)a=z;if(!d.guid)d.guid=c.guid++;if(f!==v){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=
+function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):v};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var n,o=0;n=b[o++];){var m=n.split(".");n=m.shift();if(o>1){d=c.proxy(d);if(f!==v)d.data=f}d.type=m.slice(0).sort().join(".");var s=e[n],x=this.special[n]||{};if(!s){s=e[n]={};if(!x.setup||x.setup.call(a,f,m,d)===false)if(a.addEventListener)a.addEventListener(n,i,false);else a.attachEvent&&a.attachEvent("on"+n,i)}if(x.add)if((m=x.add.call(a,
+d,f,m,s))&&c.isFunction(m)){m.guid=m.guid||d.guid;m.data=m.data||d.data;m.type=m.type||d.type;d=m}s[d.guid]=d;this.global[n]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===v||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);for(var n=0;i=b[n++];){var o=i.split(".");i=o.shift();var m=!o.length,s=c.map(o.slice(0).sort(),ab);s=new RegExp("(^|\\.)"+
+s.join("\\.(?:.*\\.)?")+"(\\.|$)");var x=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var A in f[i])if(m||s.test(f[i][A].type))delete f[i][A];x.remove&&x.remove.call(a,o,j);for(e in f[i])break;if(!e){if(!x.teardown||x.teardown.call(a,o)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(A=c.data(a,"handle"))A.elem=null;c.removeData(a,
+"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return v;a.result=v;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,
+b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(i){}if(!a.isPropagationStopped()&&f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){d=a.target;var j;if(!(c.nodeName(d,"a")&&e==="click")&&!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){try{if(d[e]){if(j=d["on"+e])d["on"+e]=null;this.triggered=true;d[e]()}}catch(n){}if(j)d["on"+e]=j;this.triggered=false}}},handle:function(a){var b,
+d;a=arguments[0]=c.event.fix(a||z.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==v){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||r;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=r.documentElement;d=r.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==v)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;b.liveProxy=a;c.event.add(this,b.live,na,b)},remove:function(a){if(a.length){var b=
+0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],na)}},special:{}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};
+c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y};var Aa=function(a){for(var b=
+a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ba=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ba:Aa,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ba:Aa)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!==
+"form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return ma("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return ma("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,
+"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var da=/textarea|input|select/i;function Ca(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ea(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Ca(d);if(a.type!=="focusout"||
+d.type!=="radio")c.data(d,"_change_data",e);if(!(f===v||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}}c.event.special.change={filters:{focusout:ea,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ea.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ea.call(this,a)},beforeactivate:function(a){a=
+a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Ca(a))}},setup:function(a,b,d){for(var f in T)c.event.add(this,f+".specialChange."+d.guid,T[f]);return da.test(this.nodeName)},remove:function(a,b){for(var d in T)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),T[d]);return da.test(this.nodeName)}};var T=c.event.special.change.filters}r.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,
+f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){e=f;f=v}var j=b==="one"?c.proxy(e,function(n){c(this).unbind(n,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,
+b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+
+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e){var i,j=0;if(c.isFunction(f)){e=f;f=v}for(d=(d||"").split(/\s+/);(i=d[j++])!=null;){i=i==="focus"?"focusin":i==="blur"?"focusout":i==="hover"?d.push("mouseleave")&&"mouseenter":i;b==="live"?c(this.context).bind(oa(i,this.selector),{data:f,selector:this.selector,
+live:i},e):c(this.context).unbind(oa(i,this.selector),e?{guid:e.guid+this.selector+i}:null)}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});z.attachEvent&&!z.addEventListener&&z.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
+(function(){function a(g){for(var h="",k,l=0;g[l];l++){k=g[l];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===k){y=l[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=k;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}l[q]=y}}}function d(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===
+k){y=l[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=k;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(o.filter(h,[t]).length>0){y=t;break}}t=t[g]}l[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,i=Object.prototype.toString,j=false,n=true;[0,0].sort(function(){n=false;return 0});var o=function(g,h,k,l){k=k||[];var q=h=h||r;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||
+typeof g!=="string")return k;for(var p=[],u,t,y,R,H=true,M=w(h),I=g;(f.exec(""),u=f.exec(I))!==null;){I=u[3];p.push(u[1]);if(u[2]){R=u[3];break}}if(p.length>1&&s.exec(g))if(p.length===2&&m.relative[p[0]])t=fa(p[0]+p[1],h);else for(t=m.relative[p[0]]?[h]:o(p.shift(),h);p.length;){g=p.shift();if(m.relative[g])g+=p.shift();t=fa(g,t)}else{if(!l&&p.length>1&&h.nodeType===9&&!M&&m.match.ID.test(p[0])&&!m.match.ID.test(p[p.length-1])){u=o.find(p.shift(),h,M);h=u.expr?o.filter(u.expr,u.set)[0]:u.set[0]}if(h){u=
+l?{expr:p.pop(),set:A(l)}:o.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=u.expr?o.filter(u.expr,u.set):u.set;if(p.length>0)y=A(t);else H=false;for(;p.length;){var D=p.pop();u=D;if(m.relative[D])u=p.pop();else D="";if(u==null)u=h;m.relative[D](y,u,M)}}else y=[]}y||(y=t);y||o.error(D||g);if(i.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))k.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&
+y[g].nodeType===1&&k.push(t[g]);else k.push.apply(k,y);else A(y,k);if(R){o(R,q,k,l);o.uniqueSort(k)}return k};o.uniqueSort=function(g){if(C){j=n;g.sort(C);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};o.matches=function(g,h){return o(g,null,null,h)};o.find=function(g,h,k){var l,q;if(!g)return[];for(var p=0,u=m.order.length;p<u;p++){var t=m.order[p];if(q=m.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");l=m.find[t](q,
+h,k);if(l!=null){g=g.replace(m.match[t],"");break}}}}l||(l=h.getElementsByTagName("*"));return{set:l,expr:g}};o.filter=function(g,h,k,l){for(var q=g,p=[],u=h,t,y,R=h&&h[0]&&w(h[0]);g&&h.length;){for(var H in m.filter)if((t=m.leftMatch[H].exec(g))!=null&&t[2]){var M=m.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(u===p)p=[];if(m.preFilter[H])if(t=m.preFilter[H](t,u,k,p,l,R)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=u[U])!=null;U++)if(D){I=M(D,t,U,u);var Da=
+l^!!I;if(k&&I!=null)if(Da)y=true;else u[U]=false;else if(Da){p.push(D);y=true}}if(I!==v){k||(u=p);g=g.replace(m.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)o.error(g);else break;q=g}return u};o.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var m=o.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,h){var k=typeof h==="string",l=k&&!/\W/.test(h);k=k&&!l;if(l)h=h.toLowerCase();l=0;for(var q=g.length,
+p;l<q;l++)if(p=g[l]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[l]=k||p&&p.nodeName.toLowerCase()===h?p||false:p===h}k&&o.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var l=0,q=g.length;l<q;l++){var p=g[l];if(p){k=p.parentNode;g[l]=k.nodeName.toLowerCase()===h?k:false}}}else{l=0;for(q=g.length;l<q;l++)if(p=g[l])g[l]=k?p.parentNode:p.parentNode===h;k&&o.filter(h,g,true)}},"":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=
+h=h.toLowerCase();q=b}q("parentNode",h,l,g,p,k)},"~":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,l,g,p,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];h=h.getElementsByName(g[1]);for(var l=0,q=h.length;l<q;l++)h[l].getAttribute("name")===g[1]&&k.push(h[l]);return k.length===0?null:k}},
+TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,l,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var u;(u=h[p])!=null;p++)if(u)if(q^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||l.push(u);else if(k)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&
+"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,l,q,p){h=g[1].replace(/\\/g,"");if(!p&&m.attrMap[h])g[1]=m.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,l,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=o(g[3],null,null,h);else{g=o.filter(g[3],h,k,true^q);k||l.push.apply(l,g);return false}else if(m.match.POS.test(g[0])||m.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);
+return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!o(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===
+g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,h){return h===0},last:function(g,h,k,l){return h===l.length-1},even:function(g,h){return h%2===
+0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,l){var q=h[1],p=m.filters[q];if(p)return p(g,k,h,l);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=h[3];k=0;for(l=h.length;k<l;k++)if(h[k]===g)return false;return true}else o.error("Syntax error, unrecognized expression: "+
+q)},CHILD:function(g,h){var k=h[1],l=g;switch(k){case "only":case "first":for(;l=l.previousSibling;)if(l.nodeType===1)return false;if(k==="first")return true;l=g;case "last":for(;l=l.nextSibling;)if(l.nodeType===1)return false;return true;case "nth":k=h[2];var q=h[3];if(k===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var u=0;for(l=p.firstChild;l;l=l.nextSibling)if(l.nodeType===1)l.nodeIndex=++u;p.sizcache=h}g=g.nodeIndex-q;return k===0?g===0:g%k===0&&g/k>=
+0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=m.attrHandle[k]?m.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var l=h[2];h=h[4];return g==null?l==="!=":l==="="?k===h:l==="*="?k.indexOf(h)>=0:l==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:l==="!="?k!==h:l==="^="?
+k.indexOf(h)===0:l==="$="?k.substr(k.length-h.length)===h:l==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,l){var q=m.setFilters[h[2]];if(q)return q(g,k,h,l)}}},s=m.match.POS;for(var x in m.match){m.match[x]=new RegExp(m.match[x].source+/(?![^\[]*\])(?![^\(]*\))/.source);m.leftMatch[x]=new RegExp(/(^(?:.|\r|\n)*?)/.source+m.match[x].source.replace(/\\(\d+)/g,function(g,h){return"\\"+(h-0+1)}))}var A=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};
+try{Array.prototype.slice.call(r.documentElement.childNodes,0)}catch(B){A=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,l=g.length;k<l;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var C;if(r.documentElement.compareDocumentPosition)C=function(g,h){if(!g.compareDocumentPosition||!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===
+h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in r.documentElement)C=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(r.createRange)C=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),l=h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);l.setStart(h,0);l.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,
+l);if(g===0)j=true;return g};(function(){var g=r.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=r.documentElement;k.insertBefore(g,k.firstChild);if(r.getElementById(h)){m.find.ID=function(l,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(l[1]))?q.id===l[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===l[1]?[q]:v:[]};m.filter.ID=function(l,q){var p=typeof l.getAttributeNode!=="undefined"&&l.getAttributeNode("id");
+return l.nodeType===1&&p&&p.nodeValue===q}}k.removeChild(g);k=g=null})();(function(){var g=r.createElement("div");g.appendChild(r.createComment(""));if(g.getElementsByTagName("*").length>0)m.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var l=0;k[l];l++)k[l].nodeType===1&&h.push(k[l]);k=h}return k};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")m.attrHandle.href=function(h){return h.getAttribute("href",
+2)};g=null})();r.querySelectorAll&&function(){var g=o,h=r.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){o=function(l,q,p,u){q=q||r;if(!u&&q.nodeType===9&&!w(q))try{return A(q.querySelectorAll(l),p)}catch(t){}return g(l,q,p,u)};for(var k in g)o[k]=g[k];h=null}}();(function(){var g=r.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===
+0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){m.order.splice(1,0,"CLASS");m.find.CLASS=function(h,k,l){if(typeof k.getElementsByClassName!=="undefined"&&!l)return k.getElementsByClassName(h[1])};g=null}}})();var E=r.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,h){return g!==h&&(g.contains?g.contains(h):true)},w=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},fa=function(g,h){var k=[],
+l="",q;for(h=h.nodeType?[h]:h;q=m.match.PSEUDO.exec(g);){l+=q[0];g=g.replace(m.match.PSEUDO,"")}g=m.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)o(g,h[q],k);return o.filter(l,k)};c.find=o;c.expr=o.selectors;c.expr[":"]=c.expr.filters;c.unique=o.uniqueSort;c.getText=a;c.isXMLDoc=w;c.contains=E})();var bb=/Until$/,cb=/^(?:parents|prevUntil|prevAll)/,db=/,/;Q=Array.prototype.slice;var Ea=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,
+function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Qa.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=
+0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ea(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ea(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i={},j;if(f&&a.length){e=0;for(var n=a.length;e<n;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>
+-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var o=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(m,s){for(;s&&s.ownerDocument&&s!==b;){if(o?o.index(s)>-1:c(s).is(a))return s;s=s.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),
+a);return this.pushStack(pa(a[0])||pa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},
+nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);bb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):
+e;if((this.length>1||db.test(f))&&cb.test(a))e=e.reverse();return this.pushStack(e,a,Q.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===v||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==
+b&&d.push(a);return d}});var Fa=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ga=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,sa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ia=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],
+col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==v)return this.empty().append((this[0]&&this[0].ownerDocument||r).createTextNode(a));return c.getText(this)},
+wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?
+d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,
+false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&
+!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Fa,"").replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){qa(this,b);qa(this.find("*"),b.find("*"))}return b},html:function(a){if(a===v)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Fa,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(Ha.exec(a)||
+["",""])[1].toLowerCase()]){a=a.replace(Ga,Ia);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,
+b,f))});else a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(s){return c.nodeName(s,"table")?s.getElementsByTagName("tbody")[0]||s.appendChild(s.ownerDocument.createElement("tbody")):s}var e,i,j=a[0],n=[];if(!c.support.checkClone&&arguments.length===3&&typeof j===
+"string"&&sa.test(j))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(j))return this.each(function(s){var x=c(this);a[0]=j.call(this,s,b?x.html():v);x.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ra(a,this,n);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var o=0,m=this.length;o<m;o++)d.call(b?f(this[o],i):this[o],e.cacheable||this.length>1||o>0?e.fragment.cloneNode(true):e.fragment)}n&&c.each(n,
+Ma)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){c.cleanData(this.getElementsByTagName("*"));c.cleanData([this])}this.parentNode&&
+this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&c.cleanData(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||r;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||r;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j===
+"string"){j=j.replace(Ga,Ia);var n=(Ha.exec(j)||["",""])[1].toLowerCase(),o=F[n]||F._default,m=o[0];i=b.createElement("div");for(i.innerHTML=o[1]+j+o[2];m--;)i=i.lastChild;if(!c.support.tbody){m=fb.test(j);n=n==="table"&&!m?i.firstChild&&i.firstChild.childNodes:o[1]==="<table>"&&!m?i.childNodes:[];for(o=n.length-1;o>=0;--o)c.nodeName(n[o],"tbody")&&!n[o].childNodes.length&&n[o].parentNode.removeChild(n[o])}!c.support.leadingWhitespace&&V.test(j)&&i.insertBefore(b.createTextNode(V.exec(j)[0]),i.firstChild);
+j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()==="text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e},cleanData:function(a){for(var b=0,d;(d=a[b])!=null;b++){c.event.remove(d);c.removeData(d)}}});var hb=/z-?index|font-?weight|opacity|zoom|line-?height/i,
+Ja=/alpha\([^)]*\)/,Ka=/opacity=([^)]*)/,ga=/float/i,ha=/-([a-z])/ig,ib=/([A-Z])/g,jb=/^-?\d+(?:px)?$/i,kb=/^-?\d/,lb={position:"absolute",visibility:"hidden",display:"block"},mb=["Left","Right"],nb=["Top","Bottom"],ob=r.defaultView&&r.defaultView.getComputedStyle,La=c.support.cssFloat?"cssFloat":"styleFloat",ia=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===v)return c.curCSS(d,f);if(typeof e==="number"&&!hb.test(f))e+="px";c.style(d,f,e)})};
+c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return v;if((b==="width"||b==="height")&&parseFloat(d)<0)d=v;var f=a.style||a,e=d!==v;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ja.test(a)?a.replace(Ja,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ka.exec(f.filter)[1])/100+"":""}if(ga.test(b))b=La;b=b.replace(ha,ia);if(e)f[b]=d;return f[b]},css:function(a,
+b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?mb:nb;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,lb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&
+a.currentStyle){f=Ka.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ga.test(b))b=La;if(!d&&e&&e[b])f=e[b];else if(ob){if(ga.test(b))b="float";b=b.replace(ib,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ha,ia);f=a.currentStyle[b]||a.currentStyle[d];if(!jb.test(f)&&kb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=
+a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var pb=
+J(),qb=/<script(.|\s)*?\/script>/gi,rb=/select|textarea/i,sb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ja=/\?/,tb=/(\?|&)_=.*?(&|$)/,ub=/^(\w+:)?\/\/([^\/?#]+)/,vb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=
+c.param(b,c.ajaxSettings.traditional);f="POST"}var i=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(j,n){if(n==="success"||n==="notmodified")i.html(e?c("<div />").append(j.responseText.replace(qb,"")).find(e):j.responseText);d&&i.each(d,[j.responseText,n,j])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&
+(this.checked||rb.test(this.nodeName)||sb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,
+b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:z.XMLHttpRequest&&(z.location.protocol!=="file:"||!z.ActiveXObject)?function(){return new z.XMLHttpRequest}:
+function(){try{return new z.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(o,n,j,w);e.global&&f("ajaxSuccess",[w,e])}function d(){e.complete&&e.complete.call(o,w,j);e.global&&f("ajaxComplete",[w,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}
+function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,n,o=a&&a.context||e,m=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(m==="GET")N.test(e.url)||(e.url+=(ja.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||
+N.test(e.url))){i=e.jsonpCallback||"jsonp"+pb++;if(e.data)e.data=(e.data+"").replace(N,"="+i+"$1");e.url=e.url.replace(N,"="+i+"$1");e.dataType="script";z[i]=z[i]||function(q){n=q;b();d();z[i]=v;try{delete z[i]}catch(p){}A&&A.removeChild(B)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&m==="GET"){var s=J(),x=e.url.replace(tb,"$1_="+s+"$2");e.url=x+(x===e.url?(ja.test(e.url)?"&":"?")+"_="+s:"")}if(e.data&&m==="GET")e.url+=(ja.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&
+c.event.trigger("ajaxStart");s=(s=ub.exec(e.url))&&(s[1]&&s[1]!==location.protocol||s[2]!==location.host);if(e.dataType==="script"&&m==="GET"&&s){var A=r.getElementsByTagName("head")[0]||r.documentElement,B=r.createElement("script");B.src=e.url;if(e.scriptCharset)B.charset=e.scriptCharset;if(!i){var C=false;B.onload=B.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;b();d();B.onload=B.onreadystatechange=null;A&&B.parentNode&&
+A.removeChild(B)}}}A.insertBefore(B,A.firstChild);return v}var E=false,w=e.xhr();if(w){e.username?w.open(m,e.url,e.async,e.username,e.password):w.open(m,e.url,e.async);try{if(e.data||a&&a.contentType)w.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&w.setRequestHeader("If-None-Match",c.etag[e.url])}s||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",
+e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(fa){}if(e.beforeSend&&e.beforeSend.call(o,w,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");w.abort();return false}e.global&&f("ajaxSend",[w,e]);var g=w.onreadystatechange=function(q){if(!w||w.readyState===0||q==="abort"){E||d();E=true;if(w)w.onreadystatechange=c.noop}else if(!E&&w&&(w.readyState===4||q==="timeout")){E=true;w.onreadystatechange=c.noop;j=q==="timeout"?"timeout":!c.httpSuccess(w)?
+"error":e.ifModified&&c.httpNotModified(w,e.url)?"notmodified":"success";var p;if(j==="success")try{n=c.httpData(w,e.dataType,e)}catch(u){j="parsererror";p=u}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,w,j,p);d();q==="timeout"&&w.abort();if(e.async)w=null}};try{var h=w.abort;w.abort=function(){w&&h.call(w);g("abort")}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){w&&!E&&g("timeout")},e.timeout);try{w.send(m==="POST"||m==="PUT"||m==="DELETE"?e.data:null)}catch(l){c.handleError(e,
+w,null,l);d()}e.async||g();return w}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=
+f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(j,n){if(c.isArray(n))c.each(n,
+function(o,m){b?f(j,m):d(j+"["+(typeof m==="object"||c.isArray(m)?o:"")+"]",m)});else!b&&n!=null&&typeof n==="object"?c.each(n,function(o,m){d(j+"["+o+"]",m)}):f(j,n)}function f(j,n){n=c.isFunction(n)?n():n;e[e.length]=encodeURIComponent(j)+"="+encodeURIComponent(n)}var e=[];if(b===v)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var i in a)d(i,a[i]);return e.join("&").replace(vb,"+")}});var ka={},wb=/toggle|show|hide/,xb=/^([+-]=)?([\d+-.]+)(.*)$/,
+W,ta=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(ka[d])f=ka[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
+ka[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
+c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,n=this.nodeType===1&&c(this).is(":hidden"),
+o=this;for(j in a){var m=j.replace(ha,ia);if(j!==m){a[m]=a[j];delete a[j];j=m}if(a[j]==="hide"&&n||a[j]==="show"&&!n)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(s,x){var A=new c.fx(o,i,s);if(wb.test(x))A[x==="toggle"?n?"show":"hide":x](a);
+else{var B=xb.exec(x),C=A.cur(true)||0;if(B){x=parseFloat(B[2]);var E=B[3]||"px";if(E!=="px"){o.style[s]=(x||1)+E;C=(x||1)/A.cur(true)*C;o.style[s]=C+E}if(B[1])x=(B[1]==="-="?-1:1)*x+C;A.custom(C,x,E)}else A.custom(C,x,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",
+1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
+b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
+null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
+"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
+this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
+c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
+null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in r.documentElement?function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
+f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(s){c.offset.setOffset(this,a,s)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
+b,e=b.ownerDocument,i,j=e.documentElement,n=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var o=b.offsetTop,m=b.offsetLeft;(b=b.parentNode)&&b!==n&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;o-=b.scrollTop;m-=b.scrollLeft;if(b===d){o+=b.offsetTop;m+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){o+=parseFloat(i.borderTopWidth)||
+0;m+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){o+=parseFloat(i.borderTopWidth)||0;m+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){o+=n.offsetTop;m+=n.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){o+=Math.max(j.scrollTop,n.scrollTop);m+=Math.max(j.scrollLeft,n.scrollLeft)}return{top:o,left:m}};c.offset={initialize:function(){var a=r.body,b=r.createElement("div"),
+d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
+d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
+bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
+e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
+this.offsetParent||r.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==v)return this.each(function(){if(i=ua(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=ua(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
+c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(i){var j=c(this);j[d](f.call(this,i,j[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||
+e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===v?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});z.jQuery=z.$=c})(window);
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate-vsdoc.js b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate-vsdoc.js
new file mode 100644
index 0000000..9fc0981
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate-vsdoc.js
@@ -0,0 +1,1292 @@
+/*
+* This file has been commented to support Visual Studio Intellisense.
+* You should not use this file at runtime inside the browser--it is only
+* intended to be used only for design-time IntelliSense. Please use the
+* standard jQuery library for all production use.
+*
+* Comment version: 1.6
+*/
+
+/*
+ * jQuery validation plug-in 1.6
+ *
+ * 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 $
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+(function($) {
+
+$.extend($.fn, {
+ // http://docs.jquery.com/Plugins/Validation/validate
+ validate: function( options ) {
+ /// <summary>
+ /// Validates the selected form. This method sets up event handlers for submit, focus,
+ /// keyup, blur and click to trigger validation of the entire form or individual
+ /// elements. Each one can be disabled, see the onxxx options (onsubmit, onfocusout,
+ /// onkeyup, onclick). focusInvalid focuses elements when submitting a invalid form.
+ /// </summary>
+ /// <param name="options" type="Options">
+ /// A set of key/value pairs that configure the validate. All options are optional.
+ /// </param>
+ /// <returns type="Validator" />
+
+ // 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 = $("<input type='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() {
+ /// <summary>
+ /// Checks if the selected form is valid or if all selected elements are valid.
+ /// validate() needs to be called on the form before checking it using this method.
+ /// </summary>
+ /// <returns type="Boolean" />
+
+ 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) {
+ /// <summary>
+ /// Remove the specified attributes from the first matched element and return them.
+ /// </summary>
+ /// <param name="attributes" type="String">
+ /// A space-seperated list of attribute names to remove.
+ /// </param>
+ /// <returns type="" />
+
+ 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) {
+ /// <summary>
+ /// Return the validations rules for the first selected element.
+ /// </summary>
+ /// <param name="command" type="String">
+ /// Can be either "add" or "remove".
+ /// </param>
+ /// <param name="argument" type="">
+ /// A list of rules to add or remove.
+ /// </param>
+ /// <returns type="" />
+
+ 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( {}, $.validator.defaults, options );
+ this.currentForm = form;
+ this.init();
+};
+
+$.validator.format = function(source, params) {
+ /// <summary>
+ /// Replaces {n} placeholders with arguments.
+ /// One or more arguments can be passed, in addition to the string template itself, to insert
+ /// into the string.
+ /// </summary>
+ /// <param name="source" type="String">
+ /// The string to format.
+ /// </param>
+ /// <param name="params" type="String">
+ /// The first argument to insert, or an array of Strings to insert
+ /// </param>
+ /// <returns type="String" />
+
+ 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) {
+ /// <summary>
+ /// Modify default settings for validation.
+ /// Accepts everything that Plugins/Validation/validate accepts.
+ /// </summary>
+ /// <param name="settings" type="Options">
+ /// Options to set as default.
+ /// </param>
+ /// <returns type="undefined" />
+
+ $.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");
+ validator.settings["on" + event.type] && validator.settings["on" + event.type].call(validator, this[0] );
+ }
+ $(this.currentForm)
+ .delegate("focusin focusout keyup", ":text, :password, :file, select, textarea", delegate)
+ .delegate("click", ":radio, :checkbox, select, option", delegate);
+
+ if (this.settings.invalidHandler)
+ $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
+ },
+
+ // http://docs.jquery.com/Plugins/Validation/Validator/form
+ form: function() {
+ /// <summary>
+ /// Validates the form, returns true if it is valid, false otherwise.
+ /// This behaves as a normal submit event, but returns the result.
+ /// </summary>
+ /// <returns type="Boolean" />
+
+ 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 ) {
+ /// <summary>
+ /// Validates a single element, returns true if it is valid, false otherwise.
+ /// This behaves as validation on blur or keyup, but returns the result.
+ /// </summary>
+ /// <param name="element" type="Selector">
+ /// An element to validate, must be inside the validated form.
+ /// </param>
+ /// <returns type="Boolean" />
+
+ 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) {
+ /// <summary>
+ /// Show the specified messages.
+ /// Keys have to refer to the names of elements, values are displayed for those elements, using the configured error placement.
+ /// </summary>
+ /// <param name="errors" type="Object">
+ /// One or more key/value pairs of input names and messages.
+ /// </param>
+ /// <returns type="undefined" />
+
+ 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() {
+ /// <summary>
+ /// Resets the controlled form.
+ /// Resets input fields to their original value (requires form plugin), removes classes
+ /// indicating invalid elements and hides error messages.
+ /// </summary>
+ /// <returns type="undefined" />
+
+ if ( $.fn.resetForm )
+ $( this.currentForm ).resetForm();
+ this.submitted = {};
+ this.prepareForm();
+ this.hideErrors();
+ this.elements().removeClass( this.settings.errorClass );
+ },
+
+ numberOfInvalids: function() {
+ /// <summary>
+ /// Returns the number of invalid fields.
+ /// This depends on the internal validator state. It covers all fields only after
+ /// validating the complete form (on submit or via $("form").valid()). After validating
+ /// a single element, only that element is counted. Most useful in combination with the
+ /// invalidHandler-option.
+ /// </summary>
+ /// <returns type="Number" />
+
+ 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();
+ } 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],
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
+ );
+ },
+
+ 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}
+ },
+
+ // http://docs.jquery.com/Plugins/Validation/Validator/addClassRules#namerules
+ addClassRules: function(className, rules) {
+ /// <summary>
+ /// Add a compound class method - useful to refactor common combinations of rules into a single
+ /// class.
+ /// </summary>
+ /// <param name="name" type="String">
+ /// The name of the class rule to add
+ /// </param>
+ /// <param name="rules" type="Options">
+ /// The compound rules
+ /// </param>
+ /// <returns type="undefined" />
+
+ 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) {
+ /// <summary>
+ /// Add a custom validation method. It must consist of a name (must be a legal javascript
+ /// identifier), a javascript based function and a default string message.
+ /// </summary>
+ /// <param name="name" type="String">
+ /// The name of the method, used to identify and referencing it, must be a valid javascript
+ /// identifier
+ /// </param>
+ /// <param name="method" type="Function">
+ /// The actual method implementation, returning true if an element is valid
+ /// </param>
+ /// <param name="message" type="String" optional="true">
+ /// (Optional) The default message to display for this method. Can be a function created by
+ /// jQuery.validator.format(value). When undefined, an already existing message is used
+ /// (handy for localization), otherwise the field-specific messages have to be defined.
+ /// </param>
+ /// <returns type="undefined" />
+
+ $.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
+
+// provides triggerEvent(type: String, target: Element) to trigger delegated events
+;(function($) {
+ $.each({
+ focus: 'focusin',
+ blur: 'focusout'
+ }, function( original, fix ){
+ $.event.special[fix] = {
+ setup:function() {
+ if ( $.browser.msie ) return false;
+ this.addEventListener( original, $.event.special[fix].handler, true );
+ },
+ teardown:function() {
+ if ( $.browser.msie ) return false;
+ this.removeEventListener( original,
+ $.event.special[fix].handler, true );
+ },
+ handler: function(e) {
+ arguments[0] = $.event.fix(e);
+ arguments[0].type = fix;
+ return $.event.handle.apply(this, arguments);
+ }
+ };
+ });
+ $.extend($.fn, {
+ delegate: function(type, delegate, handler) {
+ return this.bind(type, function(event) {
+ var target = $(event.target);
+ if (target.is(delegate)) {
+ return handler.apply(target, arguments);
+ }
+ });
+ },
+ triggerEvent: function(type, target) {
+ return this.triggerHandler(type, [$.event.fix({ type: type, target: target })]);
+ }
+ })
+})(jQuery);
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate.js b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate.js
new file mode 100644
index 0000000..132bc05
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate.js
@@ -0,0 +1,1155 @@
+/*
+ * jQuery validation plug-in 1.6
+ *
+ * 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 $
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+(function($) {
+
+$.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 = $("<input type='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( {}, $.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");
+ validator.settings["on" + event.type] && validator.settings["on" + event.type].call(validator, this[0] );
+ }
+ $(this.currentForm)
+ .delegate("focusin focusout keyup", ":text, :password, :file, select, textarea", delegate)
+ .delegate("click", ":radio, :checkbox, select, option", 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();
+ } 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],
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
+ );
+ },
+
+ 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
+
+// provides triggerEvent(type: String, target: Element) to trigger delegated events
+;(function($) {
+ $.each({
+ focus: 'focusin',
+ blur: 'focusout'
+ }, function( original, fix ){
+ $.event.special[fix] = {
+ setup:function() {
+ if ( $.browser.msie ) return false;
+ this.addEventListener( original, $.event.special[fix].handler, true );
+ },
+ teardown:function() {
+ if ( $.browser.msie ) return false;
+ this.removeEventListener( original,
+ $.event.special[fix].handler, true );
+ },
+ handler: function(e) {
+ arguments[0] = $.event.fix(e);
+ arguments[0].type = fix;
+ return $.event.handle.apply(this, arguments);
+ }
+ };
+ });
+ $.extend($.fn, {
+ delegate: function(type, delegate, handler) {
+ return this.bind(type, function(event) {
+ var target = $(event.target);
+ if (target.is(delegate)) {
+ return handler.apply(target, arguments);
+ }
+ });
+ },
+ triggerEvent: function(type, target) {
+ return this.triggerHandler(type, [$.event.fix({ type: type, target: target })]);
+ }
+ })
+})(jQuery);
diff --git a/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate.min.js b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate.min.js
new file mode 100644
index 0000000..54faf8f
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Scripts/jquery.validate.min.js
@@ -0,0 +1,31 @@
+/*
+ * jQuery validation plug-in 1.6
+ *
+ * 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 $
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+(function($){$.extend($.fn,{validate:function(options){if(!this.length){options&&options.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing");return;}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){this.find("input, button").filter(".cancel").click(function(){validator.cancelSubmit=true;});if(validator.settings.submitHandler){this.find("input, button").filter(":submit").click(function(){validator.submitButton=this;});}this.submit(function(event){if(validator.settings.debug)event.preventDefault();function handle(){if(validator.settings.submitHandler){if(validator.submitButton){var hidden=$("<input type='hidden'/>").attr("name",validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);}validator.settings.submitHandler.call(validator,validator.currentForm);if(validator.submitButton){hidden.remove();}return false;}return true;}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;},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;}},removeAttrs:function(attributes){var result={},$element=this;$.each(attributes.split(/\s/),function(index,value){result[value]=$element.attr(value);$element.removeAttr(value);});return result;},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);if(data.required){var param=data.required;delete data.required;data=$.extend({required:param},data);}return data;}});$.extend($.expr[":"],{blank:function(a){return!$.trim(""+a.value);},filled:function(a){return!!$.trim(""+a.value);},unchecked:function(a){return!a.checked;}});$.validator=function(options,form){this.settings=$.extend({},$.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;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){if(element.name in this.submitted)this.element(element);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);}},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");validator.settings["on"+event.type]&&validator.settings["on"+event.type].call(validator,this[0]);}$(this.currentForm).delegate("focusin focusout keyup",":text, :password, :file, select, textarea",delegate).delegate("click",":radio, :checkbox, select, option",delegate);if(this.settings.invalidHandler)$(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler);},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();},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()){this.toHide=this.toHide.add(this.containers);}this.showErrors();return result;},showErrors:function(errors){if(errors){$.extend(this.errorMap,errors);this.errorList=[];for(var name in errors){this.errorList.push({message:errors[name],element:this.findByName(name)[0]});}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();},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();}catch(e){}}},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={};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);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(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(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;},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];},customMessage:function(name,method){var m=this.settings.messages[name];return m&&(m.constructor==String?m:m[method]);},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),!this.settings.ignoreTitle&&element.title||undefined,$.validator.messages[method],"<strong>Warning: No message defined for "+element.name+"</strong>");},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){label.removeClass().addClass(this.settings.errorClass);label.attr("generated")&&label.html(message);}else{label=$("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(element),generated:true}).addClass(this.settings.errorClass).html(message||"");if(this.settings.wrapper){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){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--;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;}}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){$.each(rules,function(prop,val){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];}}});$.each(rules,function(rule,parameter){rules[rule]=$.isFunction(parameter)?parameter(element):parameter;});$.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){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;}}if(rules.messages){delete rules.messages}return rules;},normalizeRule:function(data){if(typeof data=="string"){var transformed={};$.each(data.split(/\s/),function(){transformed[this]=true;});data=transformed;}return data;},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:{required:function(value,element,param){if(!this.depend(param,element))return"dependency-mismatch";switch(element.nodeName.toLowerCase()){case'select':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;}},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;},minlength:function(value,element,param){return this.optional(element)||this.getLength($.trim(value),element)>=param;},maxlength:function(value,element,param){return this.optional(element)||this.getLength($.trim(value),element)<=param;},rangelength:function(value,element,param){var length=this.getLength($.trim(value),element);return this.optional(element)||(length>=param[0]&&length<=param[1]);},min:function(value,element,param){return this.optional(element)||value>=param;},max:function(value,element,param){return this.optional(element)||value<=param;},range:function(value,element,param){return this.optional(element)||(value>=param[0]&&value<=param[1]);},email:function(value,element){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);},url:function(value,element){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);},date:function(value,element){return this.optional(element)||!/Invalid|NaN/.test(new Date(value));},dateISO:function(value,element){return this.optional(element)||/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);},number:function(value,element){return this.optional(element)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);},digits:function(value,element){return this.optional(element)||/^\d+$/.test(value);},creditcard:function(value,element){if(this.optional(element))return"dependency-mismatch";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;},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"));},equalTo:function(value,element,param){var target=$(param).unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){$(element).valid();});return value==target.val();}}});$.format=$.validator.format;})(jQuery);;(function($){var ajax=$.ajax;var pendingRequests={};$.ajax=function(settings){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);;(function($){$.each({focus:'focusin',blur:'focusout'},function(original,fix){$.event.special[fix]={setup:function(){if($.browser.msie)return false;this.addEventListener(original,$.event.special[fix].handler,true);},teardown:function(){if($.browser.msie)return false;this.removeEventListener(original,$.event.special[fix].handler,true);},handler:function(e){arguments[0]=$.event.fix(e);arguments[0].type=fix;return $.event.handle.apply(this,arguments);}};});$.extend($.fn,{delegate:function(type,delegate,handler){return this.bind(type,function(event){var target=$(event.target);if(target.is(delegate)){return handler.apply(target,arguments);}});},triggerEvent:function(type,target){return this.triggerHandler(type,[$.event.fix({type:type,target:target})]);}})})(jQuery); \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/Account/LogOn.aspx b/src/OAuth/OAuthAuthorizationServer/Views/Account/LogOn.aspx
new file mode 100644
index 0000000..e83a162
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/Account/LogOn.aspx
@@ -0,0 +1,31 @@
+<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<OAuthAuthorizationServer.Models.LogOnModel>" %>
+
+<asp:Content ID="loginTitle" ContentPlaceHolderID="TitleContent" runat="server">
+ Log On
+</asp:Content>
+<asp:Content ID="loginContent" ContentPlaceHolderID="MainContent" runat="server">
+ <h2>
+ Log On</h2>
+ <% using (Html.BeginForm()) { %>
+ <%: Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") %>
+ <div>
+ <fieldset>
+ <legend>Account Information</legend>
+ <div class="editor-label">
+ <%: Html.LabelFor(m => m.UserSuppliedIdentifier) %>
+ </div>
+ <div class="editor-field">
+ <%: Html.TextBoxFor(m => m.UserSuppliedIdentifier) %>
+ <%: Html.ValidationMessageFor(m => m.UserSuppliedIdentifier) %>
+ </div>
+ <div class="editor-label">
+ <%: Html.CheckBoxFor(m => m.RememberMe) %>
+ <%: Html.LabelFor(m => m.RememberMe) %>
+ </div>
+ <p>
+ <input type="submit" value="Log On" />
+ </p>
+ </fieldset>
+ </div>
+ <% } %>
+</asp:Content>
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/Home/About.aspx b/src/OAuth/OAuthAuthorizationServer/Views/Home/About.aspx
new file mode 100644
index 0000000..335c141
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/Home/About.aspx
@@ -0,0 +1,12 @@
+<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
+
+<asp:Content ID="aboutTitle" ContentPlaceHolderID="TitleContent" runat="server">
+ About Us
+</asp:Content>
+
+<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
+ <h2>About</h2>
+ <p>
+ Put content here.
+ </p>
+</asp:Content>
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/Home/CreateDatabase.aspx b/src/OAuth/OAuthAuthorizationServer/Views/Home/CreateDatabase.aspx
new file mode 100644
index 0000000..e7d57cc
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/Home/CreateDatabase.aspx
@@ -0,0 +1,19 @@
+<%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Views/Shared/Site.Master" %>
+
+<asp:Content runat="server" ID="Content1" ContentPlaceHolderID="MainContent">
+ <% if (ViewData["Success"] != null) {
+ %>
+ <p>
+ Database (re)created!</p>
+ <p>
+ Note that to be useful, you really need to either modify the database to add an
+ account with data that will be accessed by this sample, or modify this very page
+ to inject that data into the database.
+ </p>
+ <%
+ }
+ %>
+ <p style="color: Red; font-weight: bold">
+ <%= ViewData["Error"] %>
+ </p>
+</asp:Content>
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/Home/Index.aspx b/src/OAuth/OAuthAuthorizationServer/Views/Home/Index.aspx
new file mode 100644
index 0000000..b4b1235
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/Home/Index.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
+
+<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
+ Home Page
+</asp:Content>
+<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
+ <h2>
+ DotNetOpenAuth presents the OAuth 2.0 Authorization Server!
+ </h2>
+ <p>
+ To learn more about DotNetOpenAuth visit <a href="http://www.DotNetOpenAuth.net/"
+ title="DotNetOpenAuth web site">http://www.DotNetOpenAuth.net/</a>.
+ </p>
+ <% using (Html.BeginForm("CreateDatabase", "Home")) {%>
+ <input type="submit" value="(Re)Create Database" />
+ <%
+ }%>
+</asp:Content>
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/OAuth/Authorize.aspx b/src/OAuth/OAuthAuthorizationServer/Views/OAuth/Authorize.aspx
new file mode 100644
index 0000000..94480f1
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/OAuth/Authorize.aspx
@@ -0,0 +1,65 @@
+<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<OAuthAuthorizationServer.Models.AccountAuthorizeModel>" %>
+<%@ Import Namespace="DotNetOpenAuth.OAuth2" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <h2>
+ Authorize
+ </h2>
+ <div style="background-color: Yellow">
+ <b>Warning</b>: Never give your login credentials to another web site or application.
+ </div>
+ <p>
+ The
+ <%= Html.Encode(Model.ClientApp) %>
+ application is requesting to access the private data in your account here. Is that
+ alright with you?
+ </p>
+ <p>
+ <b>Requested access: </b>
+ <%= Html.Encode(String.Join(" ", Model.Scope.ToArray())) %>
+ </p>
+ <p>
+ If you grant access now, you can revoke it at any time by returning to
+ <%= Html.ActionLink("your account page", "Edit") %>.
+ </p>
+ <% using (Html.BeginForm("AuthorizeResponse", "OAuth")) { %>
+ <%= Html.AntiForgeryToken() %>
+ <%= Html.Hidden("IsApproved") %>
+ <%= Html.Hidden("client_id", Model.AuthorizationRequest.ClientIdentifier) %>
+ <%= Html.Hidden("redirect_uri", Model.AuthorizationRequest.Callback) %>
+ <%= Html.Hidden("state", Model.AuthorizationRequest.ClientState) %>
+ <%= Html.Hidden("scope", OAuthUtilities.JoinScopes(Model.AuthorizationRequest.Scope)) %>
+ <%= Html.Hidden("response_type", Model.AuthorizationRequest.ResponseType == DotNetOpenAuth.OAuth2.Messages.EndUserAuthorizationResponseType.AccessToken ? "token" : "code") %>
+ <div style="display: none" id="responseButtonsDiv">
+ <input type="submit" value="Yes" onclick="document.getElementsByName('IsApproved')[0].value = true; return true;" />
+ <input type="submit" value="No" onclick="document.getElementsByName('IsApproved')[0].value = false; return true;" />
+ </div>
+ <div id="javascriptDisabled">
+ <b>Javascript appears to be disabled in your browser. </b>This page requires Javascript
+ to be enabled to better protect your security.
+ </div>
+
+ <script language="javascript" type="text/javascript">
+ //<![CDATA[
+ // we use HTML to hide the action buttons and Javascript to show them
+ // to protect against click-jacking in an iframe whose javascript is disabled.
+ document.getElementById('responseButtonsDiv').style.display = 'block';
+ document.getElementById('javascriptDisabled').style.display = 'none';
+
+ // Frame busting code (to protect us from being hosted in an iframe).
+ // This protects us from click-jacking.
+ if (document.location !== window.top.location) {
+ window.top.location = document.location;
+ }
+ //]]>
+ </script>
+
+ <% } %>
+</body>
+</html>
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/Shared/Error.aspx b/src/OAuth/OAuthAuthorizationServer/Views/Shared/Error.aspx
new file mode 100644
index 0000000..144df3f
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/Shared/Error.aspx
@@ -0,0 +1,11 @@
+<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>
+
+<asp:Content ID="errorTitle" ContentPlaceHolderID="TitleContent" runat="server">
+ Error
+</asp:Content>
+
+<asp:Content ID="errorContent" ContentPlaceHolderID="MainContent" runat="server">
+ <h2>
+ Sorry, an error occurred while processing your request.
+ </h2>
+</asp:Content>
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/Shared/LogOnUserControl.ascx b/src/OAuth/OAuthAuthorizationServer/Views/Shared/LogOnUserControl.ascx
new file mode 100644
index 0000000..9afaab3
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/Shared/LogOnUserControl.ascx
@@ -0,0 +1,14 @@
+<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
+<%
+ if (Request.IsAuthenticated) {
+%>
+ Welcome <b><%: Page.User.Identity.Name %></b>!
+ [ <%: Html.ActionLink("Log Off", "LogOff", "Account") %> ]
+<%
+ }
+ else {
+%>
+ [ <%: Html.ActionLink("Log On", "LogOn", "Account") %> ]
+<%
+ }
+%>
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/Shared/Site.Master b/src/OAuth/OAuthAuthorizationServer/Views/Shared/Site.Master
new file mode 100644
index 0000000..43f68e1
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/Shared/Site.Master
@@ -0,0 +1,40 @@
+<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
+ <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
+</head>
+
+<body>
+ <div class="page">
+
+ <div id="header">
+ <div id="title">
+ <h1>DotNetOpenAuth OAuth 2.0 Authorization Server</h1>
+ </div>
+
+ <div id="logindisplay">
+ <% Html.RenderPartial("LogOnUserControl"); %>
+ </div>
+
+ <div id="menucontainer">
+
+ <ul id="menu">
+ <li><%: Html.ActionLink("Home", "Index", "Home")%></li>
+ <li><%: Html.ActionLink("About", "About", "Home")%></li>
+ </ul>
+
+ </div>
+ </div>
+
+ <div id="main">
+ <asp:ContentPlaceHolder ID="MainContent" runat="server" />
+
+ <div id="footer">
+ </div>
+ </div>
+ </div>
+</body>
+</html>
diff --git a/src/OAuth/OAuthAuthorizationServer/Views/Web.config b/src/OAuth/OAuthAuthorizationServer/Views/Web.config
new file mode 100644
index 0000000..aa7a38d
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Views/Web.config
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+
+<configuration>
+ <system.web>
+ <httpHandlers>
+ <add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
+ </httpHandlers>
+
+ <!--
+ Enabling request validation in view pages would cause validation to occur
+ after the input has already been processed by the controller. By default
+ MVC performs request validation before a controller processes the input.
+ To change this behavior apply the ValidateInputAttribute to a
+ controller or action.
+ -->
+ <pages
+ validateRequest="false"
+ pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
+ pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
+ userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <controls>
+ <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
+ </controls>
+ </pages>
+ </system.web>
+
+ <system.webServer>
+ <validation validateIntegratedModeConfiguration="false" />
+
+ <handlers>
+ <remove name="BlockViewHandler"/>
+ <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
+ </handlers>
+ </system.webServer>
+</configuration>
diff --git a/src/OAuth/OAuthAuthorizationServer/Web.Debug.config b/src/OAuth/OAuthAuthorizationServer/Web.Debug.config
new file mode 100644
index 0000000..2c6dd51
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Web.Debug.config
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+
+<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+ <!--
+ In the example below, the "SetAttributes" transform will change the value of
+ "connectionString" to use "ReleaseSQLServer" only when the "Match" locator
+ finds an atrribute "name" that has a value of "MyDB".
+
+ <connectionStrings>
+ <add name="MyDB"
+ connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+ xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+ </connectionStrings>
+ -->
+ <system.web>
+ <!--
+ In the example below, the "Replace" transform will replace the entire
+ <customErrors> section of your web.config file.
+ Note that because there is only one customErrors section under the
+ <system.web> node, there is no need to use the "xdt:Locator" attribute.
+
+ <customErrors defaultRedirect="GenericError.htm"
+ mode="RemoteOnly" xdt:Transform="Replace">
+ <error statusCode="500" redirect="InternalError.htm"/>
+ </customErrors>
+ -->
+ </system.web>
+</configuration> \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Web.Release.config b/src/OAuth/OAuthAuthorizationServer/Web.Release.config
new file mode 100644
index 0000000..4122d79
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Web.Release.config
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+ <!--
+ In the example below, the "SetAttributes" transform will change the value of
+ "connectionString" to use "ReleaseSQLServer" only when the "Match" locator
+ finds an atrribute "name" that has a value of "MyDB".
+
+ <connectionStrings>
+ <add name="MyDB"
+ connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+ xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+ </connectionStrings>
+ -->
+ <system.web>
+ <compilation xdt:Transform="RemoveAttributes(debug)" />
+ <!--
+ In the example below, the "Replace" transform will replace the entire
+ <customErrors> section of your web.config file.
+ Note that because there is only one customErrors section under the
+ <system.web> node, there is no need to use the "xdt:Locator" attribute.
+
+ <customErrors defaultRedirect="GenericError.htm"
+ mode="RemoteOnly" xdt:Transform="Replace">
+ <error statusCode="500" redirect="InternalError.htm"/>
+ </customErrors>
+ -->
+ </system.web>
+</configuration> \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/Web.config b/src/OAuth/OAuthAuthorizationServer/Web.config
new file mode 100644
index 0000000..1d6955f
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/Web.config
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ For more information on how to configure your ASP.NET application, please visit
+ http://go.microsoft.com/fwlink/?LinkId=152368
+ -->
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false" />
+ <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+ <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" />
+ <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" />
+ <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ </sectionGroup>
+ </configSections>
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <uri>
+ <idn enabled="All" />
+ <iriParsing enabled="true" />
+ </uri>
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <dotNetOpenAuth>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true" />
+ <!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. -->
+ <messaging relaxSslRequirements="true">
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <!-- since this is a sample, and will often be used with localhost -->
+ <add name="localhost" />
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ <openid>
+ <relyingParty>
+ <security requireSsl="false">
+ <!-- Uncomment the trustedProviders tag if your relying party should only accept positive assertions from a closed set of OpenID Providers. -->
+ <!--<trustedProviders rejectAssertionsFromUntrustedProviders="true">
+ <add endpoint="https://www.google.com/accounts/o8/ud" />
+ </trustedProviders>-->
+ </security>
+ <behaviors>
+ <!-- The following OPTIONAL behavior allows RPs to use SREG only, but be compatible
+ with OPs that use Attribute Exchange (in various formats). -->
+ <add type="DotNetOpenAuth.OpenId.RelyingParty.Behaviors.AXFetchAsSregTransform, DotNetOpenAuth.OpenId.RelyingParty" />
+ </behaviors>
+ </relyingParty>
+ </openid>
+ </dotNetOpenAuth>
+ <log4net>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO" />
+ <!--<appender-ref ref="RollingFileAppender" />-->
+ <appender-ref ref="TracePageAppender" />
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="ALL" />
+ </logger>
+ </log4net>
+ <connectionStrings>
+ <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database2.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" />
+ </connectionStrings>
+ <system.web>
+ <compilation debug="true" targetFramework="4.0">
+ <assemblies>
+ <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ </assemblies>
+ </compilation>
+ <authentication mode="Forms">
+ <forms loginUrl="~/Account/LogOn" timeout="2880" />
+ </authentication>
+ <pages>
+ <namespaces>
+ <add namespace="System.Web.Mvc" />
+ <add namespace="System.Web.Mvc.Ajax" />
+ <add namespace="System.Web.Mvc.Html" />
+ <add namespace="System.Web.Routing" />
+ </namespaces>
+ </pages>
+ </system.web>
+ <system.webServer>
+ <validation validateIntegratedModeConfiguration="false" />
+ <modules runAllManagedModulesForAllRequests="true" />
+ </system.webServer>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ <legacyHMACWarning enabled="0" />
+ </runtime>
+</configuration> \ No newline at end of file
diff --git a/src/OAuth/OAuthAuthorizationServer/packages.config b/src/OAuth/OAuthAuthorizationServer/packages.config
new file mode 100644
index 0000000..c5d87eb
--- /dev/null
+++ b/src/OAuth/OAuthAuthorizationServer/packages.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CodeContracts.Unofficial" version="1.0.0.2" />
+ <package id="DotNetOpenAuth.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth2.AuthorizationServer" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.AuthorizationServer" version="0.23.0-draft2" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft2" />
+ <package id="DotNetOpenAuth.OpenId.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OpenId.RelyingParty" version="4.0.0.12084" />
+ <package id="log4net" version="2.0.0" />
+</packages> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Code/Logging.cs b/src/OAuth/OAuthClient/Code/Logging.cs
new file mode 100644
index 0000000..4e47e49
--- /dev/null
+++ b/src/OAuth/OAuthClient/Code/Logging.cs
@@ -0,0 +1,22 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+
+ /// <summary>
+ /// Logging tools for this sample.
+ /// </summary>
+ public static class Logging {
+ /// <summary>
+ /// An application memory cache of recent log messages.
+ /// </summary>
+ public static StringBuilder LogMessages = new StringBuilder();
+
+ /// <summary>
+ /// The logger for this sample to use.
+ /// </summary>
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthClient");
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Code/TracePageAppender.cs b/src/OAuth/OAuthClient/Code/TracePageAppender.cs
new file mode 100644
index 0000000..f41fd17
--- /dev/null
+++ b/src/OAuth/OAuthClient/Code/TracePageAppender.cs
@@ -0,0 +1,13 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Web;
+
+ public class TracePageAppender : log4net.Appender.AppenderSkeleton {
+ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
+ StringWriter sw = new StringWriter(Logging.LogMessages);
+ Layout.Format(sw, loggingEvent);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Default.aspx b/src/OAuth/OAuthClient/Default.aspx
new file mode 100644
index 0000000..f832ccf
--- /dev/null
+++ b/src/OAuth/OAuthClient/Default.aspx
@@ -0,0 +1,17 @@
+<%@ Page Title="DotNetOpenAuth Consumer samples" Language="C#" MasterPageFile="~/MasterPage.master"
+ AutoEventWireup="true" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <p>OAuth allows this web site to access your private data with your authorization, but
+ without you having to give up your password. </p>
+ <p>Select a demo:</p>
+ <ul>
+ <li><a href="GoogleAddressBook.aspx">Download your Gmail address book</a></li>
+ <li><a href="Twitter.aspx">Get your Twitter updates</a></li>
+ <li><a href="SignInWithTwitter.aspx">Sign In With Twitter</a></li>
+ <li><a href="Facebook.aspx">Sign in with Facebook</a></li>
+ <li><a href="WindowsLive.aspx">Sign in with Windows Live</a></li>
+ <li><a href="SampleWcf2.aspx">Interop with Authorization Server sample (Authorization code grant) and Resource Server using WCF w/ OAuth 2.0 </a></li>
+ <li><a href="SampleWcf2Javascript.html">Interop with Authorization Server sample (implicit grant) and Resource Server using WCF w/ OAuth 2.0 </a></li>
+ </ul>
+</asp:Content>
diff --git a/src/OAuth/OAuthClient/Facebook.aspx b/src/OAuth/OAuthClient/Facebook.aspx
new file mode 100644
index 0000000..c227814
--- /dev/null
+++ b/src/OAuth/OAuthClient/Facebook.aspx
@@ -0,0 +1,16 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OAuthClient.Facebook" Codebehind="Facebook.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ Welcome,
+ <asp:Label Text="[name]" ID="nameLabel" runat="server" />
+ </div>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthClient/Facebook.aspx.cs b/src/OAuth/OAuthClient/Facebook.aspx.cs
new file mode 100644
index 0000000..0f71712
--- /dev/null
+++ b/src/OAuth/OAuthClient/Facebook.aspx.cs
@@ -0,0 +1,32 @@
+namespace OAuthClient {
+ using System;
+ using System.Configuration;
+ using System.Net;
+ using System.Web;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.ApplicationBlock.Facebook;
+ using DotNetOpenAuth.OAuth2;
+
+ public partial class Facebook : System.Web.UI.Page {
+ private static readonly FacebookClient client = new FacebookClient {
+ ClientIdentifier = ConfigurationManager.AppSettings["facebookAppID"],
+ ClientSecret = ConfigurationManager.AppSettings["facebookAppSecret"],
+ };
+
+ protected void Page_Load(object sender, EventArgs e) {
+ IAuthorizationState authorization = client.ProcessUserAuthorization();
+ if (authorization == null) {
+ // Kick off authorization request
+ client.RequestUserAuthorization();
+ } else {
+ var request = WebRequest.Create("https://graph.facebook.com/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
+ using (var response = request.GetResponse()) {
+ using (var responseStream = response.GetResponseStream()) {
+ var graph = FacebookGraph.Deserialize(responseStream);
+ this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Facebook.aspx.designer.cs b/src/OAuth/OAuthClient/Facebook.aspx.designer.cs
new file mode 100644
index 0000000..a96e634
--- /dev/null
+++ b/src/OAuth/OAuthClient/Facebook.aspx.designer.cs
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient {
+
+
+ public partial class Facebook {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// nameLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label nameLabel;
+ }
+}
diff --git a/src/OAuth/OAuthClient/Global.asax b/src/OAuth/OAuthClient/Global.asax
new file mode 100644
index 0000000..2ec48f3
--- /dev/null
+++ b/src/OAuth/OAuthClient/Global.asax
@@ -0,0 +1 @@
+<%@ Application Language="C#" Inherits="OAuthClient.Global" CodeBehind="Global.asax.cs" %>
diff --git a/src/OAuth/OAuthClient/Global.asax.cs b/src/OAuth/OAuthClient/Global.asax.cs
new file mode 100644
index 0000000..77d397e
--- /dev/null
+++ b/src/OAuth/OAuthClient/Global.asax.cs
@@ -0,0 +1,35 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ public partial class Global : HttpApplication {
+ protected void Application_Start(object sender, EventArgs e) {
+ log4net.Config.XmlConfigurator.Configure();
+ Logging.Logger.Info("Sample starting...");
+ }
+
+ protected void Application_End(object sender, EventArgs e) {
+ Logging.Logger.Info("Sample shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ protected void Application_Error(object sender, EventArgs e) {
+ Logging.Logger.ErrorFormat("An unhandled exception was raised. Details follow: {0}", HttpContext.Current.Server.GetLastError());
+ }
+
+ protected void Session_Start(object sender, EventArgs e) {
+ // Code that runs when a new session is started
+ }
+
+ protected void Session_End(object sender, EventArgs e) {
+ // Code that runs when a session ends.
+ // Note: The Session_End event is raised only when the sessionstate mode
+ // is set to InProc in the Web.config file. If session mode is set to StateServer
+ // or SQLServer, the event is not raised.
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/GoogleAddressBook.aspx b/src/OAuth/OAuthClient/GoogleAddressBook.aspx
new file mode 100644
index 0000000..11891f2
--- /dev/null
+++ b/src/OAuth/OAuthClient/GoogleAddressBook.aspx
@@ -0,0 +1,26 @@
+<%@ Page Title="Gmail address book demo" Language="C#" MasterPageFile="~/MasterPage.master"
+ AutoEventWireup="true" Inherits="OAuthClient.GoogleAddressBook" Codebehind="GoogleAddressBook.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View runat="server">
+ <h2>Google setup</h2>
+ <p>A Google client app must be endorsed by a Google user. </p>
+ <ol>
+ <li><a target="_blank" href="https://www.google.com/accounts/ManageDomains">Visit Google
+ and create a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.
+ </li>
+ </ol>
+ </asp:View>
+ <asp:View runat="server">
+ <h2>Updates</h2>
+ <p>Ok, Google has authorized us to download your contacts. Click &#39;Get address book&#39;
+ to download the first 5 contacts to this sample. Notice how we never asked you
+ for your Google username or password. </p>
+ <asp:Button ID="getAddressBookButton" runat="server" OnClick="getAddressBookButton_Click"
+ Text="Get address book" />
+ <asp:PlaceHolder ID="resultsPlaceholder" runat="server" />
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthClient/GoogleAddressBook.aspx.cs b/src/OAuth/OAuthClient/GoogleAddressBook.aspx.cs
new file mode 100644
index 0000000..b7221af
--- /dev/null
+++ b/src/OAuth/OAuthClient/GoogleAddressBook.aspx.cs
@@ -0,0 +1,75 @@
+namespace OAuthClient {
+ using System;
+ using System.Configuration;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using System.Xml.Linq;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuth;
+
+ /// <summary>
+ /// A page to demonstrate downloading a Gmail address book using OAuth.
+ /// </summary>
+ public partial class GoogleAddressBook : System.Web.UI.Page {
+ private string AccessToken {
+ get { return (string)Session["GoogleAccessToken"]; }
+ set { Session["GoogleAccessToken"] = value; }
+ }
+
+ private InMemoryTokenManager TokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)Application["GoogleTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = ConfigurationManager.AppSettings["googleConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"];
+ if (!string.IsNullOrEmpty(consumerKey)) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Application["GoogleTokenManager"] = tokenManager;
+ }
+ }
+
+ return tokenManager;
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (this.TokenManager != null) {
+ this.MultiView1.ActiveViewIndex = 1;
+
+ if (!IsPostBack) {
+ var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
+
+ // Is Google calling back with authorization?
+ var accessTokenResponse = google.ProcessUserAuthorization();
+ if (accessTokenResponse != null) {
+ this.AccessToken = accessTokenResponse.AccessToken;
+ } else if (this.AccessToken == null) {
+ // If we don't yet have access, immediately request it.
+ GoogleConsumer.RequestAuthorization(google, GoogleConsumer.Applications.Contacts);
+ }
+ }
+ }
+ }
+
+ protected void getAddressBookButton_Click(object sender, EventArgs e) {
+ var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
+
+ XDocument contactsDocument = GoogleConsumer.GetContacts(google, this.AccessToken, 5, 1);
+ var contacts = from entry in contactsDocument.Root.Elements(XName.Get("entry", "http://www.w3.org/2005/Atom"))
+ select new { Name = entry.Element(XName.Get("title", "http://www.w3.org/2005/Atom")).Value, Email = entry.Element(XName.Get("email", "http://schemas.google.com/g/2005")).Attribute("address").Value };
+ StringBuilder tableBuilder = new StringBuilder();
+ tableBuilder.Append("<table><tr><td>Name</td><td>Email</td></tr>");
+ foreach (var contact in contacts) {
+ tableBuilder.AppendFormat(
+ "<tr><td>{0}</td><td>{1}</td></tr>",
+ HttpUtility.HtmlEncode(contact.Name),
+ HttpUtility.HtmlEncode(contact.Email));
+ }
+ tableBuilder.Append("</table>");
+ this.resultsPlaceholder.Controls.Add(new Literal { Text = tableBuilder.ToString() });
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/GoogleAddressBook.aspx.designer.cs b/src/OAuth/OAuthClient/GoogleAddressBook.aspx.designer.cs
new file mode 100644
index 0000000..576072e
--- /dev/null
+++ b/src/OAuth/OAuthClient/GoogleAddressBook.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient {
+
+
+ public partial class GoogleAddressBook {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// getAddressBookButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAddressBookButton;
+
+ /// <summary>
+ /// resultsPlaceholder control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder resultsPlaceholder;
+ }
+}
diff --git a/src/OAuth/OAuthClient/GoogleApps2Legged.aspx b/src/OAuth/OAuthClient/GoogleApps2Legged.aspx
new file mode 100644
index 0000000..cd9d9a1
--- /dev/null
+++ b/src/OAuth/OAuthClient/GoogleApps2Legged.aspx
@@ -0,0 +1,25 @@
+<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/MasterPage.master"CodeBehind="GoogleApps2Legged.aspx.cs" Inherits="OAuthConsumer.GoogleApps2Legged" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View runat="server">
+ <h2>Google setup</h2>
+ <p>A Google client app must be endorsed by a Google user. </p>
+ <ol>
+ <li><a target="_blank" href="https://www.google.com/accounts/ManageDomains">Visit Google
+ and create a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.
+ </li>
+ </ol>
+ </asp:View>
+ <asp:View runat="server">
+ <h2>Updates</h2>
+ <p>Ok, Google has authorized us to download your contacts. Click &#39;Get address book&#39;
+ to download the first 5 contacts to this sample. Notice how we never asked you
+ for your Google username or password. </p>
+ <asp:Button ID="getAddressBookButton" runat="server" OnClick="getAddressBookButton_Click"
+ Text="Get address book" />
+ <asp:PlaceHolder ID="resultsPlaceholder" runat="server" />
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthClient/GoogleApps2Legged.aspx.cs b/src/OAuth/OAuthClient/GoogleApps2Legged.aspx.cs
new file mode 100644
index 0000000..afb156b
--- /dev/null
+++ b/src/OAuth/OAuthClient/GoogleApps2Legged.aspx.cs
@@ -0,0 +1,39 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ public partial class GoogleApps2Legged : System.Web.UI.Page {
+ private InMemoryTokenManager TokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)Application["GoogleTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = ConfigurationManager.AppSettings["googleConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"];
+ if (!string.IsNullOrEmpty(consumerKey)) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Application["GoogleTokenManager"] = tokenManager;
+ }
+ }
+
+ return tokenManager;
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
+ string accessToken = google.RequestNewClientAccount();
+ ////string tokenSecret = google.TokenManager.GetTokenSecret(accessToken);
+ MessageReceivingEndpoint ep = null; // set up your authorized call here.
+ google.PrepareAuthorizedRequestAndSend(ep, accessToken);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/GoogleApps2Legged.aspx.designer.cs b/src/OAuth/OAuthClient/GoogleApps2Legged.aspx.designer.cs
new file mode 100644
index 0000000..f952937
--- /dev/null
+++ b/src/OAuth/OAuthClient/GoogleApps2Legged.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class GoogleApps2Legged {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// getAddressBookButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAddressBookButton;
+
+ /// <summary>
+ /// resultsPlaceholder control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder resultsPlaceholder;
+ }
+}
diff --git a/src/OAuth/OAuthClient/MasterPage.master b/src/OAuth/OAuthClient/MasterPage.master
new file mode 100644
index 0000000..4f23a05
--- /dev/null
+++ b/src/OAuth/OAuthClient/MasterPage.master
@@ -0,0 +1,23 @@
+<%@ Master Language="C#" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<script runat="server">
+
+</script>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>DotNetOpenAuth OAuth 2.0 Client sample</title>
+ <asp:ContentPlaceHolder ID="head" runat="server"/>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <h1>DotNetOpenAuth OAuth 2.0 Client ASP.NET WebForms sample</h1>
+ <div>
+ <asp:ContentPlaceHolder ID="Body" runat="server">
+ </asp:ContentPlaceHolder>
+ </div>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthClient/OAuthClient.csproj b/src/OAuth/OAuthClient/OAuthClient.csproj
new file mode 100644
index 0000000..63d2070
--- /dev/null
+++ b/src/OAuth/OAuthClient/OAuthClient.csproj
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{9529606E-AF76-4387-BFB7-3D10A5B399AA}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>OAuthClient</RootNamespace>
+ <AssemblyName>OAuthClient</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <TargetFrameworkProfile />
+ <UseIISExpress>false</UseIISExpress>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;SAMPLESONLY</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;SAMPLESONLY</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DefineConstants>$(DefineConstants);SAMPLESONLY</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="DotNetOpenAuth.Core">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.Common">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Common.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.Consumer">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Consumer.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.Consumer.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.ServiceProvider">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.ServiceProvider.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.ServiceProvider.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.Core.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2.Client">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.Client.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.Client.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OpenId, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OpenId.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OpenId.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OpenIdOAuth, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OpenIdOAuth.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OpenIdOAuth.dll</HintPath>
+ </Reference>
+ <Reference Include="log4net">
+ <HintPath>..\..\..\packages\log4net.2.0.0\lib\net35-full\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Contracts">
+ <HintPath>..\..\..\packages\CodeContracts.Unofficial.1.0.0.2\lib\net35-client\Microsoft.Contracts.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.ApplicationServices" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.DynamicData" />
+ <Reference Include="System.Web.Entity" />
+ <Reference Include="System.Xml.Linq" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Default.aspx" />
+ <Content Include="Facebook.aspx" />
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="GoogleAddressBook.aspx" />
+ <Content Include="GoogleApps2Legged.aspx" />
+ <Content Include="images\Sign-in-with-Twitter-darker.png" />
+ <Content Include="SampleWcf2Javascript.html" />
+ <Content Include="SampleWcf2Javascript.js" />
+ <Content Include="Scripts\jquery-1.6.1.js" />
+ <Content Include="Scripts\jquery-1.6.1.min.js" />
+ <Content Include="WindowsLive.aspx" />
+ <Content Include="Yammer.aspx" />
+ <Content Include="packages.config" />
+ <None Include="Service References\SampleResourceServer\DataApi.disco" />
+ <None Include="Service References\SampleResourceServer\configuration91.svcinfo" />
+ <None Include="Service References\SampleResourceServer\configuration.svcinfo" />
+ <None Include="Service References\SampleResourceServer\Reference.svcmap">
+ <Generator>WCF Proxy Generator</Generator>
+ <LastGenOutput>Reference.cs</LastGenOutput>
+ </None>
+ <Content Include="SampleWcf2.aspx" />
+ <Content Include="SignInWithTwitter.aspx" />
+ <Content Include="TracePage.aspx" />
+ <Content Include="Twitter.aspx" />
+ <Content Include="Web.config" />
+ <None Include="Service References\SampleResourceServer\DataApi1.xsd">
+ <SubType>Designer</SubType>
+ </None>
+ <None Include="Service References\SampleResourceServer\DataApi2.xsd">
+ <SubType>Designer</SubType>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Facebook.aspx.cs">
+ <DependentUpon>Facebook.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Facebook.aspx.designer.cs">
+ <DependentUpon>Facebook.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="GoogleAddressBook.aspx.designer.cs">
+ <DependentUpon>GoogleAddressBook.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="SampleWcf2.aspx.cs">
+ <DependentUpon>SampleWcf2.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="GoogleApps2Legged.aspx.cs">
+ <DependentUpon>GoogleApps2Legged.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="GoogleApps2Legged.aspx.designer.cs">
+ <DependentUpon>GoogleApps2Legged.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="SampleWcf2.aspx.designer.cs">
+ <DependentUpon>SampleWcf2.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Service References\SampleResourceServer\Reference.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Reference.svcmap</DependentUpon>
+ </Compile>
+ <Compile Include="SignInWithTwitter.aspx.cs">
+ <DependentUpon>SignInWithTwitter.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="SignInWithTwitter.aspx.designer.cs">
+ <DependentUpon>SignInWithTwitter.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="TracePage.aspx.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.designer.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Twitter.aspx.cs">
+ <DependentUpon>Twitter.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Code\Logging.cs" />
+ <Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="GoogleAddressBook.aspx.cs">
+ <DependentUpon>GoogleAddressBook.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Twitter.aspx.designer.cs">
+ <DependentUpon>Twitter.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="WindowsLive.aspx.cs">
+ <DependentUpon>WindowsLive.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="WindowsLive.aspx.designer.cs">
+ <DependentUpon>WindowsLive.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Yammer.aspx.cs">
+ <DependentUpon>Yammer.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Yammer.aspx.designer.cs">
+ <DependentUpon>Yammer.aspx</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="MasterPage.master" />
+ <None Include="Service References\SampleResourceServer\DataApi.wsdl" />
+ <None Include="Service References\SampleResourceServer\DataApi.xsd">
+ <SubType>Designer</SubType>
+ </None>
+ <None Include="Settings.StyleCop" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\DotNetOpenAuth.ApplicationBlock\DotNetOpenAuth.ApplicationBlock.csproj">
+ <Project>{AA78D112-D889-414B-A7D4-467B34C7B663}</Project>
+ <Name>DotNetOpenAuth.ApplicationBlock</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <WCFMetadata Include="Service References\" />
+ </ItemGroup>
+ <ItemGroup>
+ <WCFMetadataStorage Include="Service References\SampleResourceServer\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>False</AutoAssignPort>
+ <DevelopmentServerPort>59721</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+</Project> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Properties/AssemblyInfo.cs b/src/OAuth/OAuthClient/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..9eb70fe
--- /dev/null
+++ b/src/OAuth/OAuthClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OAuthClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OAuthClient")]
+[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("12549916-9ec2-4cf6-9fe3-82ea1f6ea665")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/OAuth/OAuthClient/SampleWcf2.aspx b/src/OAuth/OAuthClient/SampleWcf2.aspx
new file mode 100644
index 0000000..cfacaf1
--- /dev/null
+++ b/src/OAuth/OAuthClient/SampleWcf2.aspx
@@ -0,0 +1,33 @@
+<%@ Page Title="OAuth 2.0 client (web server flow)" Language="C#" MasterPageFile="~/MasterPage.master"
+ AutoEventWireup="true" Inherits="OAuthClient.SampleWcf2" CodeBehind="SampleWcf2.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <fieldset title="Authorization">
+ <p>
+ Check off the operations you&#39;d like to authorization this client to make on
+ behalf of your account on the resource server.<br />
+ Note that an authorization request may not actually result in you being prompted
+ to grant authorization if you&#39;ve granted it previously.&nbsp; The authorization
+ server remembers what you&#39;ve already approved.&nbsp; But even if you&#39;ve
+ requested and received authorization for all three scopes above, you can request
+ access tokens for subsets of this set of scopes to limit what you can do below.
+ </p>
+ <asp:CheckBoxList runat="server" ID="scopeList">
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetName">GetName</asp:ListItem>
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetAge">GetAge</asp:ListItem>
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetFavoriteSites">GetFavoriteSites</asp:ListItem>
+ </asp:CheckBoxList>
+ <asp:Button ID="getAuthorizationButton" runat="server" Text="Request Authorization"
+ OnClick="getAuthorizationButton_Click" />
+ <asp:Label ID="authorizationLabel" runat="server" />
+ </fieldset>
+ <br />
+ <asp:Button ID="getNameButton" runat="server" Text="Get Name" OnClick="getNameButton_Click" />
+ <asp:Label ID="nameLabel" runat="server" />
+ <br />
+ <asp:Button ID="getAgeButton" runat="server" Text="Get Age" OnClick="getAgeButton_Click" />
+ <asp:Label ID="ageLabel" runat="server" />
+ <br />
+ <asp:Button ID="getFavoriteSites" runat="server" Text="Get Favorite Sites" OnClick="getFavoriteSites_Click" />
+ <asp:Label ID="favoriteSitesLabel" runat="server" />
+</asp:Content>
diff --git a/src/OAuth/OAuthClient/SampleWcf2.aspx.cs b/src/OAuth/OAuthClient/SampleWcf2.aspx.cs
new file mode 100644
index 0000000..130932c
--- /dev/null
+++ b/src/OAuth/OAuthClient/SampleWcf2.aspx.cs
@@ -0,0 +1,137 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Linq;
+ using System.Net;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Security;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.OAuth2;
+
+ using SampleResourceServer;
+
+ public partial class SampleWcf2 : System.Web.UI.Page {
+ /// <summary>
+ /// The OAuth 2.0 client object to use to obtain authorization and authorize outgoing HTTP requests.
+ /// </summary>
+ private static readonly WebServerClient Client;
+
+ /// <summary>
+ /// The details about the sample OAuth-enabled WCF service that this sample client calls into.
+ /// </summary>
+ private static AuthorizationServerDescription authServerDescription = new AuthorizationServerDescription {
+ TokenEndpoint = new Uri("http://localhost:50172/OAuth/Token"),
+ AuthorizationEndpoint = new Uri("http://localhost:50172/OAuth/Authorize"),
+ };
+
+ /// <summary>
+ /// Initializes static members of the <see cref="SampleWcf2"/> class.
+ /// </summary>
+ static SampleWcf2() {
+ Client = new WebServerClient(authServerDescription, "sampleconsumer", "samplesecret");
+ }
+
+ /// <summary>
+ /// Gets or sets the authorization details for the logged in user.
+ /// </summary>
+ /// <value>The authorization details.</value>
+ /// <remarks>
+ /// Because this is a sample, we simply store the authorization information in memory with the user session.
+ /// A real web app should store at least the access and refresh tokens in this object in a database associated with the user.
+ /// </remarks>
+ private static IAuthorizationState Authorization {
+ get { return (AuthorizationState)HttpContext.Current.Session["Authorization"]; }
+ set { HttpContext.Current.Session["Authorization"] = value; }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (!IsPostBack) {
+ // Check to see if we're receiving a end user authorization response.
+ var authorization = Client.ProcessUserAuthorization();
+ if (authorization != null) {
+ // We are receiving an authorization response. Store it and associate it with this user.
+ Authorization = authorization;
+ Response.Redirect(Request.Path); // get rid of the /?code= parameter
+ }
+ }
+
+ if (Authorization != null) {
+ // Indicate to the user that we have already obtained authorization on some of these.
+ foreach (var li in this.scopeList.Items.OfType<ListItem>().Where(li => Authorization.Scope.Contains(li.Value))) {
+ li.Selected = true;
+ }
+ this.authorizationLabel.Text = "Authorization received!";
+ if (Authorization.AccessTokenExpirationUtc.HasValue) {
+ TimeSpan timeLeft = Authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
+ this.authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " (access token expires in {0} minutes)", Math.Round(timeLeft.TotalMinutes, 1));
+ }
+ }
+
+ this.getNameButton.Enabled = this.getAgeButton.Enabled = this.getFavoriteSites.Enabled = Authorization != null;
+ }
+
+ protected void getAuthorizationButton_Click(object sender, EventArgs e) {
+ string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>()
+ where item.Selected
+ select item.Value).ToArray();
+
+ Client.RequestUserAuthorization(scopes);
+ }
+
+ protected void getNameButton_Click(object sender, EventArgs e) {
+ try {
+ this.nameLabel.Text = this.CallService(client => client.GetName());
+ } catch (SecurityAccessDeniedException) {
+ this.nameLabel.Text = "Access denied!";
+ }
+ }
+
+ protected void getAgeButton_Click(object sender, EventArgs e) {
+ try {
+ int? age = this.CallService(client => client.GetAge());
+ this.ageLabel.Text = age.HasValue ? age.Value.ToString(CultureInfo.CurrentCulture) : "not available";
+ } catch (SecurityAccessDeniedException) {
+ this.ageLabel.Text = "Access denied!";
+ }
+ }
+
+ protected void getFavoriteSites_Click(object sender, EventArgs e) {
+ try {
+ string[] favoriteSites = this.CallService(client => client.GetFavoriteSites());
+ this.favoriteSitesLabel.Text = string.Join(", ", favoriteSites);
+ } catch (SecurityAccessDeniedException) {
+ this.favoriteSitesLabel.Text = "Access denied!";
+ }
+ }
+
+ private T CallService<T>(Func<DataApiClient, T> predicate) {
+ if (Authorization == null) {
+ throw new InvalidOperationException("No access token!");
+ }
+
+ var wcfClient = new DataApiClient();
+
+ // Refresh the access token if it expires and if its lifetime is too short to be of use.
+ if (Authorization.AccessTokenExpirationUtc.HasValue) {
+ if (Client.RefreshAuthorization(Authorization, TimeSpan.FromSeconds(30))) {
+ TimeSpan timeLeft = Authorization.AccessTokenExpirationUtc.Value - DateTime.UtcNow;
+ this.authorizationLabel.Text += string.Format(CultureInfo.CurrentCulture, " - just renewed for {0} more minutes)", Math.Round(timeLeft.TotalMinutes, 1));
+ }
+ }
+
+ var httpRequest = (HttpWebRequest)WebRequest.Create(wcfClient.Endpoint.Address.Uri);
+ ClientBase.AuthorizeRequest(httpRequest, Authorization.AccessToken);
+
+ var httpDetails = new HttpRequestMessageProperty();
+ httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization];
+ using (var scope = new OperationContextScope(wcfClient.InnerChannel)) {
+ OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpDetails;
+ return predicate(wcfClient);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/SampleWcf2.aspx.designer.cs b/src/OAuth/OAuthClient/SampleWcf2.aspx.designer.cs
new file mode 100644
index 0000000..eed51b0
--- /dev/null
+++ b/src/OAuth/OAuthClient/SampleWcf2.aspx.designer.cs
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient {
+
+
+ public partial class SampleWcf2 {
+
+ /// <summary>
+ /// scopeList control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CheckBoxList scopeList;
+
+ /// <summary>
+ /// getAuthorizationButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAuthorizationButton;
+
+ /// <summary>
+ /// authorizationLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label authorizationLabel;
+
+ /// <summary>
+ /// getNameButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getNameButton;
+
+ /// <summary>
+ /// nameLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label nameLabel;
+
+ /// <summary>
+ /// getAgeButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAgeButton;
+
+ /// <summary>
+ /// ageLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label ageLabel;
+
+ /// <summary>
+ /// getFavoriteSites control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getFavoriteSites;
+
+ /// <summary>
+ /// favoriteSitesLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label favoriteSitesLabel;
+ }
+}
diff --git a/src/OAuth/OAuthClient/SampleWcf2Javascript.html b/src/OAuth/OAuthClient/SampleWcf2Javascript.html
new file mode 100644
index 0000000..d9d957e
--- /dev/null
+++ b/src/OAuth/OAuthClient/SampleWcf2Javascript.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>OAuth 2.0 client (implicit grant)</title>
+
+ <script src="Scripts/jquery-1.6.1.js" type="text/javascript"></script>
+ <script src="SampleWcf2Javascript.js" type="text/javascript"></script>
+</head>
+<body>
+ <h1>
+ DotNetOpenAuth OAuth 2.0 Client ASP.NET WebForms sample</h1>
+ <div>
+ <fieldset title="Authorization">
+ <p>
+ Check off the operations you&#39;d like to authorization this client to make on
+ behalf of your account on the resource server.<br />
+ Note that an authorization request may not actually result in you being prompted
+ to grant authorization if you&#39;ve granted it previously.&nbsp; The authorization
+ server remembers what you&#39;ve already approved.&nbsp; But even if you&#39;ve
+ requested and received authorization for all three scopes above, you can request
+ access tokens for subsets of this set of scopes to limit what you can do below.
+ </p>
+ <table border="0">
+ <tr>
+ <td>
+ <input type="checkbox" name='scope' value='/DataApi.svc/web/name' id="getNameScopeCheckbox" /><label for="getNameScopeCheckbox">GetName</label>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="checkbox" name='scope' value='/DataApi.svc/web/age' id="getAgeScopeCheckbox" /><label for="getAgeScopeCheckbox">GetAge</label>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <input type="checkbox" name='scope' value='/DataApi.svc/web/favoritesites' id="getFavoriteSitesScopeCheckbox" /><label for="getFavoriteSitesScopeCheckbox">GetFavoriteSites</label>
+ </td>
+ </tr>
+ </table>
+ <input type="submit" id="requestAuthorizationButton" value="Request Authorization" />
+ <span id="authorizationLabel" />
+ </fieldset>
+ <br />
+ <input type="button" value="Get Name" id="getNameButton" operation='/DataApi.svc/web/name' disabled="disabled" />
+ <span id="nameLabel" operation='/DataApi.svc/web/name' ></span>
+ <br />
+ <input type="button" value="Get Age" id="getAgeButton" operation='/DataApi.svc/web/age' disabled="disabled" />
+ <span id="ageLabel" operation='/DataApi.svc/web/age' ></span>
+ <br />
+ <input type="button" value="Get Favorite Sites" id="getFavoriteSitesButton" operation='/DataApi.svc/web/favoritesites' disabled="disabled" />
+ <span id="favoriteSitesLabel" operation='/DataApi.svc/web/favoritesites' ></span>
+</body>
+</html>
diff --git a/src/OAuth/OAuthClient/SampleWcf2Javascript.js b/src/OAuth/OAuthClient/SampleWcf2Javascript.js
new file mode 100644
index 0000000..df72938
--- /dev/null
+++ b/src/OAuth/OAuthClient/SampleWcf2Javascript.js
@@ -0,0 +1,101 @@
+var utilities = {
+ assembleQueryString: function(args) {
+ var query = '?';
+ for (var key in args) {
+ if (query.length > 1) query += '&';
+ query += encodeURIComponent(key) + '=' + encodeURIComponent(args[key])
+ };
+ return query;
+ },
+
+ parseQueryString: function (query) {
+ var result = new Array();
+ var pairs = query.split('&');
+ for (var i = 0; i < pairs.length; i++) {
+ var pair = pairs[i].split('=');
+ var key = decodeURIComponent(pair[0]);
+ var value = decodeURIComponent(pair[1]);
+ result[key] = value;
+ };
+ return result;
+ },
+
+ stripQueryAndFragment: function (url) {
+ var index = url.indexOf('?');
+ if (index < 0) index = url.indexOf('#');
+ url = index < 0 ? url : url.substring(0, index);
+ return url;
+ }
+};
+
+$(document).ready(function () {
+ var requestAuthorizationButton = $('#requestAuthorizationButton');
+
+ function gatherRequestedScopes() {
+ scopes = '';
+ var scopeElements = $("input[name='scope']");
+ for (var i = 0; i < scopeElements.length; i++) {
+ if (scopeElements[i].checked) {
+ if (scopes.length > 0) scopes += ' ';
+ scopes += scopeElements[i].value;
+ }
+ };
+ return scopes;
+ };
+
+ function requestAuthorizationButton_onClick(evt) {
+ var args = new Array();
+ args['scope'] = gatherRequestedScopes();
+ args['redirect_uri'] = utilities.stripQueryAndFragment(document.location.href);
+ args['response_type'] = 'token';
+ args['client_id'] = 'sampleImplicitConsumer';
+
+ var authorizeUrl = "http://localhost:50172/OAuth/Authorize" + utilities.assembleQueryString(args);
+ document.location = authorizeUrl;
+ };
+
+ requestAuthorizationButton.click(requestAuthorizationButton_onClick);
+});
+
+$(document).ready(function () {
+ $.support.cors = true; // force cross-site scripting (as of jQuery 1.5)
+ function serviceCall(operation, accessToken, label) {
+ label.text('fetching...');
+ $.ajax({
+ url: "http://localhost:65169" + encodeURI(operation),
+ headers: {
+ "Authorization": "Bearer " + accessToken
+ },
+ cache: false,
+ success: function (data, textStatus, jqXHR) { label.text(data.toString()); },
+ error: function (jqXHR, textStatus, errorThrown) { label.text(textStatus + ": " + errorThrown); }
+ });
+ };
+
+ var fragmentIndex = document.location.href.indexOf('#');
+ if (fragmentIndex > 0) {
+ var fragment = document.location.href.substring(fragmentIndex + 1);
+ var args = utilities.parseQueryString(fragment);
+ if (args['access_token']) {
+ var authorizationLabel = $('#authorizationLabel');
+ var lifetimeInSeconds = args['expires_in'];
+ var suffix = '(access token expires in ' + lifetimeInSeconds + ' seconds)';
+ authorizationLabel.text('Authorization received! ' + suffix);
+
+ var scopes = args['scope'].split(' ');
+ for (var scopeIndex in scopes) {
+ var scope = scopes[scopeIndex];
+ var button = $('input[operation="' + scope + '"]');
+ button[0].disabled = false;
+ button.click((function (value) {
+ return function () {
+ var label = $('span[operation="' + value + '"]');
+ serviceCall(value, args['access_token'], label);
+ };
+ })(scope));
+ var checkbox = $('input[value="' + scope + '"]')[0];
+ checkbox.checked = true;
+ };
+ }
+ }
+}); \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Scripts/jquery-1.6.1.js b/src/OAuth/OAuthClient/Scripts/jquery-1.6.1.js
new file mode 100644
index 0000000..5d5a1d5
--- /dev/null
+++ b/src/OAuth/OAuthClient/Scripts/jquery-1.6.1.js
@@ -0,0 +1,8936 @@
+/*!
+ * jQuery JavaScript Library v1.6.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu May 12 15:04:36 2011 -0400
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document,
+ navigator = window.navigator,
+ location = window.location;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context, rootjQuery );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+
+ // Used for trimming whitespace
+ trimLeft = /^\s+/,
+ trimRight = /\s+$/,
+
+ // Check for digits
+ rdigit = /\d/,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // JSON RegExp
+ rvalidchars = /^[\],:{}\s]*$/,
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+ rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+ // Useragent RegExp
+ rwebkit = /(webkit)[ \/]([\w.]+)/,
+ ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+ rmsie = /(msie) ([\w.]+)/,
+ rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // The deferred used on DOM ready
+ readyList,
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwn = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ trim = String.prototype.trim,
+ indexOf = Array.prototype.indexOf,
+
+ // [[Class]] -> type pairs
+ class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+ constructor: jQuery,
+ init: function( selector, context, rootjQuery ) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // The body element only exists once, optimize finding it
+ if ( selector === "body" && !context && document.body ) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = quickExpr.exec( selector );
+ }
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ context = context instanceof jQuery ? context[0] : context;
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
+ }
+
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.6.1",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this[ this.length + num ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = this.constructor();
+
+ if ( jQuery.isArray( elems ) ) {
+ push.apply( ret, elems );
+
+ } else {
+ jQuery.merge( ret, elems );
+ }
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // Add the callback
+ readyList.done( fn );
+
+ return this;
+ },
+
+ eq: function( i ) {
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray(src) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ if ( window.$ === jQuery ) {
+ window.$ = _$;
+ }
+
+ if ( deep && window.jQuery === jQuery ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+ // Either a released hold or an DOMready/load event and not yet ready
+ if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger( "ready" ).unbind( "ready" );
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyList ) {
+ return;
+ }
+
+ readyList = jQuery._Deferred();
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent( "onreadystatechange", DOMContentLoaded );
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return jQuery.type(obj) === "function";
+ },
+
+ isArray: Array.isArray || function( obj ) {
+ return jQuery.type(obj) === "array";
+ },
+
+ // A crude way of determining if an object is a window
+ isWindow: function( obj ) {
+ return obj && typeof obj === "object" && "setInterval" in obj;
+ },
+
+ isNaN: function( obj ) {
+ return obj == null || !rdigit.test( obj ) || isNaN( obj );
+ },
+
+ type: function( obj ) {
+ return obj == null ?
+ String( obj ) :
+ class2type[ toString.call(obj) ] || "object";
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call(obj, "constructor") &&
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ // Attempt to parse using the native JSON parser first
+ if ( window.JSON && window.JSON.parse ) {
+ return window.JSON.parse( data );
+ }
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( rvalidchars.test( data.replace( rvalidescape, "@" )
+ .replace( rvalidtokens, "]" )
+ .replace( rvalidbraces, "")) ) {
+
+ return (new Function( "return " + data ))();
+
+ }
+ jQuery.error( "Invalid JSON: " + data );
+ },
+
+ // Cross-browser xml parsing
+ // (xml & tmp used internally)
+ parseXML: function( data , xml , tmp ) {
+
+ if ( window.DOMParser ) { // Standard
+ tmp = new DOMParser();
+ xml = tmp.parseFromString( data , "text/xml" );
+ } else { // IE
+ xml = new ActiveXObject( "Microsoft.XMLDOM" );
+ xml.async = "false";
+ xml.loadXML( data );
+ }
+
+ tmp = xml.documentElement;
+
+ if ( ! tmp || ! tmp.nodeName || tmp.nodeName === "parsererror" ) {
+ jQuery.error( "Invalid XML: " + data );
+ }
+
+ return xml;
+ },
+
+ noop: function() {},
+
+ // Evaluates a script in a global context
+ // Workarounds based on findings by Jim Driscoll
+ // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
+ globalEval: function( data ) {
+ if ( data && rnotwhite.test( data ) ) {
+ // We use execScript on Internet Explorer
+ // We use an anonymous function so that context is window
+ // rather than jQuery in Firefox
+ ( window.execScript || function( data ) {
+ window[ "eval" ].call( window, data );
+ } )( data );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction( object );
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return object;
+ },
+
+ // Use native String.trim function wherever possible
+ trim: trim ?
+ function( text ) {
+ return text == null ?
+ "" :
+ trim.call( text );
+ } :
+
+ // Otherwise use our own trimming functionality
+ function( text ) {
+ return text == null ?
+ "" :
+ text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+ var type = jQuery.type( array );
+
+ if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+
+ if ( indexOf ) {
+ return indexOf.call( array, elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length,
+ j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [], retVal;
+ inv = !!inv;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ retVal = !!callback( elems[ i ], i );
+ if ( inv !== retVal ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var value, key, ret = [],
+ i = 0,
+ length = elems.length,
+ // jquery objects are treated as arrays
+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
+
+ // Go through the array, translating each of the items to their
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( key in elems ) {
+ value = callback( elems[ key ], key, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ if ( typeof context === "string" ) {
+ var tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ var args = slice.call( arguments, 2 ),
+ proxy = function() {
+ return fn.apply( context, args.concat( slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ // Mutifunctional method to get and set values to a collection
+ // The value/s can be optionally by executed if its a function
+ access: function( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ jQuery.access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : undefined;
+ },
+
+ now: function() {
+ return (new Date()).getTime();
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = rwebkit.exec( ua ) ||
+ ropera.exec( ua ) ||
+ rmsie.exec( ua ) ||
+ ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ sub: function() {
+ function jQuerySub( selector, context ) {
+ return new jQuerySub.fn.init( selector, context );
+ }
+ jQuery.extend( true, jQuerySub, this );
+ jQuerySub.superclass = this;
+ jQuerySub.fn = jQuerySub.prototype = this();
+ jQuerySub.fn.constructor = jQuerySub;
+ jQuerySub.sub = this.sub;
+ jQuerySub.fn.init = function init( selector, context ) {
+ if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
+ context = jQuerySub( context );
+ }
+
+ return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
+ };
+ jQuerySub.fn.init.prototype = jQuerySub.fn;
+ var rootjQuerySub = jQuerySub(document);
+ return jQuerySub;
+ },
+
+ browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+// IE doesn't match non-breaking spaces with \s
+if ( rnotwhite.test( "\xA0" ) ) {
+ trimLeft = /^[\s\xA0]+/;
+ trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch(e) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+// Expose jQuery to the global object
+return jQuery;
+
+})();
+
+
+var // Promise methods
+ promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
+ // Static reference to slice
+ sliceDeferred = [].slice;
+
+jQuery.extend({
+ // Create a simple deferred (one callbacks list)
+ _Deferred: function() {
+ var // callbacks list
+ callbacks = [],
+ // stored [ context , args ]
+ fired,
+ // to avoid firing when already doing so
+ firing,
+ // flag to know if the deferred has been cancelled
+ cancelled,
+ // the deferred itself
+ deferred = {
+
+ // done( f1, f2, ...)
+ done: function() {
+ if ( !cancelled ) {
+ var args = arguments,
+ i,
+ length,
+ elem,
+ type,
+ _fired;
+ if ( fired ) {
+ _fired = fired;
+ fired = 0;
+ }
+ for ( i = 0, length = args.length; i < length; i++ ) {
+ elem = args[ i ];
+ type = jQuery.type( elem );
+ if ( type === "array" ) {
+ deferred.done.apply( deferred, elem );
+ } else if ( type === "function" ) {
+ callbacks.push( elem );
+ }
+ }
+ if ( _fired ) {
+ deferred.resolveWith( _fired[ 0 ], _fired[ 1 ] );
+ }
+ }
+ return this;
+ },
+
+ // resolve with given context and args
+ resolveWith: function( context, args ) {
+ if ( !cancelled && !fired && !firing ) {
+ // make sure args are available (#8421)
+ args = args || [];
+ firing = 1;
+ try {
+ while( callbacks[ 0 ] ) {
+ callbacks.shift().apply( context, args );
+ }
+ }
+ finally {
+ fired = [ context, args ];
+ firing = 0;
+ }
+ }
+ return this;
+ },
+
+ // resolve with this as context and given arguments
+ resolve: function() {
+ deferred.resolveWith( this, arguments );
+ return this;
+ },
+
+ // Has this deferred been resolved?
+ isResolved: function() {
+ return !!( firing || fired );
+ },
+
+ // Cancel
+ cancel: function() {
+ cancelled = 1;
+ callbacks = [];
+ return this;
+ }
+ };
+
+ return deferred;
+ },
+
+ // Full fledged deferred (two callbacks list)
+ Deferred: function( func ) {
+ var deferred = jQuery._Deferred(),
+ failDeferred = jQuery._Deferred(),
+ promise;
+ // Add errorDeferred methods, then and promise
+ jQuery.extend( deferred, {
+ then: function( doneCallbacks, failCallbacks ) {
+ deferred.done( doneCallbacks ).fail( failCallbacks );
+ return this;
+ },
+ always: function() {
+ return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
+ },
+ fail: failDeferred.done,
+ rejectWith: failDeferred.resolveWith,
+ reject: failDeferred.resolve,
+ isRejected: failDeferred.isResolved,
+ pipe: function( fnDone, fnFail ) {
+ return jQuery.Deferred(function( newDefer ) {
+ jQuery.each( {
+ done: [ fnDone, "resolve" ],
+ fail: [ fnFail, "reject" ]
+ }, function( handler, data ) {
+ var fn = data[ 0 ],
+ action = data[ 1 ],
+ returned;
+ if ( jQuery.isFunction( fn ) ) {
+ deferred[ handler ](function() {
+ returned = fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise().then( newDefer.resolve, newDefer.reject );
+ } else {
+ newDefer[ action ]( returned );
+ }
+ });
+ } else {
+ deferred[ handler ]( newDefer[ action ] );
+ }
+ });
+ }).promise();
+ },
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ if ( obj == null ) {
+ if ( promise ) {
+ return promise;
+ }
+ promise = obj = {};
+ }
+ var i = promiseMethods.length;
+ while( i-- ) {
+ obj[ promiseMethods[i] ] = deferred[ promiseMethods[i] ];
+ }
+ return obj;
+ }
+ });
+ // Make sure only one callback list will be used
+ deferred.done( failDeferred.cancel ).fail( deferred.cancel );
+ // Unexpose cancel
+ delete deferred.cancel;
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( firstParam ) {
+ var args = arguments,
+ i = 0,
+ length = args.length,
+ count = length,
+ deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
+ firstParam :
+ jQuery.Deferred();
+ function resolveFunc( i ) {
+ return function( value ) {
+ args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
+ if ( !( --count ) ) {
+ // Strange bug in FF4:
+ // Values changed onto the arguments object sometimes end up as undefined values
+ // outside the $.when method. Cloning the object into a fresh array solves the issue
+ deferred.resolveWith( deferred, sliceDeferred.call( args, 0 ) );
+ }
+ };
+ }
+ if ( length > 1 ) {
+ for( ; i < length; i++ ) {
+ if ( args[ i ] && jQuery.isFunction( args[ i ].promise ) ) {
+ args[ i ].promise().then( resolveFunc(i), deferred.reject );
+ } else {
+ --count;
+ }
+ }
+ if ( !count ) {
+ deferred.resolveWith( deferred, args );
+ }
+ } else if ( deferred !== firstParam ) {
+ deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
+ }
+ return deferred.promise();
+ }
+});
+
+
+
+jQuery.support = (function() {
+
+ var div = document.createElement( "div" ),
+ documentElement = document.documentElement,
+ all,
+ a,
+ select,
+ opt,
+ input,
+ marginDiv,
+ support,
+ fragment,
+ body,
+ bodyStyle,
+ tds,
+ events,
+ eventName,
+ i,
+ isSupported;
+
+ // Preliminary tests
+ div.setAttribute("className", "t");
+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+ all = div.getElementsByTagName( "*" );
+ a = div.getElementsByTagName( "a" )[ 0 ];
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return {};
+ }
+
+ // First batch of supports tests
+ select = document.createElement( "select" );
+ opt = select.appendChild( document.createElement("option") );
+ input = div.getElementsByTagName( "input" )[ 0 ];
+
+ support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: ( div.firstChild.nodeType === 3 ),
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName( "tbody" ).length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName( "link" ).length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText instead)
+ style: /top/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55$/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: ( input.value === "on" ),
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: opt.selected,
+
+ // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+ getSetAttribute: div.className !== "t",
+
+ // Will be defined later
+ submitBubbles: true,
+ changeBubbles: true,
+ focusinBubbles: false,
+ deleteExpando: true,
+ noCloneEvent: true,
+ inlineBlockNeedsLayout: false,
+ shrinkWrapBlocks: false,
+ reliableMarginRight: true
+ };
+
+ // Make sure checked status is properly cloned
+ input.checked = true;
+ support.noCloneChecked = input.cloneNode( true ).checked;
+
+ // Make sure that the options inside disabled selects aren't marked as disabled
+ // (WebKit marks them as disabled)
+ select.disabled = true;
+ support.optDisabled = !opt.disabled;
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete div.test;
+ } catch( e ) {
+ support.deleteExpando = false;
+ }
+
+ if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
+ div.attachEvent( "onclick", function click() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ support.noCloneEvent = false;
+ div.detachEvent( "onclick", click );
+ });
+ div.cloneNode( true ).fireEvent( "onclick" );
+ }
+
+ // Check if a radio maintains it's value
+ // after being appended to the DOM
+ input = document.createElement("input");
+ input.value = "t";
+ input.setAttribute("type", "radio");
+ support.radioValue = input.value === "t";
+
+ input.setAttribute("checked", "checked");
+ div.appendChild( input );
+ fragment = document.createDocumentFragment();
+ fragment.appendChild( div.firstChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ div.innerHTML = "";
+
+ // Figure out if the W3C box model works as expected
+ div.style.width = div.style.paddingLeft = "1px";
+
+ // We use our own, invisible, body
+ body = document.createElement( "body" );
+ bodyStyle = {
+ visibility: "hidden",
+ width: 0,
+ height: 0,
+ border: 0,
+ margin: 0,
+ // Set background to avoid IE crashes when removing (#9028)
+ background: "none"
+ };
+ for ( i in bodyStyle ) {
+ body.style[ i ] = bodyStyle[ i ];
+ }
+ body.appendChild( div );
+ documentElement.insertBefore( body, documentElement.firstChild );
+
+ // Check if a disconnected checkbox will retain its checked
+ // value of true after appended to the DOM (IE6/7)
+ support.appendChecked = input.checked;
+
+ support.boxModel = div.offsetWidth === 2;
+
+ if ( "zoom" in div.style ) {
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ // (IE < 8 does this)
+ div.style.display = "inline";
+ div.style.zoom = 1;
+ support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
+
+ // Check if elements with layout shrink-wrap their children
+ // (IE 6 does this)
+ div.style.display = "";
+ div.innerHTML = "<div style='width:4px;'></div>";
+ support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
+ }
+
+ div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
+ tds = div.getElementsByTagName( "td" );
+
+ // Check if table cells still have offsetWidth/Height when they are set
+ // to display:none and there are still other visible table cells in a
+ // table row; if so, offsetWidth/Height are not reliable for use when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element is
+ // hidden; don safety goggles and see bug #4512 for more information).
+ // (only IE 8 fails this test)
+ isSupported = ( tds[ 0 ].offsetHeight === 0 );
+
+ tds[ 0 ].style.display = "";
+ tds[ 1 ].style.display = "none";
+
+ // Check if empty table cells still have offsetWidth/Height
+ // (IE < 8 fail this test)
+ support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
+ div.innerHTML = "";
+
+ // Check if div with explicit width and no margin-right incorrectly
+ // gets computed margin-right based on width of container. For more
+ // info see bug #3333
+ // Fails in WebKit before Feb 2011 nightlies
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ marginDiv = document.createElement( "div" );
+ marginDiv.style.width = "0";
+ marginDiv.style.marginRight = "0";
+ div.appendChild( marginDiv );
+ support.reliableMarginRight =
+ ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
+ }
+
+ // Remove the body element we added
+ body.innerHTML = "";
+ documentElement.removeChild( body );
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ // We only care about the case where non-standard event systems
+ // are used, namely in IE. Short-circuiting here helps us to
+ // avoid an eval call (in setAttribute) which can cause CSP
+ // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+ if ( div.attachEvent ) {
+ for( i in {
+ submit: 1,
+ change: 1,
+ focusin: 1
+ } ) {
+ eventName = "on" + i;
+ isSupported = ( eventName in div );
+ if ( !isSupported ) {
+ div.setAttribute( eventName, "return;" );
+ isSupported = ( typeof div[ eventName ] === "function" );
+ }
+ support[ i + "Bubbles" ] = isSupported;
+ }
+ }
+
+ return support;
+})();
+
+// Keep track of boxModel
+jQuery.boxModel = jQuery.support.boxModel;
+
+
+
+
+var rbrace = /^(?:\{.*\}|\[.*\])$/,
+ rmultiDash = /([a-z])([A-Z])/g;
+
+jQuery.extend({
+ cache: {},
+
+ // Please use with caution
+ uuid: 0,
+
+ // Unique for each copy of jQuery on the page
+ // Non-digits removed to match rinlinejQuery
+ expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ // Ban all objects except for Flash (which handle expandos)
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+ "applet": true
+ },
+
+ hasData: function( elem ) {
+ elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
+
+ return !!elem && !isEmptyDataObject( elem );
+ },
+
+ data: function( elem, name, data, pvt /* Internal Use Only */ ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var internalKey = jQuery.expando, getByName = typeof name === "string", thisCache,
+
+ // We have to handle DOM nodes and JS objects differently because IE6-7
+ // can't GC object references properly across the DOM-JS boundary
+ isNode = elem.nodeType,
+
+ // Only DOM nodes need the global jQuery cache; JS object data is
+ // attached directly to the object so GC can occur automatically
+ cache = isNode ? jQuery.cache : elem,
+
+ // Only defining an ID for JS objects if its cache already exists allows
+ // the code to shortcut on the same path as a DOM node with no cache
+ id = isNode ? elem[ jQuery.expando ] : elem[ jQuery.expando ] && jQuery.expando;
+
+ // Avoid doing any more work than we need to when trying to get data on an
+ // object that has no data at all
+ if ( (!id || (pvt && id && !cache[ id ][ internalKey ])) && getByName && data === undefined ) {
+ return;
+ }
+
+ if ( !id ) {
+ // Only DOM nodes need a new unique ID for each element since their data
+ // ends up in the global cache
+ if ( isNode ) {
+ elem[ jQuery.expando ] = id = ++jQuery.uuid;
+ } else {
+ id = jQuery.expando;
+ }
+ }
+
+ if ( !cache[ id ] ) {
+ cache[ id ] = {};
+
+ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+ // metadata on plain JS objects when the object is serialized using
+ // JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+ }
+
+ // An object can be passed to jQuery.data instead of a key/value pair; this gets
+ // shallow copied over onto the existing cache
+ if ( typeof name === "object" || typeof name === "function" ) {
+ if ( pvt ) {
+ cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
+ } else {
+ cache[ id ] = jQuery.extend(cache[ id ], name);
+ }
+ }
+
+ thisCache = cache[ id ];
+
+ // Internal jQuery data is stored in a separate object inside the object's data
+ // cache in order to avoid key collisions between internal data and user-defined
+ // data
+ if ( pvt ) {
+ if ( !thisCache[ internalKey ] ) {
+ thisCache[ internalKey ] = {};
+ }
+
+ thisCache = thisCache[ internalKey ];
+ }
+
+ if ( data !== undefined ) {
+ thisCache[ jQuery.camelCase( name ) ] = data;
+ }
+
+ // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
+ // not attempt to inspect the internal events object using jQuery.data, as this
+ // internal data object is undocumented and subject to change.
+ if ( name === "events" && !thisCache[name] ) {
+ return thisCache[ internalKey ] && thisCache[ internalKey ].events;
+ }
+
+ return getByName ? thisCache[ jQuery.camelCase( name ) ] : thisCache;
+ },
+
+ removeData: function( elem, name, pvt /* Internal Use Only */ ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ var internalKey = jQuery.expando, isNode = elem.nodeType,
+
+ // See jQuery.data for more information
+ cache = isNode ? jQuery.cache : elem,
+
+ // See jQuery.data for more information
+ id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
+
+ // If there is already no cache entry for this object, there is no
+ // purpose in continuing
+ if ( !cache[ id ] ) {
+ return;
+ }
+
+ if ( name ) {
+ var thisCache = pvt ? cache[ id ][ internalKey ] : cache[ id ];
+
+ if ( thisCache ) {
+ delete thisCache[ name ];
+
+ // If there is no data left in the cache, we want to continue
+ // and let the cache object itself get destroyed
+ if ( !isEmptyDataObject(thisCache) ) {
+ return;
+ }
+ }
+ }
+
+ // See jQuery.data for more information
+ if ( pvt ) {
+ delete cache[ id ][ internalKey ];
+
+ // Don't destroy the parent cache unless the internal data object
+ // had been the only thing left in it
+ if ( !isEmptyDataObject(cache[ id ]) ) {
+ return;
+ }
+ }
+
+ var internalCache = cache[ id ][ internalKey ];
+
+ // Browsers that fail expando deletion also refuse to delete expandos on
+ // the window, but it will allow it on all other JS objects; other browsers
+ // don't care
+ if ( jQuery.support.deleteExpando || cache != window ) {
+ delete cache[ id ];
+ } else {
+ cache[ id ] = null;
+ }
+
+ // We destroyed the entire user cache at once because it's faster than
+ // iterating through each key, but we need to continue to persist internal
+ // data if it existed
+ if ( internalCache ) {
+ cache[ id ] = {};
+ // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+ // metadata on plain JS objects when the object is serialized using
+ // JSON.stringify
+ if ( !isNode ) {
+ cache[ id ].toJSON = jQuery.noop;
+ }
+
+ cache[ id ][ internalKey ] = internalCache;
+
+ // Otherwise, we need to eliminate the expando on the node to avoid
+ // false lookups in the cache for entries that no longer exist
+ } else if ( isNode ) {
+ // IE does not allow us to delete expando properties from nodes,
+ // nor does it have a removeAttribute function on Document nodes;
+ // we must handle all of these cases
+ if ( jQuery.support.deleteExpando ) {
+ delete elem[ jQuery.expando ];
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ } else {
+ elem[ jQuery.expando ] = null;
+ }
+ }
+ },
+
+ // For internal use only.
+ _data: function( elem, name, data ) {
+ return jQuery.data( elem, name, data, true );
+ },
+
+ // A method for determining if a DOM node can handle the data expando
+ acceptData: function( elem ) {
+ if ( elem.nodeName ) {
+ var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+ if ( match ) {
+ return !(match === true || elem.getAttribute("classid") !== match);
+ }
+ }
+
+ return true;
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ var data = null;
+
+ if ( typeof key === "undefined" ) {
+ if ( this.length ) {
+ data = jQuery.data( this[0] );
+
+ if ( this[0].nodeType === 1 ) {
+ var attr = this[0].attributes, name;
+ for ( var i = 0, l = attr.length; i < l; i++ ) {
+ name = attr[i].name;
+
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = jQuery.camelCase( name.substring(5) );
+
+ dataAttr( this[0], name, data[ name ] );
+ }
+ }
+ }
+ }
+
+ return data;
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ // Try to fetch any internally stored data first
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ data = dataAttr( this[0], key, data );
+ }
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+
+ } else {
+ return this.each(function() {
+ var $this = jQuery( this ),
+ args = [ parts[0], value ];
+
+ $this.triggerHandler( "setData" + parts[1] + "!", args );
+ jQuery.data( this, key, value );
+ $this.triggerHandler( "changeData" + parts[1] + "!", args );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+
+function dataAttr( elem, key, data ) {
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
+
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+ !jQuery.isNaN( data ) ? parseFloat( data ) :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ jQuery.data( elem, key, data );
+
+ } else {
+ data = undefined;
+ }
+ }
+
+ return data;
+}
+
+// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
+// property to be considered empty objects; this property always exists in
+// order to make sure JSON.stringify does not expose internal metadata
+function isEmptyDataObject( obj ) {
+ for ( var name in obj ) {
+ if ( name !== "toJSON" ) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+
+
+function handleQueueMarkDefer( elem, type, src ) {
+ var deferDataKey = type + "defer",
+ queueDataKey = type + "queue",
+ markDataKey = type + "mark",
+ defer = jQuery.data( elem, deferDataKey, undefined, true );
+ if ( defer &&
+ ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) &&
+ ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) {
+ // Give room for hard-coded callbacks to fire first
+ // and eventually mark/queue something else on the element
+ setTimeout( function() {
+ if ( !jQuery.data( elem, queueDataKey, undefined, true ) &&
+ !jQuery.data( elem, markDataKey, undefined, true ) ) {
+ jQuery.removeData( elem, deferDataKey, true );
+ defer.resolve();
+ }
+ }, 0 );
+ }
+}
+
+jQuery.extend({
+
+ _mark: function( elem, type ) {
+ if ( elem ) {
+ type = (type || "fx") + "mark";
+ jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true );
+ }
+ },
+
+ _unmark: function( force, elem, type ) {
+ if ( force !== true ) {
+ type = elem;
+ elem = force;
+ force = false;
+ }
+ if ( elem ) {
+ type = type || "fx";
+ var key = type + "mark",
+ count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 );
+ if ( count ) {
+ jQuery.data( elem, key, count, true );
+ } else {
+ jQuery.removeData( elem, key, true );
+ handleQueueMarkDefer( elem, type, "mark" );
+ }
+ }
+ },
+
+ queue: function( elem, type, data ) {
+ if ( elem ) {
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type, undefined, true );
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data), true );
+ } else {
+ q.push( data );
+ }
+ }
+ return q || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift(),
+ defer;
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+
+ if ( !queue.length ) {
+ jQuery.removeData( elem, type + "queue", true );
+ handleQueueMarkDefer( elem, type, "queue" );
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function() {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, object ) {
+ if ( typeof type !== "string" ) {
+ object = type;
+ type = undefined;
+ }
+ type = type || "fx";
+ var defer = jQuery.Deferred(),
+ elements = this,
+ i = elements.length,
+ count = 1,
+ deferDataKey = type + "defer",
+ queueDataKey = type + "queue",
+ markDataKey = type + "mark",
+ tmp;
+ function resolve() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ }
+ while( i-- ) {
+ if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
+ ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
+ jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
+ jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
+ count++;
+ tmp.done( resolve );
+ }
+ }
+ resolve();
+ return defer.promise();
+ }
+});
+
+
+
+
+var rclass = /[\n\t\r]/g,
+ rspace = /\s+/,
+ rreturn = /\r/g,
+ rtype = /^(?:button|input)$/i,
+ rfocusable = /^(?:button|input|object|select|textarea)$/i,
+ rclickable = /^a(?:rea)?$/i,
+ rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
+ rinvalidChar = /\:/,
+ formHook, boolHook;
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name ) {
+ return this.each(function() {
+ jQuery.removeAttr( this, name );
+ });
+ },
+
+ prop: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.prop );
+ },
+
+ removeProp: function( name ) {
+ name = jQuery.propFix[ name ] || name;
+ return this.each(function() {
+ // try/catch handles cases where IE balks (such as removing a property on window)
+ try {
+ this[ name ] = undefined;
+ delete this[ name ];
+ } catch( e ) {}
+ });
+ },
+
+ addClass: function( value ) {
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.addClass( value.call(this, i, self.attr("class") || "") );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ var classNames = (value || "").split( rspace );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className ) {
+ elem.className = value;
+
+ } else {
+ var className = " " + elem.className + " ",
+ setClass = elem.className;
+
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+ setClass += " " + classNames[c];
+ }
+ }
+ elem.className = jQuery.trim( setClass );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.removeClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ var classNames = (value || "").split( rspace );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ var className = (" " + elem.className + " ").replace(rclass, " ");
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[c] + " ", " ");
+ }
+ elem.className = jQuery.trim( className );
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value,
+ isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className,
+ i = 0,
+ self = jQuery( this ),
+ state = stateVal,
+ classNames = value.split( rspace );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery._data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ var hooks, ret,
+ elem = this[0];
+
+ if ( !arguments.length ) {
+ if ( elem ) {
+ hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
+
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+ return ret;
+ }
+
+ return (elem.value || "").replace(rreturn, "");
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction( value );
+
+ return this.each(function( i ) {
+ var self = jQuery(this), val;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call( this, i, self.val() );
+ } else {
+ val = value;
+ }
+
+ // Treat null/undefined as ""; convert numbers to string
+ if ( val == null ) {
+ val = "";
+ } else if ( typeof val === "number" ) {
+ val += "";
+ } else if ( jQuery.isArray( val ) ) {
+ val = jQuery.map(val, function ( value ) {
+ return value == null ? "" : value + "";
+ });
+ }
+
+ hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
+
+ // If set returns undefined, fall back to normal setting
+ if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ valHooks: {
+ option: {
+ get: function( elem ) {
+ // attributes.value is undefined in Blackberry 4.7 but
+ // uses .value. See #6932
+ var val = elem.attributes.value;
+ return !val || val.specified ? elem.value : elem.text;
+ }
+ },
+ select: {
+ get: function( elem ) {
+ var value,
+ index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ // Don't return options that are disabled or in a disabled optgroup
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+ // Get the specific value for the option
+ value = jQuery( option ).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
+ if ( one && !values.length && options.length ) {
+ return jQuery( options[ index ] ).val();
+ }
+
+ return values;
+ },
+
+ set: function( elem, value ) {
+ var values = jQuery.makeArray( value );
+
+ jQuery(elem).find("option").each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ elem.selectedIndex = -1;
+ }
+ return values;
+ }
+ }
+ },
+
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attrFix: {
+ // Always normalize to ensure hook usage
+ tabindex: "tabIndex"
+ },
+
+ attr: function( elem, name, value, pass ) {
+ var nType = elem.nodeType;
+
+ // don't get/set attributes on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery( elem )[ name ]( value );
+ }
+
+ // Fallback to prop when attributes are not supported
+ if ( !("getAttribute" in elem) ) {
+ return jQuery.prop( elem, name, value );
+ }
+
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ // Normalize the name if needed
+ name = notxml && jQuery.attrFix[ name ] || name;
+
+ hooks = jQuery.attrHooks[ name ];
+
+ if ( !hooks ) {
+ // Use boolHook for boolean attributes
+ if ( rboolean.test( name ) &&
+ (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
+
+ hooks = boolHook;
+
+ // Use formHook for forms and if the name contains certain characters
+ } else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
+ hooks = formHook;
+ }
+ }
+
+ if ( value !== undefined ) {
+
+ if ( value === null ) {
+ jQuery.removeAttr( elem, name );
+ return undefined;
+
+ } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ elem.setAttribute( name, "" + value );
+ return value;
+ }
+
+ } else if ( hooks && "get" in hooks && notxml ) {
+ return hooks.get( elem, name );
+
+ } else {
+
+ ret = elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return ret === null ?
+ undefined :
+ ret;
+ }
+ },
+
+ removeAttr: function( elem, name ) {
+ var propName;
+ if ( elem.nodeType === 1 ) {
+ name = jQuery.attrFix[ name ] || name;
+
+ if ( jQuery.support.getSetAttribute ) {
+ // Use removeAttribute in browsers that support it
+ elem.removeAttribute( name );
+ } else {
+ jQuery.attr( elem, name, "" );
+ elem.removeAttributeNode( elem.getAttributeNode( name ) );
+ }
+
+ // Set corresponding property to false for boolean attributes
+ if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
+ elem[ propName ] = false;
+ }
+ }
+ },
+
+ attrHooks: {
+ type: {
+ set: function( elem, value ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
+ // Setting the type on a radio button after the value resets the value in IE6-9
+ // Reset value to it's default in case type is set after value
+ // This is for element creation
+ var val = elem.value;
+ elem.setAttribute( "type", value );
+ if ( val ) {
+ elem.value = val;
+ }
+ return value;
+ }
+ }
+ },
+ tabIndex: {
+ get: function( elem ) {
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ var attributeNode = elem.getAttributeNode("tabIndex");
+
+ return attributeNode && attributeNode.specified ?
+ parseInt( attributeNode.value, 10 ) :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+ }
+ },
+
+ propFix: {
+ tabindex: "tabIndex",
+ readonly: "readOnly",
+ "for": "htmlFor",
+ "class": "className",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ cellpadding: "cellPadding",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ usemap: "useMap",
+ frameborder: "frameBorder",
+ contenteditable: "contentEditable"
+ },
+
+ prop: function( elem, name, value ) {
+ var nType = elem.nodeType;
+
+ // don't get/set properties on text, comment and attribute nodes
+ if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+ return undefined;
+ }
+
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.propFix[ name ] || name;
+
+ hooks = jQuery.propHooks[ name ];
+
+ if ( value !== undefined ) {
+ if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ return (elem[ name ] = value);
+ }
+
+ } else {
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
+ return ret;
+
+ } else {
+ return elem[ name ];
+ }
+ }
+ },
+
+ propHooks: {}
+});
+
+// Hook for boolean attributes
+boolHook = {
+ get: function( elem, name ) {
+ // Align boolean attributes with corresponding properties
+ return elem[ jQuery.propFix[ name ] || name ] ?
+ name.toLowerCase() :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ var propName;
+ if ( value === false ) {
+ // Remove boolean attributes when set to false
+ jQuery.removeAttr( elem, name );
+ } else {
+ // value is true since we know at this point it's type boolean and not false
+ // Set boolean attributes to the same name and set the DOM property
+ propName = jQuery.propFix[ name ] || name;
+ if ( propName in elem ) {
+ // Only set the IDL specifically if it already exists on the element
+ elem[ propName ] = value;
+ }
+
+ elem.setAttribute( name, name.toLowerCase() );
+ }
+ return name;
+ }
+};
+
+// Use the value property for back compat
+// Use the formHook for button elements in IE6/7 (#1954)
+jQuery.attrHooks.value = {
+ get: function( elem, name ) {
+ if ( formHook && jQuery.nodeName( elem, "button" ) ) {
+ return formHook.get( elem, name );
+ }
+ return elem.value;
+ },
+ set: function( elem, value, name ) {
+ if ( formHook && jQuery.nodeName( elem, "button" ) ) {
+ return formHook.set( elem, value, name );
+ }
+ // Does not return so that setAttribute is also used
+ elem.value = value;
+ }
+};
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !jQuery.support.getSetAttribute ) {
+
+ // propFix is more comprehensive and contains all fixes
+ jQuery.attrFix = jQuery.propFix;
+
+ // Use this for any attribute on a form in IE6/7
+ formHook = jQuery.attrHooks.name = jQuery.valHooks.button = {
+ get: function( elem, name ) {
+ var ret;
+ ret = elem.getAttributeNode( name );
+ // Return undefined if nodeValue is empty string
+ return ret && ret.nodeValue !== "" ?
+ ret.nodeValue :
+ undefined;
+ },
+ set: function( elem, value, name ) {
+ // Check form objects in IE (multiple bugs related)
+ // Only use nodeValue if the attribute node exists on the form
+ var ret = elem.getAttributeNode( name );
+ if ( ret ) {
+ ret.nodeValue = value;
+ return value;
+ }
+ }
+ };
+
+ // Set width and height to auto instead of 0 on empty string( Bug #8150 )
+ // This is for removals
+ jQuery.each([ "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ set: function( elem, value ) {
+ if ( value === "" ) {
+ elem.setAttribute( name, "auto" );
+ return value;
+ }
+ }
+ });
+ });
+}
+
+
+// Some attributes require a special call on IE
+if ( !jQuery.support.hrefNormalized ) {
+ jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
+ jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
+ get: function( elem ) {
+ var ret = elem.getAttribute( name, 2 );
+ return ret === null ? undefined : ret;
+ }
+ });
+ });
+}
+
+if ( !jQuery.support.style ) {
+ jQuery.attrHooks.style = {
+ get: function( elem ) {
+ // Return undefined in the case of empty string
+ // Normalize to lowercase since IE uppercases css property names
+ return elem.style.cssText.toLowerCase() || undefined;
+ },
+ set: function( elem, value ) {
+ return (elem.style.cssText = "" + value);
+ }
+ };
+}
+
+// Safari mis-reports the default selected property of an option
+// Accessing the parent's selectedIndex property fixes it
+if ( !jQuery.support.optSelected ) {
+ jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
+ get: function( elem ) {
+ var parent = elem.parentNode;
+
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+ });
+}
+
+// Radios and checkboxes getter/setter
+if ( !jQuery.support.checkOn ) {
+ jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = {
+ get: function( elem ) {
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+ };
+ });
+}
+jQuery.each([ "radio", "checkbox" ], function() {
+ jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
+ set: function( elem, value ) {
+ if ( jQuery.isArray( value ) ) {
+ return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
+ }
+ }
+ });
+});
+
+
+
+
+var hasOwn = Object.prototype.hasOwnProperty,
+ rnamespaces = /\.(.*)$/,
+ rformElems = /^(?:textarea|input|select)$/i,
+ rperiod = /\./g,
+ rspaces = / /g,
+ rescape = /[^\w\s.|`]/g,
+ fcleanup = function( nm ) {
+ return nm.replace(rescape, "\\$&");
+ };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ if ( handler === false ) {
+ handler = returnFalse;
+ } else if ( !handler ) {
+ // Fixes bug #7229. Fix recommended by jdalton
+ return;
+ }
+
+ var handleObjIn, handleObj;
+
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure
+ var elemData = jQuery._data( elem );
+
+ // If no elemData is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !elemData ) {
+ return;
+ }
+
+ var events = elemData.events,
+ eventHandle = elemData.handle;
+
+ if ( !events ) {
+ elemData.events = events = {};
+ }
+
+ if ( !eventHandle ) {
+ elemData.handle = eventHandle = function( e ) {
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native events in IE.
+ eventHandle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ var type, i = 0, namespaces;
+
+ while ( (type = types[ i++ ]) ) {
+ handleObj = handleObjIn ?
+ jQuery.extend({}, handleObjIn) :
+ { handler: handler, data: data };
+
+ // Namespaced event handlers
+ if ( type.indexOf(".") > -1 ) {
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+ } else {
+ namespaces = [];
+ handleObj.namespace = "";
+ }
+
+ handleObj.type = type;
+ if ( !handleObj.guid ) {
+ handleObj.guid = handler.guid;
+ }
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = jQuery.event.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = [];
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers.push( handleObj );
+
+ // Keep track of which events have been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, pos ) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ if ( handler === false ) {
+ handler = returnFalse;
+ }
+
+ var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+ elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
+ events = elemData && elemData.events;
+
+ if ( !elemData || !events ) {
+ return;
+ }
+
+ // types is actually an event object here
+ if ( types && types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Unbind all events for the element
+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+ types = types || "";
+
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types );
+ }
+
+ return;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ while ( (type = types[ i++ ]) ) {
+ origType = type;
+ handleObj = null;
+ all = type.indexOf(".") < 0;
+ namespaces = [];
+
+ if ( !all ) {
+ // Namespaced event handlers
+ namespaces = type.split(".");
+ type = namespaces.shift();
+
+ namespace = new RegExp("(^|\\.)" +
+ jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ eventType = events[ type ];
+
+ if ( !eventType ) {
+ continue;
+ }
+
+ if ( !handler ) {
+ for ( j = 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ jQuery.event.remove( elem, origType, handleObj.handler, j );
+ eventType.splice( j--, 1 );
+ }
+ }
+
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+
+ for ( j = pos || 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( handler.guid === handleObj.guid ) {
+ // remove the given handler for the given type
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ if ( pos == null ) {
+ eventType.splice( j--, 1 );
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+
+ if ( pos != null ) {
+ break;
+ }
+ }
+ }
+
+ // remove generic event handler if no more handlers exist
+ if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ ret = null;
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ var handle = elemData.handle;
+ if ( handle ) {
+ handle.elem = null;
+ }
+
+ delete elemData.events;
+ delete elemData.handle;
+
+ if ( jQuery.isEmptyObject( elemData ) ) {
+ jQuery.removeData( elem, undefined, true );
+ }
+ }
+ },
+
+ // Events that are safe to short-circuit if no handlers are attached.
+ // Native DOM events should not be added, they may have inline handlers.
+ customEvent: {
+ "getData": true,
+ "setData": true,
+ "changeData": true
+ },
+
+ trigger: function( event, data, elem, onlyHandlers ) {
+ // Event object or event type
+ var type = event.type || event,
+ namespaces = [],
+ exclusive;
+
+ if ( type.indexOf("!") >= 0 ) {
+ // Exclusive events trigger only for the exact event (no namespaces)
+ type = type.slice(0, -1);
+ exclusive = true;
+ }
+
+ if ( type.indexOf(".") >= 0 ) {
+ // Namespaced trigger; create a regexp to match event type in handle()
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ namespaces.sort();
+ }
+
+ if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
+ // No jQuery handlers for this event type, and it can't have inline handlers
+ return;
+ }
+
+ // Caller can pass in an Event, Object, or just an event type string
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[ jQuery.expando ] ? event :
+ // Object literal
+ new jQuery.Event( type, event ) :
+ // Just the event type (string)
+ new jQuery.Event( type );
+
+ event.type = type;
+ event.exclusive = exclusive;
+ event.namespace = namespaces.join(".");
+ event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
+
+ // triggerHandler() and global events don't bubble or run the default action
+ if ( onlyHandlers || !elem ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // TODO: Stop taunting the data cache; remove global events and always attach to document
+ jQuery.each( jQuery.cache, function() {
+ // internalKey variable is just used to make it easier to find
+ // and potentially change this stuff later; currently it just
+ // points to jQuery.expando
+ var internalKey = jQuery.expando,
+ internalCache = this[ internalKey ];
+ if ( internalCache && internalCache.events && internalCache.events[ type ] ) {
+ jQuery.event.trigger( event, data, internalCache.handle.elem );
+ }
+ });
+ return;
+ }
+
+ // Don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // Clean up the event in case it is being reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone any incoming data and prepend the event, creating the handler arg list
+ data = data ? jQuery.makeArray( data ) : [];
+ data.unshift( event );
+
+ var cur = elem,
+ // IE doesn't like method names with a colon (#3533, #8272)
+ ontype = type.indexOf(":") < 0 ? "on" + type : "";
+
+ // Fire event on the current element, then bubble up the DOM tree
+ do {
+ var handle = jQuery._data( cur, "handle" );
+
+ event.currentTarget = cur;
+ if ( handle ) {
+ handle.apply( cur, data );
+ }
+
+ // Trigger an inline bound script
+ if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
+ event.result = false;
+ event.preventDefault();
+ }
+
+ // Bubble up to document, then to window
+ cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
+ } while ( cur && !event.isPropagationStopped() );
+
+ // If nobody prevented the default action, do it now
+ if ( !event.isDefaultPrevented() ) {
+ var old,
+ special = jQuery.event.special[ type ] || {};
+
+ if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
+ !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
+
+ // Call a native DOM method on the target with the same name name as the event.
+ // Can't use an .isFunction)() check here because IE6/7 fails that test.
+ // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
+ try {
+ if ( ontype && elem[ type ] ) {
+ // Don't re-trigger an onFOO event when we call its FOO() method
+ old = elem[ ontype ];
+
+ if ( old ) {
+ elem[ ontype ] = null;
+ }
+
+ jQuery.event.triggered = type;
+ elem[ type ]();
+ }
+ } catch ( ieError ) {}
+
+ if ( old ) {
+ elem[ ontype ] = old;
+ }
+
+ jQuery.event.triggered = undefined;
+ }
+ }
+
+ return event.result;
+ },
+
+ handle: function( event ) {
+ event = jQuery.event.fix( event || window.event );
+ // Snapshot the handlers list since a called handler may add/remove events.
+ var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
+ run_all = !event.exclusive && !event.namespace,
+ args = Array.prototype.slice.call( arguments, 0 );
+
+ // Use the fix-ed Event rather than the (read-only) native event
+ args[0] = event;
+ event.currentTarget = this;
+
+ for ( var j = 0, l = handlers.length; j < l; j++ ) {
+ var handleObj = handlers[ j ];
+
+ // Triggered event must 1) be non-exclusive and have no namespace, or
+ // 2) have namespace(s) a subset or equal to those in the bound event.
+ if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handleObj.handler;
+ event.data = handleObj.data;
+ event.handleObj = handleObj;
+
+ var ret = handleObj.handler.apply( this, args );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+ return event.result;
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function( event ) {
+ if ( event[ jQuery.expando ] ) {
+ return event;
+ }
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ) {
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target ) {
+ // Fixes #1925 where srcElement might not be defined either
+ event.target = event.srcElement || document;
+ }
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement ) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var eventDocument = event.target.ownerDocument || document,
+ doc = eventDocument.documentElement,
+ body = eventDocument.body;
+
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+ event.which = event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ // Deprecated, use jQuery.guid instead
+ guid: 1E8,
+
+ // Deprecated, use jQuery.proxy instead
+ proxy: jQuery.proxy,
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady,
+ teardown: jQuery.noop
+ },
+
+ live: {
+ add: function( handleObj ) {
+ jQuery.event.add( this,
+ liveConvert( handleObj.origType, handleObj.selector ),
+ jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
+ },
+
+ remove: function( handleObj ) {
+ jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
+ }
+ },
+
+ beforeunload: {
+ setup: function( data, namespaces, eventHandle ) {
+ // We only want to do this special case on windows
+ if ( jQuery.isWindow( this ) ) {
+ this.onbeforeunload = eventHandle;
+ }
+ },
+
+ teardown: function( namespaces, eventHandle ) {
+ if ( this.onbeforeunload === eventHandle ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ }
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle, false );
+ }
+ } :
+ function( elem, type, handle ) {
+ if ( elem.detachEvent ) {
+ elem.detachEvent( "on" + type, handle );
+ }
+ };
+
+jQuery.Event = function( src, props ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !this.preventDefault ) {
+ return new jQuery.Event( src, props );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+
+ // Events bubbling up the document may have been marked as prevented
+ // by a handler lower down the tree; reflect the correct value.
+ this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false ||
+ src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse;
+
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // Put explicitly provided properties onto the event object
+ if ( props ) {
+ jQuery.extend( this, props );
+ }
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = jQuery.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+
+ // otherwise set the returnValue property of the original event to false (IE)
+ } else {
+ e.returnValue = false;
+ }
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+
+ // set the correct event type
+ event.type = event.data;
+
+ // Firefox sometimes assigns relatedTarget a XUL element
+ // which we cannot access the parentNode property of
+ try {
+
+ // Chrome does something similar, the parentNode property
+ // can be accessed but is null.
+ if ( parent && parent !== document && !parent.parentNode ) {
+ return;
+ }
+
+ // Traverse up the tree
+ while ( parent && parent !== this ) {
+ parent = parent.parentNode;
+ }
+
+ if ( parent !== this ) {
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+
+ // assuming we've left the element since we most likely mousedover a xul element
+ } catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+ event.type = event.data;
+ jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ setup: function( data ) {
+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+ },
+ teardown: function( data ) {
+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+ }
+ };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function( data, namespaces ) {
+ if ( !jQuery.nodeName( this, "form" ) ) {
+ jQuery.event.add(this, "click.specialSubmit", function( e ) {
+ var elem = e.target,
+ type = elem.type;
+
+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+ trigger( "submit", this, arguments );
+ }
+ });
+
+ jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+ var elem = e.target,
+ type = elem.type;
+
+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+ trigger( "submit", this, arguments );
+ }
+ });
+
+ } else {
+ return false;
+ }
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialSubmit" );
+ }
+ };
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+ var changeFilters,
+
+ getVal = function( elem ) {
+ var type = elem.type, val = elem.value;
+
+ if ( type === "radio" || type === "checkbox" ) {
+ val = elem.checked;
+
+ } else if ( type === "select-multiple" ) {
+ val = elem.selectedIndex > -1 ?
+ jQuery.map( elem.options, function( elem ) {
+ return elem.selected;
+ }).join("-") :
+ "";
+
+ } else if ( jQuery.nodeName( elem, "select" ) ) {
+ val = elem.selectedIndex;
+ }
+
+ return val;
+ },
+
+ testChange = function testChange( e ) {
+ var elem = e.target, data, val;
+
+ if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
+ return;
+ }
+
+ data = jQuery._data( elem, "_change_data" );
+ val = getVal(elem);
+
+ // the current data will be also retrieved by beforeactivate
+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
+ jQuery._data( elem, "_change_data", val );
+ }
+
+ if ( data === undefined || val === data ) {
+ return;
+ }
+
+ if ( data != null || val ) {
+ e.type = "change";
+ e.liveFired = undefined;
+ jQuery.event.trigger( e, arguments[1], elem );
+ }
+ };
+
+ jQuery.event.special.change = {
+ filters: {
+ focusout: testChange,
+
+ beforedeactivate: testChange,
+
+ click: function( e ) {
+ var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
+
+ if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) {
+ testChange.call( this, e );
+ }
+ },
+
+ // Change has to be called before submit
+ // Keydown will be called before keypress, which is used in submit-event delegation
+ keydown: function( e ) {
+ var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : "";
+
+ if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) ||
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+ type === "select-multiple" ) {
+ testChange.call( this, e );
+ }
+ },
+
+ // Beforeactivate happens also before the previous element is blurred
+ // with this event you can't trigger a change event, but you can store
+ // information
+ beforeactivate: function( e ) {
+ var elem = e.target;
+ jQuery._data( elem, "_change_data", getVal(elem) );
+ }
+ },
+
+ setup: function( data, namespaces ) {
+ if ( this.type === "file" ) {
+ return false;
+ }
+
+ for ( var type in changeFilters ) {
+ jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+ }
+
+ return rformElems.test( this.nodeName );
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialChange" );
+
+ return rformElems.test( this.nodeName );
+ }
+ };
+
+ changeFilters = jQuery.event.special.change.filters;
+
+ // Handle when the input is .focus()'d
+ changeFilters.focus = changeFilters.beforeactivate;
+}
+
+function trigger( type, elem, args ) {
+ // Piggyback on a donor event to simulate a different one.
+ // Fake originalEvent to avoid donor's stopPropagation, but if the
+ // simulated event prevents default then we do the same on the donor.
+ // Don't pass args or remember liveFired; they apply to the donor event.
+ var event = jQuery.extend( {}, args[ 0 ] );
+ event.type = type;
+ event.originalEvent = {};
+ event.liveFired = undefined;
+ jQuery.event.handle.call( elem, event );
+ if ( event.isDefaultPrevented() ) {
+ args[ 0 ].preventDefault();
+ }
+}
+
+// Create "bubbling" focus and blur events
+if ( !jQuery.support.focusinBubbles ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+ // Attach a single capturing handler while someone wants focusin/focusout
+ var attaches = 0;
+
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ if ( attaches++ === 0 ) {
+ document.addEventListener( orig, handler, true );
+ }
+ },
+ teardown: function() {
+ if ( --attaches === 0 ) {
+ document.removeEventListener( orig, handler, true );
+ }
+ }
+ };
+
+ function handler( donor ) {
+ // Donor event is always a native one; fix it and switch its type.
+ // Let focusin/out handler cancel the donor focus/blur event.
+ var e = jQuery.event.fix( donor );
+ e.type = fix;
+ e.originalEvent = {};
+ jQuery.event.trigger( e, null, e.target );
+ if ( e.isDefaultPrevented() ) {
+ donor.preventDefault();
+ }
+ }
+ });
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+ jQuery.fn[ name ] = function( type, data, fn ) {
+ var handler;
+
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ name ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( arguments.length === 2 || data === false ) {
+ fn = data;
+ data = undefined;
+ }
+
+ if ( name === "one" ) {
+ handler = function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ };
+ handler.guid = fn.guid || jQuery.guid++;
+ } else {
+ handler = fn;
+ }
+
+ if ( type === "unload" && name !== "one" ) {
+ this.one( type, data, fn );
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.add( this[i], type, handler, data );
+ }
+ }
+
+ return this;
+ };
+});
+
+jQuery.fn.extend({
+ unbind: function( type, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" && !type.preventDefault ) {
+ for ( var key in type ) {
+ this.unbind(key, type[key]);
+ }
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.remove( this[i], type, fn );
+ }
+ }
+
+ return this;
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.live( types, data, fn, selector );
+ },
+
+ undelegate: function( selector, types, fn ) {
+ if ( arguments.length === 0 ) {
+ return this.unbind( "live" );
+
+ } else {
+ return this.die( types, null, fn, selector );
+ }
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if ( this[0] ) {
+ return jQuery.event.trigger( type, data, this[0], true );
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments,
+ guid = fn.guid || jQuery.guid++,
+ i = 0,
+ toggler = function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ };
+
+ // link all the functions, so any of them can unbind this click handler
+ toggler.guid = guid;
+ while ( i < args.length ) {
+ args[ i++ ].guid = guid;
+ }
+
+ return this.click( toggler );
+ },
+
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+var liveMap = {
+ focus: "focusin",
+ blur: "focusout",
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+ jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+ var type, i = 0, match, namespaces, preType,
+ selector = origSelector || this.selector,
+ context = origSelector ? this : jQuery( this.context );
+
+ if ( typeof types === "object" && !types.preventDefault ) {
+ for ( var key in types ) {
+ context[ name ]( key, data, types[key], selector );
+ }
+
+ return this;
+ }
+
+ if ( name === "die" && !types &&
+ origSelector && origSelector.charAt(0) === "." ) {
+
+ context.unbind( origSelector );
+
+ return this;
+ }
+
+ if ( data === false || jQuery.isFunction( data ) ) {
+ fn = data || returnFalse;
+ data = undefined;
+ }
+
+ types = (types || "").split(" ");
+
+ while ( (type = types[ i++ ]) != null ) {
+ match = rnamespaces.exec( type );
+ namespaces = "";
+
+ if ( match ) {
+ namespaces = match[0];
+ type = type.replace( rnamespaces, "" );
+ }
+
+ if ( type === "hover" ) {
+ types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+ continue;
+ }
+
+ preType = type;
+
+ if ( liveMap[ type ] ) {
+ types.push( liveMap[ type ] + namespaces );
+ type = type + namespaces;
+
+ } else {
+ type = (liveMap[ type ] || type) + namespaces;
+ }
+
+ if ( name === "live" ) {
+ // bind live handler
+ for ( var j = 0, l = context.length; j < l; j++ ) {
+ jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
+ { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+ }
+
+ } else {
+ // unbind live handler
+ context.unbind( "live." + liveConvert( type, selector ), fn );
+ }
+ }
+
+ return this;
+ };
+});
+
+function liveHandler( event ) {
+ var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+ elems = [],
+ selectors = [],
+ events = jQuery._data( this, "events" );
+
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
+ if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
+ return;
+ }
+
+ if ( event.namespace ) {
+ namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ event.liveFired = this;
+
+ var live = events.live.slice(0);
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+ selectors.push( handleObj.selector );
+
+ } else {
+ live.splice( j--, 1 );
+ }
+ }
+
+ match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+ for ( i = 0, l = match.length; i < l; i++ ) {
+ close = match[i];
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) && !close.elem.disabled ) {
+ elem = close.elem;
+ related = null;
+
+ // Those two events require additional checking
+ if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+ event.type = handleObj.preType;
+ related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+
+ // Make sure not to accidentally match a child element with the same selector
+ if ( related && jQuery.contains( elem, related ) ) {
+ related = elem;
+ }
+ }
+
+ if ( !related || related !== elem ) {
+ elems.push({ elem: elem, handleObj: handleObj, level: close.level });
+ }
+ }
+ }
+ }
+
+ for ( i = 0, l = elems.length; i < l; i++ ) {
+ match = elems[i];
+
+ if ( maxLevel && match.level > maxLevel ) {
+ break;
+ }
+
+ event.currentTarget = match.elem;
+ event.data = match.handleObj.data;
+ event.handleObj = match.handleObj;
+
+ ret = match.handleObj.origHandler.apply( match.elem, arguments );
+
+ if ( ret === false || event.isPropagationStopped() ) {
+ maxLevel = match.level;
+
+ if ( ret === false ) {
+ stop = false;
+ }
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+
+ return stop;
+}
+
+function liveConvert( type, selector ) {
+ return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( data, fn ) {
+ if ( fn == null ) {
+ fn = data;
+ data = null;
+ }
+
+ return arguments.length > 0 ?
+ this.bind( name, data, fn ) :
+ this.trigger( name );
+ };
+
+ if ( jQuery.attrFn ) {
+ jQuery.attrFn[ name ] = true;
+ }
+});
+
+
+
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true,
+ rBackslash = /\\/g,
+ rNonWord = /\W/;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function() {
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+
+ var origContext = context;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var m, set, checkSet, extra, ret, cur, pop, i,
+ prune = true,
+ contextXML = Sizzle.isXML( context ),
+ parts = [],
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ do {
+ chunker.exec( "" );
+ m = chunker.exec( soFar );
+
+ if ( m ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+ } while ( m );
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set );
+ }
+ }
+
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+
+ ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set )[0] :
+ ret.set[0];
+ }
+
+ if ( context ) {
+ ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+
+ set = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set ) :
+ ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray( set );
+
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ cur = parts.pop();
+ pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+
+ } else if ( context && context.nodeType === 1 ) {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+
+ } else {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function( results ) {
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function( expr, set ) {
+ return Sizzle( expr, null, null, set );
+};
+
+Sizzle.matchesSelector = function( node, expr ) {
+ return Sizzle( expr, null, null, [node] ).length > 0;
+};
+
+Sizzle.find = function( expr, context, isXML ) {
+ var set;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var match,
+ type = Expr.order[i];
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice( 1, 1 );
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace( rBackslash, "" );
+ set = Expr.find[ type ]( match, context, isXML );
+
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = typeof context.getElementsByTagName !== "undefined" ?
+ context.getElementsByTagName( "*" ) :
+ [];
+ }
+
+ return { set: set, expr: expr };
+};
+
+Sizzle.filter = function( expr, set, inplace, not ) {
+ var match, anyFound,
+ old = expr,
+ result = [],
+ curLoop = set,
+ isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ var found, item,
+ filter = Expr.filter[ type ],
+ left = match[1];
+
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+
+ } else {
+ curLoop[i] = false;
+ }
+
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+
+ leftMatch: {},
+
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+
+ attrHandle: {
+ href: function( elem ) {
+ return elem.getAttribute( "href" );
+ },
+ type: function( elem ) {
+ return elem.getAttribute( "type" );
+ }
+ },
+
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !rNonWord.test( part ),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+
+ ">": function( checkSet, part ) {
+ var elem,
+ isPartStr = typeof part === "string",
+ i = 0,
+ l = checkSet.length;
+
+ if ( isPartStr && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+
+ } else {
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+
+ "": function(checkSet, part, isXML){
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
+ },
+
+ "~": function( checkSet, part, isXML ) {
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !rNonWord.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
+ }
+ },
+
+ find: {
+ ID: function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ },
+
+ NAME: function( match, context ) {
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [],
+ results = context.getElementsByName( match[1] );
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+
+ TAG: function( match, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( match[1] );
+ }
+ }
+ },
+ preFilter: {
+ CLASS: function( match, curLoop, inplace, result, not, isXML ) {
+ match = " " + match[1].replace( rBackslash, "" ) + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ ID: function( match ) {
+ return match[1].replace( rBackslash, "" );
+ },
+
+ TAG: function( match, curLoop ) {
+ return match[1].replace( rBackslash, "" ).toLowerCase();
+ },
+
+ CHILD: function( match ) {
+ if ( match[1] === "nth" ) {
+ if ( !match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ match[2] = match[2].replace(/^\+|\s*/g, '');
+
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+ else if ( match[2] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+
+ ATTR: function( match, curLoop, inplace, result, not, isXML ) {
+ var name = match[1] = match[1].replace( rBackslash, "" );
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ // Handle if an un-quoted value was used
+ match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+
+ PSEUDO: function( match, curLoop, inplace, result, not ) {
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+
+ return false;
+ }
+
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+
+ POS: function( match ) {
+ match.unshift( true );
+
+ return match;
+ }
+ },
+
+ filters: {
+ enabled: function( elem ) {
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+
+ disabled: function( elem ) {
+ return elem.disabled === true;
+ },
+
+ checked: function( elem ) {
+ return elem.checked === true;
+ },
+
+ selected: function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ parent: function( elem ) {
+ return !!elem.firstChild;
+ },
+
+ empty: function( elem ) {
+ return !elem.firstChild;
+ },
+
+ has: function( elem, i, match ) {
+ return !!Sizzle( match[3], elem ).length;
+ },
+
+ header: function( elem ) {
+ return (/h\d/i).test( elem.nodeName );
+ },
+
+ text: function( elem ) {
+ var attr = elem.getAttribute( "type" ), type = elem.type;
+ // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
+ // use getAttribute instead to test this case
+ return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
+ },
+
+ radio: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
+ },
+
+ checkbox: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
+ },
+
+ file: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
+ },
+
+ password: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
+ },
+
+ submit: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && "submit" === elem.type;
+ },
+
+ image: function( elem ) {
+ return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
+ },
+
+ reset: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && "reset" === elem.type;
+ },
+
+ button: function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && "button" === elem.type || name === "button";
+ },
+
+ input: function( elem ) {
+ return (/input|select|textarea|button/i).test( elem.nodeName );
+ },
+
+ focus: function( elem ) {
+ return elem === elem.ownerDocument.activeElement;
+ }
+ },
+ setFilters: {
+ first: function( elem, i ) {
+ return i === 0;
+ },
+
+ last: function( elem, i, match, array ) {
+ return i === array.length - 1;
+ },
+
+ even: function( elem, i ) {
+ return i % 2 === 0;
+ },
+
+ odd: function( elem, i ) {
+ return i % 2 === 1;
+ },
+
+ lt: function( elem, i, match ) {
+ return i < match[3] - 0;
+ },
+
+ gt: function( elem, i, match ) {
+ return i > match[3] - 0;
+ },
+
+ nth: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ },
+
+ eq: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function( elem, match, i, array ) {
+ var name = match[1],
+ filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
+
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var j = 0, l = not.length; j < l; j++ ) {
+ if ( not[j] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ } else {
+ Sizzle.error( name );
+ }
+ },
+
+ CHILD: function( elem, match ) {
+ var type = match[1],
+ node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ case "nth":
+ var first = match[2],
+ last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+
+ if ( first === 0 ) {
+ return diff === 0;
+
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+
+ ID: function( elem, match ) {
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+
+ TAG: function( elem, match ) {
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+ },
+
+ CLASS: function( elem, match ) {
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+
+ ATTR: function( elem, match ) {
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+
+ POS: function( elem, match, i, array ) {
+ var name = match[2],
+ filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS,
+ fescape = function(all, num){
+ return "\\" + (num - 0 + 1);
+ };
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
+}
+
+var makeArray = function( array, results ) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch( e ) {
+ makeArray = function( array, results ) {
+ var i = 0,
+ ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+
+ } else {
+ for ( ; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder, siblingCheck;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+ };
+
+} else {
+ sortOrder = function( a, b ) {
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // Fallback to using sourceIndex (in IE) if it's available on both nodes
+ } else if ( a.sourceIndex && b.sourceIndex ) {
+ return a.sourceIndex - b.sourceIndex;
+ }
+
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+ siblingCheck = function( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+ };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+Sizzle.getText = function( elems ) {
+ var ret = "", elem;
+
+ for ( var i = 0; elems[i]; i++ ) {
+ elem = elems[i];
+
+ // Get the text from text nodes and CDATA nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+ ret += elem.nodeValue;
+
+ // Traverse everything else, except comment nodes
+ } else if ( elem.nodeType !== 8 ) {
+ ret += Sizzle.getText( elem.childNodes );
+ }
+ }
+
+ return ret;
+};
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date()).getTime(),
+ root = document.documentElement;
+
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( document.getElementById( id ) ) {
+ Expr.find.ID = function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+
+ return m ?
+ m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
+ [m] :
+ undefined :
+ [];
+ }
+ };
+
+ Expr.filter.ID = function( elem, match ) {
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+
+ // release memory in IE
+ root = form = null;
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function( match, context ) {
+ var results = context.getElementsByTagName( match[1] );
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+
+ Expr.attrHandle.href = function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ };
+ }
+
+ // release memory in IE
+ div = null;
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle,
+ div = document.createElement("div"),
+ id = "__sizzle__";
+
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function( query, context, extra, seed ) {
+ context = context || document;
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && !Sizzle.isXML(context) ) {
+ // See if we find a selector to speed up
+ var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
+
+ if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
+ // Speed-up: Sizzle("TAG")
+ if ( match[1] ) {
+ return makeArray( context.getElementsByTagName( query ), extra );
+
+ // Speed-up: Sizzle(".CLASS")
+ } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
+ return makeArray( context.getElementsByClassName( match[2] ), extra );
+ }
+ }
+
+ if ( context.nodeType === 9 ) {
+ // Speed-up: Sizzle("body")
+ // The body element only exists once, optimize finding it
+ if ( query === "body" && context.body ) {
+ return makeArray( [ context.body ], extra );
+
+ // Speed-up: Sizzle("#ID")
+ } else if ( match && match[3] ) {
+ var elem = context.getElementById( match[3] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id === match[3] ) {
+ return makeArray( [ elem ], extra );
+ }
+
+ } else {
+ return makeArray( [], extra );
+ }
+ }
+
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(qsaError) {}
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ var oldContext = context,
+ old = context.getAttribute( "id" ),
+ nid = old || id,
+ hasParent = context.parentNode,
+ relativeHierarchySelector = /^\s*[+~]/.test( query );
+
+ if ( !old ) {
+ context.setAttribute( "id", nid );
+ } else {
+ nid = nid.replace( /'/g, "\\$&" );
+ }
+ if ( relativeHierarchySelector && hasParent ) {
+ context = context.parentNode;
+ }
+
+ try {
+ if ( !relativeHierarchySelector || hasParent ) {
+ return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
+ }
+
+ } catch(pseudoError) {
+ } finally {
+ if ( !old ) {
+ oldContext.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ // release memory in IE
+ div = null;
+ })();
+}
+
+(function(){
+ var html = document.documentElement,
+ matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
+
+ if ( matches ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9 fails this)
+ var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
+ pseudoWorks = false;
+
+ try {
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( document.documentElement, "[test!='']:sizzle" );
+
+ } catch( pseudoError ) {
+ pseudoWorks = true;
+ }
+
+ Sizzle.matchesSelector = function( node, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+ if ( !Sizzle.isXML( node ) ) {
+ try {
+ if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
+ var ret = matches.call( node, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || !disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9, so check for that
+ node.document && node.document.nodeType !== 11 ) {
+ return ret;
+ }
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle(expr, null, null, [node]).length > 0;
+ };
+ }
+})();
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function( match, context, isXML ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ // release memory in IE
+ div = null;
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+if ( document.documentElement.contains ) {
+ Sizzle.contains = function( a, b ) {
+ return a !== b && (a.contains ? a.contains(b) : true);
+ };
+
+} else if ( document.documentElement.compareDocumentPosition ) {
+ Sizzle.contains = function( a, b ) {
+ return !!(a.compareDocumentPosition(b) & 16);
+ };
+
+} else {
+ Sizzle.contains = function() {
+ return false;
+ };
+}
+
+Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function( selector, context ) {
+ var match,
+ tmpSet = [],
+ later = "",
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})();
+
+
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ isSimple = /^.[^:#\[\.,]*$/,
+ slice = Array.prototype.slice,
+ POS = jQuery.expr.match.POS,
+ // methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var self = this,
+ i, l;
+
+ if ( typeof selector !== "string" ) {
+ return jQuery( selector ).filter(function() {
+ for ( i = 0, l = self.length; i < l; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ });
+ }
+
+ var ret = this.pushStack( "", "find", selector ),
+ length, n, r;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( n = length; n < ret.length; n++ ) {
+ for ( r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ return !!selector && ( typeof selector === "string" ?
+ jQuery.filter( selector, this ).length > 0 :
+ this.filter( selector ).length > 0 );
+ },
+
+ closest: function( selectors, context ) {
+ var ret = [], i, l, cur = this[0];
+
+ // Array
+ if ( jQuery.isArray( selectors ) ) {
+ var match, selector,
+ matches = {},
+ level = 1;
+
+ if ( cur && selectors.length ) {
+ for ( i = 0, l = selectors.length; i < l; i++ ) {
+ selector = selectors[i];
+
+ if ( !matches[ selector ] ) {
+ matches[ selector ] = POS.test( selector ) ?
+ jQuery( selector, context || this.context ) :
+ selector;
+ }
+ }
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( selector in matches ) {
+ match = matches[ selector ];
+
+ if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
+ ret.push({ selector: selector, elem: cur, level: level });
+ }
+ }
+
+ cur = cur.parentNode;
+ level++;
+ }
+ }
+
+ return ret;
+ }
+
+ // String
+ var pos = POS.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ cur = this[i];
+
+ while ( cur ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+ ret.push( cur );
+ break;
+
+ } else {
+ cur = cur.parentNode;
+ if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
+ break;
+ }
+ }
+ }
+ }
+
+ ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
+
+ return this.pushStack( ret, "closest", selectors );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ if ( !elem || typeof elem === "string" ) {
+ return jQuery.inArray( this[0],
+ // If it receives a string, the selector is used
+ // If it receives nothing, the siblings are used
+ elem ? jQuery( elem ) : this.parent().children() );
+ }
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context ) :
+ jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until ),
+ // The variable 'args' was introduced in
+ // https://github.com/jquery/jquery/commit/52a0238
+ // to work around a bug in Chrome 10 (Dev) and should be removed when the bug is fixed.
+ // http://code.google.com/p/v8/issues/detail?id=1050
+ args = slice.call(arguments);
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, args.join(",") );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 ?
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+ jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [],
+ cur = elem[ dir ];
+
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+
+ // Can't pass null or undefined to indexOf in Firefox 4
+ // Set to 0 to skip string check
+ qualifier = qualifier || 0;
+
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ var retVal = !!qualifier.call( elem, i, elem );
+ return retVal === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+ });
+}
+
+
+
+
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&#?\w+;/,
+ rnocache = /<(?:script|object|embed|option|style)/i,
+ // checked="checked" or checked
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+ rscriptType = /\/(java|ecma)script/i,
+ rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery( this );
+
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.text( this );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append( this );
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function() {
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery(arguments[0]);
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery(arguments[0]).toArray() );
+ return set;
+ }
+ },
+
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+ if ( !keepData && elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ jQuery.cleanData( [ elem ] );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+ }
+ }
+
+ return this;
+ },
+
+ empty: function() {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( dataAndEvents, deepDataAndEvents ) {
+ dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+ deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+ return this.map( function () {
+ return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+ });
+ },
+
+ html: function( value ) {
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !rnocache.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, "<$1></$2>");
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery( this );
+
+ self.html( value.call(this, i, self.html()) );
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ if ( typeof value !== "string" ) {
+ value = jQuery( value ).detach();
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling,
+ parent = this.parentNode;
+
+ jQuery( this ).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.length ?
+ this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
+ this;
+ }
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ var results, first, fragment, parent,
+ value = args[0],
+ scripts = [];
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ parent = value && value.parentNode;
+
+ // If we're in a fragment, just use that instead of building a new one
+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+ results = { fragment: parent };
+
+ } else {
+ results = jQuery.buildFragment( args, this, scripts );
+ }
+
+ fragment = results.fragment;
+
+ if ( fragment.childNodes.length === 1 ) {
+ first = fragment = fragment.firstChild;
+ } else {
+ first = fragment.firstChild;
+ }
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ // Make sure that we do not leak memory by inadvertently discarding
+ // the original fragment (which might have attached data) instead of
+ // using it; in addition, use the original fragment object for the last
+ // item instead of first because it can end up being emptied incorrectly
+ // in certain situations (Bug #8070).
+ // Fragments from the fragment cache must always be cloned and never used
+ // in place.
+ results.cacheable || (l > 1 && i < lastIndex) ?
+ jQuery.clone( fragment, true, true ) :
+ fragment
+ );
+ }
+ }
+
+ if ( scripts.length ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+ }
+});
+
+function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+}
+
+function cloneCopyEvent( src, dest ) {
+
+ if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
+ return;
+ }
+
+ var internalKey = jQuery.expando,
+ oldData = jQuery.data( src ),
+ curData = jQuery.data( dest, oldData );
+
+ // Switch to use the internal data object, if it exists, for the next
+ // stage of data copying
+ if ( (oldData = oldData[ internalKey ]) ) {
+ var events = oldData.events;
+ curData = curData[ internalKey ] = jQuery.extend({}, oldData);
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( var type in events ) {
+ for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
+ jQuery.event.add( dest, type + ( events[ type ][ i ].namespace ? "." : "" ) + events[ type ][ i ].namespace, events[ type ][ i ], events[ type ][ i ].data );
+ }
+ }
+ }
+ }
+}
+
+function cloneFixAttributes( src, dest ) {
+ var nodeName;
+
+ // We do not need to do anything for non-Elements
+ if ( dest.nodeType !== 1 ) {
+ return;
+ }
+
+ // clearAttributes removes the attributes, which we don't want,
+ // but also removes the attachEvent events, which we *do* want
+ if ( dest.clearAttributes ) {
+ dest.clearAttributes();
+ }
+
+ // mergeAttributes, in contrast, only merges back on the
+ // original attributes, not the events
+ if ( dest.mergeAttributes ) {
+ dest.mergeAttributes( src );
+ }
+
+ nodeName = dest.nodeName.toLowerCase();
+
+ // IE6-8 fail to clone children inside object elements that use
+ // the proprietary classid attribute value (rather than the type
+ // attribute) to identify the type of content to display
+ if ( nodeName === "object" ) {
+ dest.outerHTML = src.outerHTML;
+
+ } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
+ // IE6-8 fails to persist the checked state of a cloned checkbox
+ // or radio button. Worse, IE6-7 fail to give the cloned element
+ // a checked appearance if the defaultChecked value isn't also set
+ if ( src.checked ) {
+ dest.defaultChecked = dest.checked = src.checked;
+ }
+
+ // IE6-7 get confused and end up setting the value of a cloned
+ // checkbox/radio button to an empty string instead of "on"
+ if ( dest.value !== src.value ) {
+ dest.value = src.value;
+ }
+
+ // IE6-8 fails to return the selected option to the default selected
+ // state when cloning options
+ } else if ( nodeName === "option" ) {
+ dest.selected = src.defaultSelected;
+
+ // IE6-8 fails to set the defaultValue to the correct value when
+ // cloning other types of input fields
+ } else if ( nodeName === "input" || nodeName === "textarea" ) {
+ dest.defaultValue = src.defaultValue;
+ }
+
+ // Event data gets referenced instead of copied if the expando
+ // gets copied too
+ dest.removeAttribute( jQuery.expando );
+}
+
+jQuery.buildFragment = function( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults,
+ doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+ // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
+ // Cloning options loses the selected state, so don't cache them
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+ args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+ cacheable = true;
+
+ cacheresults = jQuery.fragments[ args[0] ];
+ if ( cacheresults && cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+
+ if ( !fragment ) {
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [],
+ insert = jQuery( selector ),
+ parent = this.length === 1 && this[0].parentNode;
+
+ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+ insert[ original ]( this[0] );
+ return this;
+
+ } else {
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery( insert[i] )[ original ]( elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, insert.selector );
+ }
+ };
+});
+
+function getAll( elem ) {
+ if ( "getElementsByTagName" in elem ) {
+ return elem.getElementsByTagName( "*" );
+
+ } else if ( "querySelectorAll" in elem ) {
+ return elem.querySelectorAll( "*" );
+
+ } else {
+ return [];
+ }
+}
+
+// Used in clean, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+ if ( elem.type === "checkbox" || elem.type === "radio" ) {
+ elem.defaultChecked = elem.checked;
+ }
+}
+// Finds all inputs and passes them to fixDefaultChecked
+function findInputs( elem ) {
+ if ( jQuery.nodeName( elem, "input" ) ) {
+ fixDefaultChecked( elem );
+ } else if ( elem.getElementsByTagName ) {
+ jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
+ }
+}
+
+jQuery.extend({
+ clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+ var clone = elem.cloneNode(true),
+ srcElements,
+ destElements,
+ i;
+
+ if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
+ (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
+ // IE copies events bound via attachEvent when using cloneNode.
+ // Calling detachEvent on the clone will also remove the events
+ // from the original. In order to get around this, we use some
+ // proprietary methods to clear the events. Thanks to MooTools
+ // guys for this hotness.
+
+ cloneFixAttributes( elem, clone );
+
+ // Using Sizzle here is crazy slow, so we use getElementsByTagName
+ // instead
+ srcElements = getAll( elem );
+ destElements = getAll( clone );
+
+ // Weird iteration because IE will replace the length property
+ // with an element if you are cloning the body and one of the
+ // elements on the page has a name or id of "length"
+ for ( i = 0; srcElements[i]; ++i ) {
+ cloneFixAttributes( srcElements[i], destElements[i] );
+ }
+ }
+
+ // Copy the events from the original to the clone
+ if ( dataAndEvents ) {
+ cloneCopyEvent( elem, clone );
+
+ if ( deepDataAndEvents ) {
+ srcElements = getAll( elem );
+ destElements = getAll( clone );
+
+ for ( i = 0; srcElements[i]; ++i ) {
+ cloneCopyEvent( srcElements[i], destElements[i] );
+ }
+ }
+ }
+
+ // Return the cloned set
+ return clone;
+ },
+
+ clean: function( elems, context, fragment, scripts ) {
+ var checkScriptType;
+
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [], j;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ continue;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" ) {
+ if ( !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+ } else {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = div.childNodes;
+ }
+ }
+
+ // Resets defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ var len;
+ if ( !jQuery.support.appendChecked ) {
+ if ( elem[0] && typeof (len = elem.length) === "number" ) {
+ for ( j = 0; j < len; j++ ) {
+ findInputs( elem[j] );
+ }
+ } else {
+ findInputs( elem );
+ }
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+ }
+
+ if ( fragment ) {
+ checkScriptType = function( elem ) {
+ return !elem.type || rscriptType.test( elem.type );
+ };
+ for ( i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType );
+
+ ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ var data, id, cache = jQuery.cache, internalKey = jQuery.expando, special = jQuery.event.special,
+ deleteExpando = jQuery.support.deleteExpando;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ continue;
+ }
+
+ id = elem[ jQuery.expando ];
+
+ if ( id ) {
+ data = cache[ id ] && cache[ id ][ internalKey ];
+
+ if ( data && data.events ) {
+ for ( var type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ // This is a shortcut to avoid jQuery.event.remove's overhead
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
+ }
+
+ // Null the DOM reference to avoid IE6/7/8 leak (#7054)
+ if ( data.handle ) {
+ data.handle.elem = null;
+ }
+ }
+
+ if ( deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ delete cache[ id ];
+ }
+ }
+ }
+});
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+
+
+
+var ralpha = /alpha\([^)]*\)/i,
+ ropacity = /opacity=([^)]*)/,
+ rdashAlpha = /-([a-z])/ig,
+ // fixed for IE9, see #8346
+ rupper = /([A-Z]|^ms)/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+ rrelNum = /^[+\-]=/,
+ rrelNumFilter = /[^+\-\.\de]+/g,
+
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+ curCSS,
+
+ getComputedStyle,
+ currentStyle,
+
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn.css = function( name, value ) {
+ // Setting 'undefined' is a no-op
+ if ( arguments.length === 2 && value === undefined ) {
+ return this;
+ }
+
+ return jQuery.access( this, name, value, true, function( elem, name, value ) {
+ return value !== undefined ?
+ jQuery.style( elem, name, value ) :
+ jQuery.css( elem, name );
+ });
+};
+
+jQuery.extend({
+ // Add in style property hooks for overriding the default
+ // behavior of getting and setting a style property
+ cssHooks: {
+ opacity: {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // We should always get a number back from opacity
+ var ret = curCSS( elem, "opacity", "opacity" );
+ return ret === "" ? "1" : ret;
+
+ } else {
+ return elem.style.opacity;
+ }
+ }
+ }
+ },
+
+ // Exclude the following css properties to add px
+ cssNumber: {
+ "zIndex": true,
+ "fontWeight": true,
+ "opacity": true,
+ "zoom": true,
+ "lineHeight": true,
+ "widows": true,
+ "orphans": true
+ },
+
+ // Add in properties whose names you wish to fix before
+ // setting or getting the value
+ cssProps: {
+ // normalize float css property
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+ },
+
+ // Get and set the style property on a DOM Node
+ style: function( elem, name, value, extra ) {
+ // Don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+ return;
+ }
+
+ // Make sure that we're working with the right name
+ var ret, type, origName = jQuery.camelCase( name ),
+ style = elem.style, hooks = jQuery.cssHooks[ origName ];
+
+ name = jQuery.cssProps[ origName ] || origName;
+
+ // Check if we're setting a value
+ if ( value !== undefined ) {
+ type = typeof value;
+
+ // Make sure that NaN and null values aren't set. See: #7116
+ if ( type === "number" && isNaN( value ) || value == null ) {
+ return;
+ }
+
+ // convert relative number strings (+= or -=) to relative numbers. #7345
+ if ( type === "string" && rrelNum.test( value ) ) {
+ value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
+ }
+
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
+ if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+ value += "px";
+ }
+
+ // If a hook was provided, use that value, otherwise just set the specified value
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+ // Fixes bug #5509
+ try {
+ style[ name ] = value;
+ } catch(e) {}
+ }
+
+ } else {
+ // If a hook was provided get the non-computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+ return ret;
+ }
+
+ // Otherwise just get the value from the style object
+ return style[ name ];
+ }
+ },
+
+ css: function( elem, name, extra ) {
+ var ret, hooks;
+
+ // Make sure that we're working with the right name
+ name = jQuery.camelCase( name );
+ hooks = jQuery.cssHooks[ name ];
+ name = jQuery.cssProps[ name ] || name;
+
+ // cssFloat needs a special treatment
+ if ( name === "cssFloat" ) {
+ name = "float";
+ }
+
+ // If a hook was provided get the computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
+ return ret;
+
+ // Otherwise, if a way to get the computed value exists, use that
+ } else if ( curCSS ) {
+ return curCSS( elem, name );
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ },
+
+ camelCase: function( string ) {
+ return string.replace( rdashAlpha, fcamelCase );
+ }
+});
+
+// DEPRECATED, Use jQuery.css() instead
+jQuery.curCSS = jQuery.css;
+
+jQuery.each(["height", "width"], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ var val;
+
+ if ( computed ) {
+ if ( elem.offsetWidth !== 0 ) {
+ val = getWH( elem, name, extra );
+
+ } else {
+ jQuery.swap( elem, cssShow, function() {
+ val = getWH( elem, name, extra );
+ });
+ }
+
+ if ( val <= 0 ) {
+ val = curCSS( elem, name, name );
+
+ if ( val === "0px" && currentStyle ) {
+ val = currentStyle( elem, name, name );
+ }
+
+ if ( val != null ) {
+ // Should return "auto" instead of 0, use 0 for
+ // temporary backwards-compat
+ return val === "" || val === "auto" ? "0px" : val;
+ }
+ }
+
+ if ( val < 0 || val == null ) {
+ val = elem.style[ name ];
+
+ // Should return "auto" instead of 0, use 0 for
+ // temporary backwards-compat
+ return val === "" || val === "auto" ? "0px" : val;
+ }
+
+ return typeof val === "string" ? val : val + "px";
+ }
+ },
+
+ set: function( elem, value ) {
+ if ( rnumpx.test( value ) ) {
+ // ignore negative width and height values #1599
+ value = parseFloat(value);
+
+ if ( value >= 0 ) {
+ return value + "px";
+ }
+
+ } else {
+ return value;
+ }
+ }
+ };
+});
+
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
+ ( parseFloat( RegExp.$1 ) / 100 ) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style,
+ currentStyle = elem.currentStyle;
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ var opacity = jQuery.isNaN( value ) ?
+ "" :
+ "alpha(opacity=" + value * 100 + ")",
+ filter = currentStyle && currentStyle.filter || style.filter || "";
+
+ style.filter = ralpha.test( filter ) ?
+ filter.replace( ralpha, opacity ) :
+ filter + " " + opacity;
+ }
+ };
+}
+
+jQuery(function() {
+ // This hook cannot be added until DOM ready because the support test
+ // for it is not run until after DOM ready
+ if ( !jQuery.support.reliableMarginRight ) {
+ jQuery.cssHooks.marginRight = {
+ get: function( elem, computed ) {
+ // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+ // Work around by temporarily setting element display to inline-block
+ var ret;
+ jQuery.swap( elem, { "display": "inline-block" }, function() {
+ if ( computed ) {
+ ret = curCSS( elem, "margin-right", "marginRight" );
+ } else {
+ ret = elem.style.marginRight;
+ }
+ });
+ return ret;
+ }
+ };
+ }
+});
+
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ getComputedStyle = function( elem, name ) {
+ var ret, defaultView, computedStyle;
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ if ( !(defaultView = elem.ownerDocument.defaultView) ) {
+ return undefined;
+ }
+
+ if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+ ret = computedStyle.getPropertyValue( name );
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+ }
+
+ return ret;
+ };
+}
+
+if ( document.documentElement.currentStyle ) {
+ currentStyle = function( elem, name ) {
+ var left,
+ ret = elem.currentStyle && elem.currentStyle[ name ],
+ rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
+ style = elem.style;
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+ // Remember the original values
+ left = style.left;
+
+ // Put in the new values to get a computed value out
+ if ( rsLeft ) {
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ }
+ style.left = name === "fontSize" ? "1em" : (ret || 0);
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ if ( rsLeft ) {
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+
+ return ret === "" ? "auto" : ret;
+ };
+}
+
+curCSS = getComputedStyle || currentStyle;
+
+function getWH( elem, name, extra ) {
+ var which = name === "width" ? cssWidth : cssHeight,
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" ) {
+ return val;
+ }
+
+ jQuery.each( which, function() {
+ if ( !extra ) {
+ val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
+ }
+
+ if ( extra === "margin" ) {
+ val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
+
+ } else {
+ val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
+ }
+ });
+
+ return val;
+}
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth,
+ height = elem.offsetHeight;
+
+ return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+
+
+
+
+var r20 = /%20/g,
+ rbracket = /\[\]$/,
+ rCRLF = /\r?\n/g,
+ rhash = /#.*$/,
+ rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
+ rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+ // #7653, #8125, #8152: local protocol detection
+ rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|widget):$/,
+ rnoContent = /^(?:GET|HEAD)$/,
+ rprotocol = /^\/\//,
+ rquery = /\?/,
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+ rselectTextarea = /^(?:select|textarea)/i,
+ rspacesAjax = /\s+/,
+ rts = /([?&])_=[^&]*/,
+ rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load,
+
+ /* Prefilters
+ * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+ * 2) These are called:
+ * - BEFORE asking for a transport
+ * - AFTER param serialization (s.data is a string if s.processData is true)
+ * 3) key is the dataType
+ * 4) the catchall symbol "*" can be used
+ * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+ */
+ prefilters = {},
+
+ /* Transports bindings
+ * 1) key is the dataType
+ * 2) the catchall symbol "*" can be used
+ * 3) selection will start with transport dataType and THEN go to "*" if needed
+ */
+ transports = {},
+
+ // Document location
+ ajaxLocation,
+
+ // Document location segments
+ ajaxLocParts;
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+ ajaxLocation = location.href;
+} catch( e ) {
+ // Use the href attribute of an A element
+ // since IE will modify it given document.location
+ ajaxLocation = document.createElement( "a" );
+ ajaxLocation.href = "";
+ ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+ // dataTypeExpression is optional and defaults to "*"
+ return function( dataTypeExpression, func ) {
+
+ if ( typeof dataTypeExpression !== "string" ) {
+ func = dataTypeExpression;
+ dataTypeExpression = "*";
+ }
+
+ if ( jQuery.isFunction( func ) ) {
+ var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
+ i = 0,
+ length = dataTypes.length,
+ dataType,
+ list,
+ placeBefore;
+
+ // For each dataType in the dataTypeExpression
+ for(; i < length; i++ ) {
+ dataType = dataTypes[ i ];
+ // We control if we're asked to add before
+ // any existing element
+ placeBefore = /^\+/.test( dataType );
+ if ( placeBefore ) {
+ dataType = dataType.substr( 1 ) || "*";
+ }
+ list = structure[ dataType ] = structure[ dataType ] || [];
+ // then we add to the structure accordingly
+ list[ placeBefore ? "unshift" : "push" ]( func );
+ }
+ }
+ };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
+ dataType /* internal */, inspected /* internal */ ) {
+
+ dataType = dataType || options.dataTypes[ 0 ];
+ inspected = inspected || {};
+
+ inspected[ dataType ] = true;
+
+ var list = structure[ dataType ],
+ i = 0,
+ length = list ? list.length : 0,
+ executeOnly = ( structure === prefilters ),
+ selection;
+
+ for(; i < length && ( executeOnly || !selection ); i++ ) {
+ selection = list[ i ]( options, originalOptions, jqXHR );
+ // If we got redirected to another dataType
+ // we try there if executing only and not done already
+ if ( typeof selection === "string" ) {
+ if ( !executeOnly || inspected[ selection ] ) {
+ selection = undefined;
+ } else {
+ options.dataTypes.unshift( selection );
+ selection = inspectPrefiltersOrTransports(
+ structure, options, originalOptions, jqXHR, selection, inspected );
+ }
+ }
+ }
+ // If we're only executing or nothing was selected
+ // we try the catchall dataType if not done already
+ if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
+ selection = inspectPrefiltersOrTransports(
+ structure, options, originalOptions, jqXHR, "*", inspected );
+ }
+ // unnecessary when only executing (prefilters)
+ // but it'll be ignored by the caller in that case
+ return selection;
+}
+
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" && _load ) {
+ return _load.apply( this, arguments );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf( " " );
+ if ( off >= 0 ) {
+ var selector = url.slice( off, url.length );
+ url = url.slice( 0, off );
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = undefined;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ // Complete callback (responseText is used internally)
+ complete: function( jqXHR, status, responseText ) {
+ // Store the response as specified by the jqXHR object
+ responseText = jqXHR.responseText;
+ // If successful, inject the HTML into all the matched elements
+ if ( jqXHR.isResolved() ) {
+ // #4825: Get the actual response in case
+ // a dataFilter is present in ajaxSettings
+ jqXHR.done(function( r ) {
+ responseText = r;
+ });
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [ responseText, status, jqXHR ] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param( this.serializeArray() );
+ },
+
+ serializeArray: function() {
+ return this.map(function(){
+ return this.elements ? jQuery.makeArray( this.elements ) : this;
+ })
+ .filter(function(){
+ return this.name && !this.disabled &&
+ ( this.checked || rselectTextarea.test( this.nodeName ) ||
+ rinput.test( this.type ) );
+ })
+ .map(function( i, elem ){
+ var val = jQuery( this ).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray( val ) ?
+ jQuery.map( val, function( val, i ){
+ return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }) :
+ { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
+ jQuery.fn[ o ] = function( f ){
+ return this.bind( o, f );
+ };
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+ jQuery[ method ] = function( url, data, callback, type ) {
+ // shift arguments if data argument was omitted
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = undefined;
+ }
+
+ return jQuery.ajax({
+ type: method,
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ };
+});
+
+jQuery.extend({
+
+ getScript: function( url, callback ) {
+ return jQuery.get( url, undefined, callback, "script" );
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get( url, data, callback, "json" );
+ },
+
+ // Creates a full fledged settings object into target
+ // with both ajaxSettings and settings fields.
+ // If target is omitted, writes into ajaxSettings.
+ ajaxSetup: function ( target, settings ) {
+ if ( !settings ) {
+ // Only one parameter, we extend ajaxSettings
+ settings = target;
+ target = jQuery.extend( true, jQuery.ajaxSettings, settings );
+ } else {
+ // target was provided, we extend into it
+ jQuery.extend( true, target, jQuery.ajaxSettings, settings );
+ }
+ // Flatten fields we don't want deep extended
+ for( var field in { context: 1, url: 1 } ) {
+ if ( field in settings ) {
+ target[ field ] = settings[ field ];
+ } else if( field in jQuery.ajaxSettings ) {
+ target[ field ] = jQuery.ajaxSettings[ field ];
+ }
+ }
+ return target;
+ },
+
+ ajaxSettings: {
+ url: ajaxLocation,
+ isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ dataType: null,
+ username: null,
+ password: null,
+ cache: null,
+ traditional: false,
+ headers: {},
+ */
+
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ text: "text/plain",
+ json: "application/json, text/javascript",
+ "*": "*/*"
+ },
+
+ contents: {
+ xml: /xml/,
+ html: /html/,
+ json: /json/
+ },
+
+ responseFields: {
+ xml: "responseXML",
+ text: "responseText"
+ },
+
+ // List of data converters
+ // 1) key format is "source_type destination_type" (a single space in-between)
+ // 2) the catchall symbol "*" can be used for source_type
+ converters: {
+
+ // Convert anything to text
+ "* text": window.String,
+
+ // Text to html (true = no transformation)
+ "text html": true,
+
+ // Evaluate text as a json expression
+ "text json": jQuery.parseJSON,
+
+ // Parse text as xml
+ "text xml": jQuery.parseXML
+ }
+ },
+
+ ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+ ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+ // Main method
+ ajax: function( url, options ) {
+
+ // If url is an object, simulate pre-1.5 signature
+ if ( typeof url === "object" ) {
+ options = url;
+ url = undefined;
+ }
+
+ // Force options to be an object
+ options = options || {};
+
+ var // Create the final options object
+ s = jQuery.ajaxSetup( {}, options ),
+ // Callbacks context
+ callbackContext = s.context || s,
+ // Context for global events
+ // It's the callbackContext if one was provided in the options
+ // and if it's a DOM node or a jQuery collection
+ globalEventContext = callbackContext !== s &&
+ ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
+ jQuery( callbackContext ) : jQuery.event,
+ // Deferreds
+ deferred = jQuery.Deferred(),
+ completeDeferred = jQuery._Deferred(),
+ // Status-dependent callbacks
+ statusCode = s.statusCode || {},
+ // ifModified key
+ ifModifiedKey,
+ // Headers (they are sent all at once)
+ requestHeaders = {},
+ requestHeadersNames = {},
+ // Response headers
+ responseHeadersString,
+ responseHeaders,
+ // transport
+ transport,
+ // timeout handle
+ timeoutTimer,
+ // Cross-domain detection vars
+ parts,
+ // The jqXHR state
+ state = 0,
+ // To know if global events are to be dispatched
+ fireGlobals,
+ // Loop variable
+ i,
+ // Fake xhr
+ jqXHR = {
+
+ readyState: 0,
+
+ // Caches the header
+ setRequestHeader: function( name, value ) {
+ if ( !state ) {
+ var lname = name.toLowerCase();
+ name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+ requestHeaders[ name ] = value;
+ }
+ return this;
+ },
+
+ // Raw string
+ getAllResponseHeaders: function() {
+ return state === 2 ? responseHeadersString : null;
+ },
+
+ // Builds headers hashtable if needed
+ getResponseHeader: function( key ) {
+ var match;
+ if ( state === 2 ) {
+ if ( !responseHeaders ) {
+ responseHeaders = {};
+ while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+ responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+ }
+ }
+ match = responseHeaders[ key.toLowerCase() ];
+ }
+ return match === undefined ? null : match;
+ },
+
+ // Overrides response content-type header
+ overrideMimeType: function( type ) {
+ if ( !state ) {
+ s.mimeType = type;
+ }
+ return this;
+ },
+
+ // Cancel the request
+ abort: function( statusText ) {
+ statusText = statusText || "abort";
+ if ( transport ) {
+ transport.abort( statusText );
+ }
+ done( 0, statusText );
+ return this;
+ }
+ };
+
+ // Callback for when everything is done
+ // It is defined here because jslint complains if it is declared
+ // at the end of the function (which would be more logical and readable)
+ function done( status, statusText, responses, headers ) {
+
+ // Called once
+ if ( state === 2 ) {
+ return;
+ }
+
+ // State is "done" now
+ state = 2;
+
+ // Clear timeout if it exists
+ if ( timeoutTimer ) {
+ clearTimeout( timeoutTimer );
+ }
+
+ // Dereference transport for early garbage collection
+ // (no matter how long the jqXHR object will be used)
+ transport = undefined;
+
+ // Cache response headers
+ responseHeadersString = headers || "";
+
+ // Set readyState
+ jqXHR.readyState = status ? 4 : 0;
+
+ var isSuccess,
+ success,
+ error,
+ response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
+ lastModified,
+ etag;
+
+ // If successful, handle type chaining
+ if ( status >= 200 && status < 300 || status === 304 ) {
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+
+ if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
+ jQuery.lastModified[ ifModifiedKey ] = lastModified;
+ }
+ if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
+ jQuery.etag[ ifModifiedKey ] = etag;
+ }
+ }
+
+ // If not modified
+ if ( status === 304 ) {
+
+ statusText = "notmodified";
+ isSuccess = true;
+
+ // If we have data
+ } else {
+
+ try {
+ success = ajaxConvert( s, response );
+ statusText = "success";
+ isSuccess = true;
+ } catch(e) {
+ // We have a parsererror
+ statusText = "parsererror";
+ error = e;
+ }
+ }
+ } else {
+ // We extract error from statusText
+ // then normalize statusText and status for non-aborts
+ error = statusText;
+ if( !statusText || status ) {
+ statusText = "error";
+ if ( status < 0 ) {
+ status = 0;
+ }
+ }
+ }
+
+ // Set data for the fake xhr object
+ jqXHR.status = status;
+ jqXHR.statusText = statusText;
+
+ // Success/Error
+ if ( isSuccess ) {
+ deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+ } else {
+ deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+ }
+
+ // Status-dependent callbacks
+ jqXHR.statusCode( statusCode );
+ statusCode = undefined;
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
+ [ jqXHR, s, isSuccess ? success : error ] );
+ }
+
+ // Complete
+ completeDeferred.resolveWith( callbackContext, [ jqXHR, statusText ] );
+
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxComplete", [ jqXHR, s] );
+ // Handle the global AJAX counter
+ if ( !( --jQuery.active ) ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ }
+ }
+
+ // Attach deferreds
+ deferred.promise( jqXHR );
+ jqXHR.success = jqXHR.done;
+ jqXHR.error = jqXHR.fail;
+ jqXHR.complete = completeDeferred.done;
+
+ // Status-dependent callbacks
+ jqXHR.statusCode = function( map ) {
+ if ( map ) {
+ var tmp;
+ if ( state < 2 ) {
+ for( tmp in map ) {
+ statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
+ }
+ } else {
+ tmp = map[ jqXHR.status ];
+ jqXHR.then( tmp, tmp );
+ }
+ }
+ return this;
+ };
+
+ // Remove hash character (#7531: and string promotion)
+ // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+ // We also use the url parameter if available
+ s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+ // Extract dataTypes list
+ s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
+
+ // Determine if a cross-domain request is in order
+ if ( s.crossDomain == null ) {
+ parts = rurl.exec( s.url.toLowerCase() );
+ s.crossDomain = !!( parts &&
+ ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
+ ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
+ ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
+ );
+ }
+
+ // Convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Apply prefilters
+ inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+ // If request was aborted inside a prefiler, stop there
+ if ( state === 2 ) {
+ return false;
+ }
+
+ // We can fire global events as of now if asked to
+ fireGlobals = s.global;
+
+ // Uppercase the type
+ s.type = s.type.toUpperCase();
+
+ // Determine if request has content
+ s.hasContent = !rnoContent.test( s.type );
+
+ // Watch for a new set of requests
+ if ( fireGlobals && jQuery.active++ === 0 ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // More options handling for requests with no content
+ if ( !s.hasContent ) {
+
+ // If data is available, append data to url
+ if ( s.data ) {
+ s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
+ }
+
+ // Get ifModifiedKey before adding the anti-cache parameter
+ ifModifiedKey = s.url;
+
+ // Add anti-cache in url if needed
+ if ( s.cache === false ) {
+
+ var ts = jQuery.now(),
+ // try replacing _= if it is there
+ ret = s.url.replace( rts, "$1_=" + ts );
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ( (ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
+ }
+ }
+
+ // Set the correct header, if data is being sent
+ if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+ jqXHR.setRequestHeader( "Content-Type", s.contentType );
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ ifModifiedKey = ifModifiedKey || s.url;
+ if ( jQuery.lastModified[ ifModifiedKey ] ) {
+ jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
+ }
+ if ( jQuery.etag[ ifModifiedKey ] ) {
+ jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
+ }
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ jqXHR.setRequestHeader(
+ "Accept",
+ s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+ s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) :
+ s.accepts[ "*" ]
+ );
+
+ // Check for headers option
+ for ( i in s.headers ) {
+ jqXHR.setRequestHeader( i, s.headers[ i ] );
+ }
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+ // Abort if not done already
+ jqXHR.abort();
+ return false;
+
+ }
+
+ // Install callbacks on deferreds
+ for ( i in { success: 1, error: 1, complete: 1 } ) {
+ jqXHR[ i ]( s[ i ] );
+ }
+
+ // Get transport
+ transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+ // If no transport, we auto-abort
+ if ( !transport ) {
+ done( -1, "No Transport" );
+ } else {
+ jqXHR.readyState = 1;
+ // Send global event
+ if ( fireGlobals ) {
+ globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+ }
+ // Timeout
+ if ( s.async && s.timeout > 0 ) {
+ timeoutTimer = setTimeout( function(){
+ jqXHR.abort( "timeout" );
+ }, s.timeout );
+ }
+
+ try {
+ state = 1;
+ transport.send( requestHeaders, done );
+ } catch (e) {
+ // Propagate exception as error if not done
+ if ( status < 2 ) {
+ done( -1, e );
+ // Simply rethrow otherwise
+ } else {
+ jQuery.error( e );
+ }
+ }
+ }
+
+ return jqXHR;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ var s = [],
+ add = function( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction( value ) ? value() : value;
+ s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+ };
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[ prefix ], traditional, add );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join( "&" ).replace( r20, "+" );
+ }
+});
+
+function buildParams( prefix, obj, traditional, add ) {
+ if ( jQuery.isArray( obj ) ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ // Serialize object item.
+ for ( var name in obj ) {
+ buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+ }
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+}
+
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {}
+
+});
+
+/* Handles responses to an ajax request:
+ * - sets all responseXXX fields accordingly
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+ var contents = s.contents,
+ dataTypes = s.dataTypes,
+ responseFields = s.responseFields,
+ ct,
+ type,
+ finalDataType,
+ firstDataType;
+
+ // Fill responseXXX fields
+ for( type in responseFields ) {
+ if ( type in responses ) {
+ jqXHR[ responseFields[type] ] = responses[ type ];
+ }
+ }
+
+ // Remove auto dataType and get content-type in the process
+ while( dataTypes[ 0 ] === "*" ) {
+ dataTypes.shift();
+ if ( ct === undefined ) {
+ ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
+ }
+ }
+
+ // Check if we're dealing with a known content-type
+ if ( ct ) {
+ for ( type in contents ) {
+ if ( contents[ type ] && contents[ type ].test( ct ) ) {
+ dataTypes.unshift( type );
+ break;
+ }
+ }
+ }
+
+ // Check to see if we have a response for the expected dataType
+ if ( dataTypes[ 0 ] in responses ) {
+ finalDataType = dataTypes[ 0 ];
+ } else {
+ // Try convertible dataTypes
+ for ( type in responses ) {
+ if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+ finalDataType = type;
+ break;
+ }
+ if ( !firstDataType ) {
+ firstDataType = type;
+ }
+ }
+ // Or just use first one
+ finalDataType = finalDataType || firstDataType;
+ }
+
+ // If we found a dataType
+ // We add the dataType to the list if needed
+ // and return the corresponding response
+ if ( finalDataType ) {
+ if ( finalDataType !== dataTypes[ 0 ] ) {
+ dataTypes.unshift( finalDataType );
+ }
+ return responses[ finalDataType ];
+ }
+}
+
+// Chain conversions given the request and the original response
+function ajaxConvert( s, response ) {
+
+ // Apply the dataFilter if provided
+ if ( s.dataFilter ) {
+ response = s.dataFilter( response, s.dataType );
+ }
+
+ var dataTypes = s.dataTypes,
+ converters = {},
+ i,
+ key,
+ length = dataTypes.length,
+ tmp,
+ // Current and previous dataTypes
+ current = dataTypes[ 0 ],
+ prev,
+ // Conversion expression
+ conversion,
+ // Conversion function
+ conv,
+ // Conversion functions (transitive conversion)
+ conv1,
+ conv2;
+
+ // For each dataType in the chain
+ for( i = 1; i < length; i++ ) {
+
+ // Create converters map
+ // with lowercased keys
+ if ( i === 1 ) {
+ for( key in s.converters ) {
+ if( typeof key === "string" ) {
+ converters[ key.toLowerCase() ] = s.converters[ key ];
+ }
+ }
+ }
+
+ // Get the dataTypes
+ prev = current;
+ current = dataTypes[ i ];
+
+ // If current is auto dataType, update it to prev
+ if( current === "*" ) {
+ current = prev;
+ // If no auto and dataTypes are actually different
+ } else if ( prev !== "*" && prev !== current ) {
+
+ // Get the converter
+ conversion = prev + " " + current;
+ conv = converters[ conversion ] || converters[ "* " + current ];
+
+ // If there is no direct converter, search transitively
+ if ( !conv ) {
+ conv2 = undefined;
+ for( conv1 in converters ) {
+ tmp = conv1.split( " " );
+ if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
+ conv2 = converters[ tmp[1] + " " + current ];
+ if ( conv2 ) {
+ conv1 = converters[ conv1 ];
+ if ( conv1 === true ) {
+ conv = conv2;
+ } else if ( conv2 === true ) {
+ conv = conv1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ // If we found no converter, dispatch an error
+ if ( !( conv || conv2 ) ) {
+ jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
+ }
+ // If found converter is not an equivalence
+ if ( conv !== true ) {
+ // Convert with 1 or 2 converters accordingly
+ response = conv ? conv( response ) : conv2( conv1(response) );
+ }
+ }
+ }
+ return response;
+}
+
+
+
+
+var jsc = jQuery.now(),
+ jsre = /(\=)\?(&|$)|\?\?/i;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+ jsonp: "callback",
+ jsonpCallback: function() {
+ return jQuery.expando + "_" + ( jsc++ );
+ }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+ var inspectData = s.contentType === "application/x-www-form-urlencoded" &&
+ ( typeof s.data === "string" );
+
+ if ( s.dataTypes[ 0 ] === "jsonp" ||
+ s.jsonp !== false && ( jsre.test( s.url ) ||
+ inspectData && jsre.test( s.data ) ) ) {
+
+ var responseContainer,
+ jsonpCallback = s.jsonpCallback =
+ jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
+ previous = window[ jsonpCallback ],
+ url = s.url,
+ data = s.data,
+ replace = "$1" + jsonpCallback + "$2";
+
+ if ( s.jsonp !== false ) {
+ url = url.replace( jsre, replace );
+ if ( s.url === url ) {
+ if ( inspectData ) {
+ data = data.replace( jsre, replace );
+ }
+ if ( s.data === data ) {
+ // Add callback manually
+ url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
+ }
+ }
+ }
+
+ s.url = url;
+ s.data = data;
+
+ // Install callback
+ window[ jsonpCallback ] = function( response ) {
+ responseContainer = [ response ];
+ };
+
+ // Clean-up function
+ jqXHR.always(function() {
+ // Set callback back to previous value
+ window[ jsonpCallback ] = previous;
+ // Call if it was a function and we have a response
+ if ( responseContainer && jQuery.isFunction( previous ) ) {
+ window[ jsonpCallback ]( responseContainer[ 0 ] );
+ }
+ });
+
+ // Use data converter to retrieve json after script execution
+ s.converters["script json"] = function() {
+ if ( !responseContainer ) {
+ jQuery.error( jsonpCallback + " was not called" );
+ }
+ return responseContainer[ 0 ];
+ };
+
+ // force json dataType
+ s.dataTypes[ 0 ] = "json";
+
+ // Delegate to script
+ return "script";
+ }
+});
+
+
+
+
+// Install script dataType
+jQuery.ajaxSetup({
+ accepts: {
+ script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+ },
+ contents: {
+ script: /javascript|ecmascript/
+ },
+ converters: {
+ "text script": function( text ) {
+ jQuery.globalEval( text );
+ return text;
+ }
+ }
+});
+
+// Handle cache's special case and global
+jQuery.ajaxPrefilter( "script", function( s ) {
+ if ( s.cache === undefined ) {
+ s.cache = false;
+ }
+ if ( s.crossDomain ) {
+ s.type = "GET";
+ s.global = false;
+ }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function(s) {
+
+ // This transport only deals with cross domain requests
+ if ( s.crossDomain ) {
+
+ var script,
+ head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
+
+ return {
+
+ send: function( _, callback ) {
+
+ script = document.createElement( "script" );
+
+ script.async = "async";
+
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+
+ script.src = s.url;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function( _, isAbort ) {
+
+ if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+
+ // Remove the script
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+
+ // Dereference the script
+ script = undefined;
+
+ // Callback if not abort
+ if ( !isAbort ) {
+ callback( 200, "success" );
+ }
+ }
+ };
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+ },
+
+ abort: function() {
+ if ( script ) {
+ script.onload( 0, 1 );
+ }
+ }
+ };
+ }
+});
+
+
+
+
+var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
+ xhrOnUnloadAbort = window.ActiveXObject ? function() {
+ // Abort all pending requests
+ for ( var key in xhrCallbacks ) {
+ xhrCallbacks[ key ]( 0, 1 );
+ }
+ } : false,
+ xhrId = 0,
+ xhrCallbacks;
+
+// Functions to create xhrs
+function createStandardXHR() {
+ try {
+ return new window.XMLHttpRequest();
+ } catch( e ) {}
+}
+
+function createActiveXHR() {
+ try {
+ return new window.ActiveXObject( "Microsoft.XMLHTTP" );
+ } catch( e ) {}
+}
+
+// Create the request object
+// (This is still attached to ajaxSettings for backward compatibility)
+jQuery.ajaxSettings.xhr = window.ActiveXObject ?
+ /* Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+ function() {
+ return !this.isLocal && createStandardXHR() || createActiveXHR();
+ } :
+ // For all other browsers, use the standard XMLHttpRequest object
+ createStandardXHR;
+
+// Determine support properties
+(function( xhr ) {
+ jQuery.extend( jQuery.support, {
+ ajax: !!xhr,
+ cors: !!xhr && ( "withCredentials" in xhr )
+ });
+})( jQuery.ajaxSettings.xhr() );
+
+// Create transport if the browser can provide an xhr
+if ( jQuery.support.ajax ) {
+
+ jQuery.ajaxTransport(function( s ) {
+ // Cross domain only allowed if supported through XMLHttpRequest
+ if ( !s.crossDomain || jQuery.support.cors ) {
+
+ var callback;
+
+ return {
+ send: function( headers, complete ) {
+
+ // Get a new xhr
+ var xhr = s.xhr(),
+ handle,
+ i;
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open( s.type, s.url, s.async, s.username, s.password );
+ } else {
+ xhr.open( s.type, s.url, s.async );
+ }
+
+ // Apply custom fields if provided
+ if ( s.xhrFields ) {
+ for ( i in s.xhrFields ) {
+ xhr[ i ] = s.xhrFields[ i ];
+ }
+ }
+
+ // Override mime type if needed
+ if ( s.mimeType && xhr.overrideMimeType ) {
+ xhr.overrideMimeType( s.mimeType );
+ }
+
+ // X-Requested-With header
+ // For cross-domain requests, seeing as conditions for a preflight are
+ // akin to a jigsaw puzzle, we simply never set it to be sure.
+ // (it can always be set on a per-request basis or even using ajaxSetup)
+ // For same-domain requests, won't change header if already provided.
+ if ( !s.crossDomain && !headers["X-Requested-With"] ) {
+ headers[ "X-Requested-With" ] = "XMLHttpRequest";
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ for ( i in headers ) {
+ xhr.setRequestHeader( i, headers[ i ] );
+ }
+ } catch( _ ) {}
+
+ // Do send the request
+ // This may raise an exception which is actually
+ // handled in jQuery.ajax (so no try/catch here)
+ xhr.send( ( s.hasContent && s.data ) || null );
+
+ // Listener
+ callback = function( _, isAbort ) {
+
+ var status,
+ statusText,
+ responseHeaders,
+ responses,
+ xml;
+
+ // Firefox throws exceptions when accessing properties
+ // of an xhr when a network error occured
+ // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
+ try {
+
+ // Was never called and is aborted or complete
+ if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
+
+ // Only called once
+ callback = undefined;
+
+ // Do not keep as active anymore
+ if ( handle ) {
+ xhr.onreadystatechange = jQuery.noop;
+ if ( xhrOnUnloadAbort ) {
+ delete xhrCallbacks[ handle ];
+ }
+ }
+
+ // If it's an abort
+ if ( isAbort ) {
+ // Abort it manually if needed
+ if ( xhr.readyState !== 4 ) {
+ xhr.abort();
+ }
+ } else {
+ status = xhr.status;
+ responseHeaders = xhr.getAllResponseHeaders();
+ responses = {};
+ xml = xhr.responseXML;
+
+ // Construct response list
+ if ( xml && xml.documentElement /* #4958 */ ) {
+ responses.xml = xml;
+ }
+ responses.text = xhr.responseText;
+
+ // Firefox throws an exception when accessing
+ // statusText for faulty cross-domain requests
+ try {
+ statusText = xhr.statusText;
+ } catch( e ) {
+ // We normalize with Webkit giving an empty statusText
+ statusText = "";
+ }
+
+ // Filter status for non standard behaviors
+
+ // If the request is local and we have data: assume a success
+ // (success with no data won't get notified, that's the best we
+ // can do given current implementations)
+ if ( !status && s.isLocal && !s.crossDomain ) {
+ status = responses.text ? 200 : 404;
+ // IE - #1450: sometimes returns 1223 when it should be 204
+ } else if ( status === 1223 ) {
+ status = 204;
+ }
+ }
+ }
+ } catch( firefoxAccessException ) {
+ if ( !isAbort ) {
+ complete( -1, firefoxAccessException );
+ }
+ }
+
+ // Call complete if needed
+ if ( responses ) {
+ complete( status, statusText, responses, responseHeaders );
+ }
+ };
+
+ // if we're in sync mode or it's in cache
+ // and has been retrieved directly (IE6 & IE7)
+ // we need to manually fire the callback
+ if ( !s.async || xhr.readyState === 4 ) {
+ callback();
+ } else {
+ handle = ++xhrId;
+ if ( xhrOnUnloadAbort ) {
+ // Create the active xhrs callbacks list if needed
+ // and attach the unload handler
+ if ( !xhrCallbacks ) {
+ xhrCallbacks = {};
+ jQuery( window ).unload( xhrOnUnloadAbort );
+ }
+ // Add to list of active xhrs callbacks
+ xhrCallbacks[ handle ] = callback;
+ }
+ xhr.onreadystatechange = callback;
+ }
+ },
+
+ abort: function() {
+ if ( callback ) {
+ callback(0,1);
+ }
+ }
+ };
+ }
+ });
+}
+
+
+
+
+var elemdisplay = {},
+ iframe, iframeDoc,
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ],
+ fxNow,
+ requestAnimationFrame = window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame;
+
+jQuery.fn.extend({
+ show: function( speed, easing, callback ) {
+ var elem, display;
+
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("show", 3), speed, easing, callback);
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ elem = this[i];
+
+ if ( elem.style ) {
+ display = elem.style.display;
+
+ // Reset the inline display of this element to learn if it is
+ // being hidden by cascaded rules or not
+ if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
+ display = elem.style.display = "";
+ }
+
+ // Set elements which have been overridden with display: none
+ // in a stylesheet to whatever the default browser style is
+ // for such an element
+ if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+ jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName));
+ }
+ }
+ }
+
+ // Set the display of most of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ elem = this[i];
+
+ if ( elem.style ) {
+ display = elem.style.display;
+
+ if ( display === "" || display === "none" ) {
+ elem.style.display = jQuery._data(elem, "olddisplay") || "";
+ }
+ }
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, easing, callback ) {
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, easing, callback);
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ if ( this[i].style ) {
+ var display = jQuery.css( this[i], "display" );
+
+ if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) {
+ jQuery._data( this[i], "olddisplay", display );
+ }
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ if ( this[i].style ) {
+ this[i].style.display = "none";
+ }
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2, callback ) {
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2, callback);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, easing, callback ) {
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, easing, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete, [ false ] );
+ }
+
+ // Do not change referenced properties as per-property easing will be lost
+ prop = jQuery.extend( {}, prop );
+
+ return this[ optall.queue === false ? "each" : "queue" ](function() {
+ // XXX 'this' does not always have a nodeName when running the
+ // test suite
+
+ if ( optall.queue === false ) {
+ jQuery._mark( this );
+ }
+
+ var opt = jQuery.extend( {}, optall ),
+ isElement = this.nodeType === 1,
+ hidden = isElement && jQuery(this).is(":hidden"),
+ name, val, p,
+ display, e,
+ parts, start, end, unit;
+
+ // will store per property easing and be used to determine when an animation is complete
+ opt.animatedProperties = {};
+
+ for ( p in prop ) {
+
+ // property name normalization
+ name = jQuery.camelCase( p );
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ }
+
+ val = prop[ name ];
+
+ // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
+ if ( jQuery.isArray( val ) ) {
+ opt.animatedProperties[ name ] = val[ 1 ];
+ val = prop[ name ] = val[ 0 ];
+ } else {
+ opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
+ }
+
+ if ( val === "hide" && hidden || val === "show" && !hidden ) {
+ return opt.complete.call( this );
+ }
+
+ if ( isElement && ( name === "height" || name === "width" ) ) {
+ // Make sure that nothing sneaks out
+ // Record all 3 overflow attributes because IE does not
+ // change the overflow attribute when overflowX and
+ // overflowY are set to the same value
+ opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+ // Set display property to inline-block for height/width
+ // animations on inline elements that are having width/height
+ // animated
+ if ( jQuery.css( this, "display" ) === "inline" &&
+ jQuery.css( this, "float" ) === "none" ) {
+ if ( !jQuery.support.inlineBlockNeedsLayout ) {
+ this.style.display = "inline-block";
+
+ } else {
+ display = defaultDisplay( this.nodeName );
+
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( display === "inline" ) {
+ this.style.display = "inline-block";
+
+ } else {
+ this.style.display = "inline";
+ this.style.zoom = 1;
+ }
+ }
+ }
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ for ( p in prop ) {
+ e = new jQuery.fx( this, opt, p );
+ val = prop[ p ];
+
+ if ( rfxtypes.test(val) ) {
+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
+
+ } else {
+ parts = rfxnum.exec( val );
+ start = e.cur();
+
+ if ( parts ) {
+ end = parseFloat( parts[2] );
+ unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ jQuery.style( this, p, (end || 1) + unit);
+ start = ((end || 1) / e.cur()) * start;
+ jQuery.style( this, p, start + unit);
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ }
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function( clearQueue, gotoEnd ) {
+ if ( clearQueue ) {
+ this.queue([]);
+ }
+
+ this.each(function() {
+ var timers = jQuery.timers,
+ i = timers.length;
+ // clear marker counters if we know they won't be
+ if ( !gotoEnd ) {
+ jQuery._unmark( true, this );
+ }
+ while ( i-- ) {
+ if ( timers[i].elem === this ) {
+ if (gotoEnd) {
+ // force the next step to be the last
+ timers[i](true);
+ }
+
+ timers.splice(i, 1);
+ }
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if ( !gotoEnd ) {
+ this.dequeue();
+ }
+
+ return this;
+ }
+
+});
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+ setTimeout( clearFxNow, 0 );
+ return ( fxNow = jQuery.now() );
+}
+
+function clearFxNow() {
+ fxNow = undefined;
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+});
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function( noUnmark ) {
+ if ( opt.queue !== false ) {
+ jQuery.dequeue( this );
+ } else if ( noUnmark !== false ) {
+ jQuery._unmark( this );
+ }
+
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ options.orig = options.orig || {};
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+ },
+
+ // Get the current size
+ cur: function() {
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var parsed,
+ r = jQuery.css( this.elem, this.prop );
+ // Empty strings, null, undefined and "auto" are converted to 0,
+ // complex values such as "rotate(1rad)" are returned as is,
+ // simple values such as "10px" are parsed to Float.
+ return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ var self = this,
+ fx = jQuery.fx,
+ raf;
+
+ this.startTime = fxNow || createFxNow();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ function t( gotoEnd ) {
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ // Use requestAnimationFrame instead of setInterval if available
+ if ( requestAnimationFrame ) {
+ timerId = 1;
+ raf = function() {
+ // When timerId gets set to null at any point, this stops
+ if ( timerId ) {
+ requestAnimationFrame( raf );
+ fx.tick();
+ }
+ };
+ requestAnimationFrame( raf );
+ } else {
+ timerId = setInterval( fx.tick, fx.interval );
+ }
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ var t = fxNow || createFxNow(),
+ done = true,
+ elem = this.elem,
+ options = this.options,
+ i, n;
+
+ if ( gotoEnd || t >= options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ options.animatedProperties[ this.prop ] = true;
+
+ for ( i in options.animatedProperties ) {
+ if ( options.animatedProperties[i] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ // Reset the overflow
+ if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+
+ jQuery.each( [ "", "X", "Y" ], function (index, value) {
+ elem.style[ "overflow" + value ] = options.overflow[index];
+ });
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( options.hide ) {
+ jQuery(elem).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( options.hide || options.show ) {
+ for ( var p in options.animatedProperties ) {
+ jQuery.style( elem, p, options.orig[p] );
+ }
+ }
+
+ // Execute the complete function
+ options.complete.call( elem );
+ }
+
+ return false;
+
+ } else {
+ // classical easing cannot be used with an Infinity duration
+ if ( options.duration == Infinity ) {
+ this.now = t;
+ } else {
+ n = t - this.startTime;
+ this.state = n / options.duration;
+
+ // Perform the easing function, defaults to swing
+ this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
+ this.now = this.start + ((this.end - this.start) * this.pos);
+ }
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) {
+ if ( !timers[i]() ) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ interval: 13,
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style( fx.elem, "opacity", fx.now );
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+// Try to restore the default display value of an element
+function defaultDisplay( nodeName ) {
+
+ if ( !elemdisplay[ nodeName ] ) {
+
+ var elem = jQuery( "<" + nodeName + ">" ).appendTo( "body" ),
+ display = elem.css( "display" );
+
+ elem.remove();
+
+ // If the simple way fails,
+ // get element's real default display by attaching it to a temp iframe
+ if ( display === "none" || display === "" ) {
+ // No iframe to use yet, so create it
+ if ( !iframe ) {
+ iframe = document.createElement( "iframe" );
+ iframe.frameBorder = iframe.width = iframe.height = 0;
+ }
+
+ document.body.appendChild( iframe );
+
+ // Create a cacheable copy of the iframe document on first call.
+ // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake html
+ // document to it, Webkit & Firefox won't allow reusing the iframe document
+ if ( !iframeDoc || !iframe.createElement ) {
+ iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
+ iframeDoc.write( "<!doctype><html><body></body></html>" );
+ }
+
+ elem = iframeDoc.createElement( nodeName );
+
+ iframeDoc.body.appendChild( elem );
+
+ display = jQuery.css( elem, "display" );
+
+ document.body.removeChild( iframe );
+ }
+
+ // Store the correct default display
+ elemdisplay[ nodeName ] = display;
+ }
+
+ return elemdisplay[ nodeName ];
+}
+
+
+
+
+var rtable = /^t(?:able|d|h)$/i,
+ rroot = /^(?:body|html)$/i;
+
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0], box;
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ try {
+ box = elem.getBoundingClientRect();
+ } catch(e) {}
+
+ var doc = elem.ownerDocument,
+ docElem = doc.documentElement;
+
+ // Make sure we're not dealing with a disconnected DOM node
+ if ( !box || !jQuery.contains( docElem, elem ) ) {
+ return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
+ }
+
+ var body = doc.body,
+ win = getWindow(doc),
+ clientTop = docElem.clientTop || body.clientTop || 0,
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
+ scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
+ top = box.top + scrollTop - clientTop,
+ left = box.left + scrollLeft - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ jQuery.offset.initialize();
+
+ var computedStyle,
+ offsetParent = elem.offsetParent,
+ prevOffsetParent = elem,
+ doc = elem.ownerDocument,
+ docElem = doc.documentElement,
+ body = doc.body,
+ defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop,
+ left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent;
+ offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+ initialize: function() {
+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
+ html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+ container.innerHTML = html;
+ body.insertBefore( container, body.firstChild );
+ innerDiv = container.firstChild;
+ checkDiv = innerDiv.firstChild;
+ td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ checkDiv.style.position = "fixed";
+ checkDiv.style.top = "20px";
+
+ // safari subtracts parent border width here which is 5px
+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+ checkDiv.style.position = checkDiv.style.top = "";
+
+ innerDiv.style.overflow = "hidden";
+ innerDiv.style.position = "relative";
+
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+ body.removeChild( container );
+ jQuery.offset.initialize = jQuery.noop;
+ },
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop,
+ left = body.offsetLeft;
+
+ jQuery.offset.initialize();
+
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+ left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ var position = jQuery.css( elem, "position" );
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
+ props = {}, curPosition = {}, curTop, curLeft;
+
+ // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ curTop = curPosition.top;
+ curLeft = curPosition.left;
+ } else {
+ curTop = parseFloat( curCSSTop ) || 0;
+ curLeft = parseFloat( curCSSLeft ) || 0;
+ }
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if (options.top != null) {
+ props.top = (options.top - curOffset.top) + curTop;
+ }
+ if (options.left != null) {
+ props.left = (options.left - curOffset.left) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+ offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+ parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function( val ) {
+ var elem, win;
+
+ if ( val === undefined ) {
+ elem = this[ 0 ];
+
+ if ( !elem ) {
+ return null;
+ }
+
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery( win ).scrollLeft(),
+ i ? val : jQuery( win ).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ };
+});
+
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+
+
+
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function() {
+ return this[0] ?
+ parseFloat( jQuery.css( this[0], type, "padding" ) ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function( margin ) {
+ return this[0] ?
+ parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ if ( jQuery.isWindow( elem ) ) {
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
+ var docElemProp = elem.document.documentElement[ "client" + name ];
+ return elem.document.compatMode === "CSS1Compat" && docElemProp ||
+ elem.document.body[ "client" + name ] || docElemProp;
+
+ // Get document width or height
+ } else if ( elem.nodeType === 9 ) {
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ return Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ );
+
+ // Get or set width or height on the element
+ } else if ( size === undefined ) {
+ var orig = jQuery.css( elem, type ),
+ ret = parseFloat( orig );
+
+ return jQuery.isNaN( ret ) ? orig : ret;
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ } else {
+ return this.css( type, typeof size === "string" ? size : size + "px" );
+ }
+ };
+
+});
+
+
+window.jQuery = window.$ = jQuery;
+})(window);
diff --git a/src/OAuth/OAuthClient/Scripts/jquery-1.6.1.min.js b/src/OAuth/OAuthClient/Scripts/jquery-1.6.1.min.js
new file mode 100644
index 0000000..b2ac174
--- /dev/null
+++ b/src/OAuth/OAuthClient/Scripts/jquery-1.6.1.min.js
@@ -0,0 +1,18 @@
+/*!
+ * jQuery JavaScript Library v1.6.1
+ * http://jquery.com/
+ *
+ * Copyright 2011, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2011, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu May 12 15:04:36 2011 -0400
+ */
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!cj[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),c.body.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write("<!doctype><html><body></body></html>");b=cl.createElement(a),cl.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ck)}cj[a]=d}return cj[a]}function cu(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function ct(){cq=b}function cs(){setTimeout(ct,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bF.test(a)?d(a,e):b_(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bU,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bQ),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bD(a,b,c){var d=b==="width"?bx:by,e=b==="width"?a.offsetWidth:a.offsetHeight;if(c==="border")return e;f.each(d,function(){c||(e-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?e+=parseFloat(f.css(a,"margin"+this))||0:e-=parseFloat(f.css(a,"border"+this+"Width"))||0});return e}function bn(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bm(a){f.nodeName(a,"input")?bl(a):a.getElementsByTagName&&f.grep(a.getElementsByTagName("input"),bl)}function bl(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bk(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bj(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bi(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bh(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function X(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(S.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function W(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function O(a,b){return(a&&a!=="*"?a+".":"")+b.replace(A,"`").replace(B,"&")}function N(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(y,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function L(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function F(){return!0}function E(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.1",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:E?function(a){return a==null?"":E.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?C.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(F)return F.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=D.call(arguments,2),g=function(){return a.apply(c,f.concat(D.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){G["[object "+b+"]"]=b.toLowerCase()}),x=e.uaMatch(w),x.browser&&(e.browser[x.browser]=!0,e.browser.version=x.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?z=function(){c.removeEventListener("DOMContentLoaded",z,!1),e.ready()}:c.attachEvent&&(z=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",z),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g](h)}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};f=c.createElement("select"),g=f.appendChild(c.createElement("option")),h=a.getElementsByTagName("input")[0],j={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},h.checked=!0,j.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,j.optDisabled=!g.disabled;try{delete a.test}catch(s){j.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function b(){j.noCloneEvent=!1,a.detachEvent("onclick",b)}),a.cloneNode(!0).fireEvent("onclick")),h=c.createElement("input"),h.value="t",h.setAttribute("type","radio"),j.radioValue=h.value==="t",h.setAttribute("checked","checked"),a.appendChild(h),k=c.createDocumentFragment(),k.appendChild(a.firstChild),j.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",l=c.createElement("body"),m={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(q in m)l.style[q]=m[q];l.appendChild(a),b.insertBefore(l,b.firstChild),j.appendChecked=h.checked,j.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,j.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",j.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",n=a.getElementsByTagName("td"),r=n[0].offsetHeight===0,n[0].style.display="",n[1].style.display="none",j.reliableHiddenOffsets=r&&n[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(i=c.createElement("div"),i.style.width="0",i.style.marginRight="0",a.appendChild(i),j.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(i,null)||{marginRight:0}).marginRight,10)||0)===0),l.innerHTML="",b.removeChild(l);if(a.attachEvent)for(q in{submit:1,change:1,focusin:1})p="on"+q,r=p in a,r||(a.setAttribute(p,"return;"),r=typeof a[p]=="function"),j[q+"Bubbles"]=r;return j}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u=/\:/,v,w;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.addClass(a.call(this,b,c.attr("class")||""))});if(a&&typeof a=="string"){var b=(a||"").split(o);for(var c=0,d=this.length;c<d;c++){var e=this[c];if(e.nodeType===1)if(!e.className)e.className=a;else{var g=" "+e.className+" ",h=e.className;for(var i=0,j=b.length;i<j;i++)g.indexOf(" "+b[i]+" ")<0&&(h+=" "+b[i]);e.className=f.trim(h)}}}return this},removeClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.removeClass(a.call(this,b,c.attr("class")))});if(a&&typeof a=="string"||a===b){var c=(a||"").split(o);for(var d=0,e=this.length;d<e;d++){var g=this[d];if(g.nodeType===1&&g.className)if(a){var h=(" "+g.className+" ").replace(n," ");for(var i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){var d=f(this);d.toggleClass(a.call(this,c,d.attr("class"),b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;return(e.value||"").replace(p,"")}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);c=j&&f.attrFix[c]||c,i=f.attrHooks[c],i||(!t.test(c)||typeof d!="boolean"&&d!==b&&d.toLowerCase()!==c.toLowerCase()?v&&(f.nodeName(a,"form")||u.test(c))&&(i=v):i=w);if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j)return i.get(a,c);h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);c=i&&f.propFix[c]||c,h=f.propHooks[c];return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return a[f.propFix[c]||c]?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=b),a.setAttribute(c,c.toLowerCase()));return c}},f.attrHooks.value={get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return a.value},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=Object.prototype.hasOwnProperty,y=/\.(.*)$/,z=/^(?:textarea|input|select)$/i,A=/\./g,B=/ /g,C=/[^\w\s.|`]/g,D=function(a){return a.replace(C,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=E;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=E);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),D).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem
+)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,O(a.origType,a.selector),f.extend({},a,{handler:N,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,O(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?F:E):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=F;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=F;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=F,this.stopPropagation()},isDefaultPrevented:E,isPropagationStopped:E,isImmediatePropagationStopped:E};var G=function(a){var b=a.relatedTarget;a.type=a.data;try{if(b&&b!==c&&!b.parentNode)return;while(b&&b!==this)b=b.parentNode;b!==this&&f.event.handle.apply(this,arguments)}catch(d){}},H=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?H:G,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?H:G)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&f(b).closest("form").length&&L("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&L("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var I,J=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},K=function(c){var d=c.target,e,g;if(!!z.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=J(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:K,beforedeactivate:K,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&K.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&K.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",J(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in I)f.event.add(this,c+".specialChange",I[c]);return z.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return z.test(this.nodeName)}},I=f.event.special.change.filters,I.focus=I.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var M={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||E,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=y.exec(h),k="",j&&(k=j[0],h=h.replace(y,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,M[h]?(a.push(M[h]+k),h=h+k):h=(M[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+O(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+O(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var P=/Until$/,Q=/^(?:parents|prevUntil|prevAll)/,R=/,/,S=/^.[^:#\[\.,]*$/,T=Array.prototype.slice,U=f.expr.match.POS,V={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(X(this,a,!1),"not",a)},filter:function(a){return this.pushStack(X(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=U.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=U.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(W(c[0])||W(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=T.call(arguments);P.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!V[a]?f.unique(e):e,(this.length>1||R.test(d))&&Q.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y=/ jQuery\d+="(?:\d+|null)"/g,Z=/^\s+/,$=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,_=/<([\w:]+)/,ba=/<tbody/i,bb=/<|&#?\w+;/,bc=/<(?:script|object|embed|option|style)/i,bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Y,""):null;if(typeof a=="string"&&!bc.test(a)&&(f.support.leadingWhitespace||!Z.test(a))&&!bg[(_.exec(a)||["",""])[1].toLowerCase()]){a=a.replace($,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bh(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bn)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i=b&&b[0]?b[0].ownerDocument||b[0]:c;a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!bc.test(a[0])&&(f.support.checkClone||!bd.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bj(a,d),e=bk(a),g=bk(d);for(h=0;e[h];++h)bj(e[h],g[h])}if(b){bi(a,d);if(c){e=bk(a),g=bk(d);for(h=0;e[h];++h)bi(e[h],g[h])}}return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||
+b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bb.test(k))k=b.createTextNode(k);else{k=k.replace($,"<$1></$2>");var l=(_.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=ba.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Z.test(k)&&o.insertBefore(b.createTextNode(Z.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bm(k[i]);else bm(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bo=/alpha\([^)]*\)/i,bp=/opacity=([^)]*)/,bq=/-([a-z])/ig,br=/([A-Z]|^ms)/g,bs=/^-?\d+(?:px)?$/i,bt=/^-?\d/,bu=/^[+\-]=/,bv=/[^+\-\.\de]+/g,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB,bC=function(a,b){return b.toUpperCase()};f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0,widows:!0,orphans:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d;if(h==="number"&&isNaN(d)||d==null)return;h==="string"&&bu.test(d)&&(d=+d.replace(bv,"")+parseFloat(f.css(a,c))),h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bq,bC)}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){a.offsetWidth!==0?e=bD(a,b,d):f.swap(a,bw,function(){e=bD(a,b,d)});if(e<=0){e=bz(a,b,b),e==="0px"&&bB&&(e=bB(a,b,b));if(e!=null)return e===""||e==="auto"?"0px":e}if(e<0||e==null){e=a.style[b];return e===""||e==="auto"?"0px":e}return typeof e=="string"?e:e+"px"}},set:function(a,b){if(!bs.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bp.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bo.test(g)?g.replace(bo,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,c){var d,e,g;c=c.replace(br,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bs.test(d)&&bt.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bE=/%20/g,bF=/\[\]$/,bG=/\r?\n/g,bH=/#.*$/,bI=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bJ=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bK=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bL=/^(?:GET|HEAD)$/,bM=/^\/\//,bN=/\?/,bO=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bP=/^(?:select|textarea)/i,bQ=/\s+/,bR=/([?&])_=[^&]*/,bS=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bT=f.fn.load,bU={},bV={},bW,bX;try{bW=e.href}catch(bY){bW=c.createElement("a"),bW.href="",bW=bW.href}bX=bS.exec(bW.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bT)return bT.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bO,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bP.test(this.nodeName)||bJ.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bG,"\r\n")}}):{name:b.name,value:c.replace(bG,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bW,isLocal:bK.test(bX[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bZ(bU),ajaxTransport:bZ(bV),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?ca(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=cb(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bI.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bH,"").replace(bM,bX[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bQ),d.crossDomain==null&&(r=bS.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bX[1]&&r[2]==bX[2]&&(r[3]||(r[1]==="http:"?80:443))==(bX[3]||(bX[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bU,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bL.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bN.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bR,"$1_="+x);d.url=y+(y===d.url?(bN.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bV,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bE,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq,cr=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cv(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cm.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=cn.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this),f.isFunction(d.old)&&d.old.call(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function h(a){return d.step(a)}var d=this,e=f.fx,g;this.startTime=cq||cs(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,h.elem=this.elem,h()&&f.timers.push(h)&&!co&&(cr?(co=1,g=function(){co&&(cr(g),e.tick())},cr(g)):co=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cq||cs(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){return this[0]?parseFloat(f.css(this[0],d,"padding")):null},f.fn["outer"+c]=function(a){return this[0]?parseFloat(f.css(this[0],d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.disco b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.disco
new file mode 100644
index 0000000..f8d5e5b
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.disco
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
+ <contractRef ref="http://localhost:65169/DataApi.svc?wsdl" docRef="http://localhost:65169/DataApi.svc" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
+</discovery> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.wsdl b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.wsdl
new file mode 100644
index 0000000..702762a
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.wsdl
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wsdl:definitions xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://tempuri.org/" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="DataApi" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:ProtectionToken>
+ <wsp:Policy>
+ <sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:RequireDerivedKeys />
+ <sp:BootstrapPolicy>
+ <wsp:Policy>
+ <sp:SignedParts>
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts>
+ <sp:Body />
+ </sp:EncryptedParts>
+ <sp:SymmetricBinding>
+ <wsp:Policy>
+ <sp:ProtectionToken>
+ <wsp:Policy>
+ <sp:SpnegoContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:RequireDerivedKeys />
+ </wsp:Policy>
+ </sp:SpnegoContextToken>
+ </wsp:Policy>
+ </sp:ProtectionToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Strict />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:EncryptSignature />
+ <sp:OnlySignEntireHeadersAndBody />
+ </wsp:Policy>
+ </sp:SymmetricBinding>
+ <sp:Wss11>
+ <wsp:Policy>
+ <sp:MustSupportRefKeyIdentifier />
+ <sp:MustSupportRefIssuerSerial />
+ <sp:MustSupportRefThumbprint />
+ <sp:MustSupportRefEncryptedKey />
+ </wsp:Policy>
+ </sp:Wss11>
+ <sp:Trust10>
+ <wsp:Policy>
+ <sp:MustSupportIssuedTokens />
+ <sp:RequireClientEntropy />
+ <sp:RequireServerEntropy />
+ </wsp:Policy>
+ </sp:Trust10>
+ </wsp:Policy>
+ </sp:BootstrapPolicy>
+ </wsp:Policy>
+ </sp:SecureConversationToken>
+ </wsp:Policy>
+ </sp:ProtectionToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Strict />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:EncryptSignature />
+ <sp:OnlySignEntireHeadersAndBody />
+ </wsp:Policy>
+ </sp:SymmetricBinding>
+ <sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:MustSupportRefKeyIdentifier />
+ <sp:MustSupportRefIssuerSerial />
+ <sp:MustSupportRefThumbprint />
+ <sp:MustSupportRefEncryptedKey />
+ </wsp:Policy>
+ </sp:Wss11>
+ <sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:MustSupportIssuedTokens />
+ <sp:RequireClientEntropy />
+ <sp:RequireServerEntropy />
+ </wsp:Policy>
+ </sp:Trust10>
+ <wsaw:UsingAddressing />
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetAge_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetAge_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetName_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetName_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetFavoriteSites_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetFavoriteSites_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsdl:types>
+ <xsd:schema targetNamespace="http://tempuri.org/Imports">
+ <xsd:import schemaLocation="http://localhost:65169/DataApi.svc?xsd=xsd0" namespace="http://tempuri.org/" />
+ <xsd:import schemaLocation="http://localhost:65169/DataApi.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
+ <xsd:import schemaLocation="http://localhost:65169/DataApi.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
+ </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="IDataApi_GetAge_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetAge" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetAge_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetAgeResponse" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetName_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetName" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetName_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetNameResponse" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetFavoriteSites_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetFavoriteSites" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetFavoriteSites_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetFavoriteSitesResponse" />
+ </wsdl:message>
+ <wsdl:portType name="IDataApi">
+ <wsdl:operation name="GetAge">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetAge" message="tns:IDataApi_GetAge_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetAgeResponse" message="tns:IDataApi_GetAge_OutputMessage" />
+ </wsdl:operation>
+ <wsdl:operation name="GetName">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetName" message="tns:IDataApi_GetName_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetNameResponse" message="tns:IDataApi_GetName_OutputMessage" />
+ </wsdl:operation>
+ <wsdl:operation name="GetFavoriteSites">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetFavoriteSites" message="tns:IDataApi_GetFavoriteSites_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetFavoriteSitesResponse" message="tns:IDataApi_GetFavoriteSites_OutputMessage" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="WSHttpBinding_IDataApi" type="tns:IDataApi">
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_policy" />
+ <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetAge">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetAge" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetAge_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetAge_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetName">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetName" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetName_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetName_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetFavoriteSites">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetFavoriteSites" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetFavoriteSites_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetFavoriteSites_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="DataApi">
+ <wsdl:port name="WSHttpBinding_IDataApi" binding="tns:WSHttpBinding_IDataApi">
+ <soap12:address location="http://localhost:65169/DataApi.svc" />
+ <wsa10:EndpointReference>
+ <wsa10:Address>http://localhost:65169/DataApi.svc</wsa10:Address>
+ <Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
+ <Dns>localhost</Dns>
+ </Identity>
+ </wsa10:EndpointReference>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.xsd b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.xsd
new file mode 100644
index 0000000..3109534
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi.xsd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:import schemaLocation="http://localhost:65169/DataApi.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
+ <xs:element name="GetAge">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetAgeResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="GetAgeResult" nillable="true" type="xs:int" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetName">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetNameResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="GetNameResult" nillable="true" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetFavoriteSites">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetFavoriteSitesResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="GetFavoriteSitesResult" nillable="true" type="q1:ArrayOfstring" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi1.xsd b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi1.xsd
new file mode 100644
index 0000000..d58e7f3
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi1.xsd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="anyType" nillable="true" type="xs:anyType" />
+ <xs:element name="anyURI" nillable="true" type="xs:anyURI" />
+ <xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
+ <xs:element name="boolean" nillable="true" type="xs:boolean" />
+ <xs:element name="byte" nillable="true" type="xs:byte" />
+ <xs:element name="dateTime" nillable="true" type="xs:dateTime" />
+ <xs:element name="decimal" nillable="true" type="xs:decimal" />
+ <xs:element name="double" nillable="true" type="xs:double" />
+ <xs:element name="float" nillable="true" type="xs:float" />
+ <xs:element name="int" nillable="true" type="xs:int" />
+ <xs:element name="long" nillable="true" type="xs:long" />
+ <xs:element name="QName" nillable="true" type="xs:QName" />
+ <xs:element name="short" nillable="true" type="xs:short" />
+ <xs:element name="string" nillable="true" type="xs:string" />
+ <xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
+ <xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
+ <xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
+ <xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
+ <xs:element name="char" nillable="true" type="tns:char" />
+ <xs:simpleType name="char">
+ <xs:restriction base="xs:int" />
+ </xs:simpleType>
+ <xs:element name="duration" nillable="true" type="tns:duration" />
+ <xs:simpleType name="duration">
+ <xs:restriction base="xs:duration">
+ <xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
+ <xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
+ <xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="guid" nillable="true" type="tns:guid" />
+ <xs:simpleType name="guid">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:attribute name="FactoryType" type="xs:QName" />
+ <xs:attribute name="Id" type="xs:ID" />
+ <xs:attribute name="Ref" type="xs:IDREF" />
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi2.xsd b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi2.xsd
new file mode 100644
index 0000000..04a74a4
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/DataApi2.xsd
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType name="ArrayOfstring">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="ArrayOfstring" nillable="true" type="tns:ArrayOfstring" />
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/Reference.cs b/src/OAuth/OAuthClient/Service References/SampleResourceServer/Reference.cs
new file mode 100644
index 0000000..02fc057
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/Reference.cs
@@ -0,0 +1,67 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.17379
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient.SampleResourceServer {
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ [System.ServiceModel.ServiceContractAttribute(ConfigurationName="SampleResourceServer.IDataApi")]
+ public interface IDataApi {
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetAge", ReplyAction="http://tempuri.org/IDataApi/GetAgeResponse")]
+ System.Nullable<int> GetAge();
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetName", ReplyAction="http://tempuri.org/IDataApi/GetNameResponse")]
+ string GetName();
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetFavoriteSites", ReplyAction="http://tempuri.org/IDataApi/GetFavoriteSitesResponse")]
+ string[] GetFavoriteSites();
+ }
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ public interface IDataApiChannel : OAuthClient.SampleResourceServer.IDataApi, System.ServiceModel.IClientChannel {
+ }
+
+ [System.Diagnostics.DebuggerStepThroughAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ public partial class DataApiClient : System.ServiceModel.ClientBase<OAuthClient.SampleResourceServer.IDataApi>, OAuthClient.SampleResourceServer.IDataApi {
+
+ public DataApiClient() {
+ }
+
+ public DataApiClient(string endpointConfigurationName) :
+ base(endpointConfigurationName) {
+ }
+
+ public DataApiClient(string endpointConfigurationName, string remoteAddress) :
+ base(endpointConfigurationName, remoteAddress) {
+ }
+
+ public DataApiClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
+ base(endpointConfigurationName, remoteAddress) {
+ }
+
+ public DataApiClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
+ base(binding, remoteAddress) {
+ }
+
+ public System.Nullable<int> GetAge() {
+ return base.Channel.GetAge();
+ }
+
+ public string GetName() {
+ return base.Channel.GetName();
+ }
+
+ public string[] GetFavoriteSites() {
+ return base.Channel.GetFavoriteSites();
+ }
+ }
+}
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/Reference.svcmap b/src/OAuth/OAuthClient/Service References/SampleResourceServer/Reference.svcmap
new file mode 100644
index 0000000..4463f99
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/Reference.svcmap
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ReferenceGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="41652b7a-0e9d-40be-8e75-8ccd843850c4" xmlns="urn:schemas-microsoft-com:xml-wcfservicemap">
+ <ClientOptions>
+ <GenerateAsynchronousMethods>false</GenerateAsynchronousMethods>
+ <EnableDataBinding>true</EnableDataBinding>
+ <ExcludedTypes />
+ <ImportXmlTypes>false</ImportXmlTypes>
+ <GenerateInternalTypes>false</GenerateInternalTypes>
+ <GenerateMessageContracts>false</GenerateMessageContracts>
+ <NamespaceMappings />
+ <CollectionMappings />
+ <GenerateSerializableTypes>true</GenerateSerializableTypes>
+ <Serializer>Auto</Serializer>
+ <UseSerializerForFaults>true</UseSerializerForFaults>
+ <ReferenceAllAssemblies>true</ReferenceAllAssemblies>
+ <ReferencedAssemblies />
+ <ReferencedDataContractTypes />
+ <ServiceContractMappings />
+ </ClientOptions>
+ <MetadataSources>
+ <MetadataSource Address="http://localhost:65169/DataApi.svc" Protocol="http" SourceId="1" />
+ </MetadataSources>
+ <Metadata>
+ <MetadataFile FileName="DataApi.xsd" MetadataType="Schema" ID="82a34da8-d721-4c35-aaf9-fc5d08771cd2" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?xsd=xsd0" />
+ <MetadataFile FileName="DataApi.wsdl" MetadataType="Wsdl" ID="96350220-1df2-429e-8cb5-4fc33703bcc7" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?wsdl" />
+ <MetadataFile FileName="DataApi.disco" MetadataType="Disco" ID="c4f66dee-ac01-4476-afb0-34f7350c06ad" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?disco" />
+ <MetadataFile FileName="DataApi1.xsd" MetadataType="Schema" ID="7aaf262f-6342-421b-8f44-0e624be7a5fb" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?xsd=xsd1" />
+ <MetadataFile FileName="DataApi2.xsd" MetadataType="Schema" ID="67c1ea8d-12c4-4a0c-aa33-7226018cf16e" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?xsd=xsd2" />
+ </Metadata>
+ <Extensions>
+ <ExtensionFile FileName="configuration91.svcinfo" Name="configuration91.svcinfo" />
+ <ExtensionFile FileName="configuration.svcinfo" Name="configuration.svcinfo" />
+ </Extensions>
+</ReferenceGroup> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/configuration.svcinfo b/src/OAuth/OAuthClient/Service References/SampleResourceServer/configuration.svcinfo
new file mode 100644
index 0000000..c21c2f6
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/configuration.svcinfo
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configurationSnapshot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:schemas-microsoft-com:xml-wcfconfigurationsnapshot">
+ <behaviors />
+ <bindings>
+ <binding digest="System.ServiceModel.Configuration.WSHttpBindingElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data hostNameComparisonMode=&quot;StrongWildcard&quot; messageEncoding=&quot;Text&quot; name=&quot;WSHttpBinding_IDataApi&quot; textEncoding=&quot;utf-8&quot; transactionFlow=&quot;false&quot;&gt;&lt;readerQuotas maxArrayLength=&quot;16384&quot; maxBytesPerRead=&quot;4096&quot; maxDepth=&quot;32&quot; maxNameTableCharCount=&quot;16384&quot; maxStringContentLength=&quot;8192&quot; /&gt;&lt;reliableSession enabled=&quot;false&quot; inactivityTimeout=&quot;00:10:00&quot; ordered=&quot;true&quot; /&gt;&lt;security mode=&quot;Message&quot;&gt;&lt;message algorithmSuite=&quot;Default&quot; clientCredentialType=&quot;Windows&quot; negotiateServiceCredential=&quot;true&quot; /&gt;&lt;transport clientCredentialType=&quot;Windows&quot; proxyCredentialType=&quot;None&quot; realm=&quot;&quot; /&gt;&lt;/security&gt;&lt;/Data&gt;" bindingType="wsHttpBinding" name="WSHttpBinding_IDataApi" />
+ </bindings>
+ <endpoints>
+ <endpoint normalizedDigest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://localhost:65169/DataApi.svc&quot; binding=&quot;wsHttpBinding&quot; bindingConfiguration=&quot;WSHttpBinding_IDataApi&quot; contract=&quot;SampleResourceServer.IDataApi&quot; name=&quot;WSHttpBinding_IDataApi&quot;&gt;&lt;identity&gt;&lt;dns value=&quot;localhost&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" digest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://localhost:65169/DataApi.svc&quot; binding=&quot;wsHttpBinding&quot; bindingConfiguration=&quot;WSHttpBinding_IDataApi&quot; contract=&quot;SampleResourceServer.IDataApi&quot; name=&quot;WSHttpBinding_IDataApi&quot;&gt;&lt;identity&gt;&lt;dns value=&quot;localhost&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" contractName="SampleResourceServer.IDataApi" name="WSHttpBinding_IDataApi" />
+ </endpoints>
+</configurationSnapshot> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Service References/SampleResourceServer/configuration91.svcinfo b/src/OAuth/OAuthClient/Service References/SampleResourceServer/configuration91.svcinfo
new file mode 100644
index 0000000..3dd0d1a
--- /dev/null
+++ b/src/OAuth/OAuthClient/Service References/SampleResourceServer/configuration91.svcinfo
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="utf-8"?>
+<SavedWcfConfigurationInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="9.1" CheckSum="Go5YjnH8CtVcll2vFbhXoqBKm/A=">
+ <bindingConfigurations>
+ <bindingConfiguration bindingType="wsHttpBinding" name="WSHttpBinding_IDataApi">
+ <properties>
+ <property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi</serializedValue>
+ </property>
+ <property path="/closeTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/openTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/receiveTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:10:00</serializedValue>
+ </property>
+ <property path="/sendTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/bypassProxyOnLocal" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/transactionFlow" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/hostNameComparisonMode" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HostNameComparisonMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>StrongWildcard</serializedValue>
+ </property>
+ <property path="/maxBufferPoolSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>524288</serializedValue>
+ </property>
+ <property path="/maxReceivedMessageSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>65536</serializedValue>
+ </property>
+ <property path="/messageEncoding" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.WSMessageEncoding, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Text</serializedValue>
+ </property>
+ <property path="/proxyAddress" isComplexType="false" isExplicitlyDefined="false" clrType="System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/readerQuotas" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxDepth" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>32</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxStringContentLength" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>8192</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxArrayLength" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>16384</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxBytesPerRead" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>4096</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxNameTableCharCount" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>16384</serializedValue>
+ </property>
+ <property path="/reliableSession" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.StandardBindingOptionalReliableSessionElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.StandardBindingOptionalReliableSessionElement</serializedValue>
+ </property>
+ <property path="/reliableSession/ordered" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/reliableSession/inactivityTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:10:00</serializedValue>
+ </property>
+ <property path="/reliableSession/enabled" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/textEncoding" isComplexType="false" isExplicitlyDefined="true" clrType="System.Text.Encoding, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.Text.UTF8Encoding</serializedValue>
+ </property>
+ <property path="/useDefaultWebProxy" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/allowCookies" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/security" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.WSHttpSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.WSHttpSecurityElement</serializedValue>
+ </property>
+ <property path="/security/mode" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.SecurityMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Message</serializedValue>
+ </property>
+ <property path="/security/transport" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.WSHttpTransportSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.WSHttpTransportSecurityElement</serializedValue>
+ </property>
+ <property path="/security/transport/clientCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HttpClientCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Windows</serializedValue>
+ </property>
+ <property path="/security/transport/proxyCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HttpProxyCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>None</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/policyEnforcement" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.PolicyEnforcement, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Never</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/protectionScenario" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.ProtectionScenario, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>TransportSelected</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/customServiceNames" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ServiceNameElementCollection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>(Collection)</serializedValue>
+ </property>
+ <property path="/security/transport/realm" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/security/message" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.NonDualMessageSecurityOverHttpElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.NonDualMessageSecurityOverHttpElement</serializedValue>
+ </property>
+ <property path="/security/message/clientCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.MessageCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Windows</serializedValue>
+ </property>
+ <property path="/security/message/negotiateServiceCredential" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/security/message/algorithmSuite" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.Security.SecurityAlgorithmSuite, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Default</serializedValue>
+ </property>
+ <property path="/security/message/establishSecurityContext" isComplexType="false" isExplicitlyDefined="false" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ </properties>
+ </bindingConfiguration>
+ </bindingConfigurations>
+ <endpoints>
+ <endpoint name="WSHttpBinding_IDataApi" contract="SampleResourceServer.IDataApi" bindingType="wsHttpBinding" address="http://localhost:65169/DataApi.svc" bindingConfiguration="WSHttpBinding_IDataApi">
+ <properties>
+ <property path="/address" isComplexType="false" isExplicitlyDefined="true" clrType="System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>http://localhost:65169/DataApi.svc</serializedValue>
+ </property>
+ <property path="/behaviorConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/binding" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>wsHttpBinding</serializedValue>
+ </property>
+ <property path="/bindingConfiguration" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi</serializedValue>
+ </property>
+ <property path="/contract" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>SampleResourceServer.IDataApi</serializedValue>
+ </property>
+ <property path="/headers" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.AddressHeaderCollectionElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.AddressHeaderCollectionElement</serializedValue>
+ </property>
+ <property path="/headers/headers" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.Channels.AddressHeaderCollection, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>&lt;Header /&gt;</serializedValue>
+ </property>
+ <property path="/identity" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.IdentityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.IdentityElement</serializedValue>
+ </property>
+ <property path="/identity/userPrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.UserPrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.UserPrincipalNameElement</serializedValue>
+ </property>
+ <property path="/identity/userPrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/servicePrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.ServicePrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.ServicePrincipalNameElement</serializedValue>
+ </property>
+ <property path="/identity/servicePrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/dns" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.DnsElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.DnsElement</serializedValue>
+ </property>
+ <property path="/identity/dns/value" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>localhost</serializedValue>
+ </property>
+ <property path="/identity/rsa" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.RsaElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.RsaElement</serializedValue>
+ </property>
+ <property path="/identity/rsa/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificate" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.CertificateElement</serializedValue>
+ </property>
+ <property path="/identity/certificate/encodedValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificateReference" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateReferenceElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.CertificateReferenceElement</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/storeName" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreName, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>My</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/storeLocation" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreLocation, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>LocalMachine</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/x509FindType" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.X509FindType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>FindBySubjectDistinguishedName</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/findValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificateReference/isChainIncluded" isComplexType="false" isExplicitlyDefined="false" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi</serializedValue>
+ </property>
+ <property path="/kind" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/endpointConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ </properties>
+ </endpoint>
+ </endpoints>
+</SavedWcfConfigurationInformation> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Settings.StyleCop b/src/OAuth/OAuthClient/Settings.StyleCop
new file mode 100644
index 0000000..7f55ce6
--- /dev/null
+++ b/src/OAuth/OAuthClient/Settings.StyleCop
@@ -0,0 +1 @@
+<StyleCopSettings Version="4.3" /> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/SignInWithTwitter.aspx b/src/OAuth/OAuthClient/SignInWithTwitter.aspx
new file mode 100644
index 0000000..9fda5c1
--- /dev/null
+++ b/src/OAuth/OAuthClient/SignInWithTwitter.aspx
@@ -0,0 +1,38 @@
+<%@ Page Language="C#" AutoEventWireup="true"
+ Inherits="OAuthClient.SignInWithTwitter" Codebehind="SignInWithTwitter.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>Sign-in with Twitter</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View ID="View1" runat="server">
+ <h2>
+ Twitter setup</h2>
+ <p>
+ A Twitter client app must be endorsed by a Twitter user.
+ </p>
+ <ol>
+ <li><a target="_blank" href="https://twitter.com/oauth_clients">Visit Twitter and create
+ a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.</li>
+ </ol>
+ </asp:View>
+ <asp:View ID="View2" runat="server">
+ <asp:ImageButton ImageUrl="~/images/Sign-in-with-Twitter-darker.png" runat="server"
+ AlternateText="Sign In With Twitter" ID="signInButton" OnClick="signInButton_Click" />
+ <asp:CheckBox Text="force re-login" runat="server" ID="forceLoginCheckbox" />
+ <br />
+ <asp:Panel runat="server" ID="loggedInPanel" Visible="false">
+ Now logged in as
+ <asp:Label Text="[name]" runat="server" ID="loggedInName" />
+ </asp:Panel>
+ </asp:View>
+ </asp:MultiView>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthClient/SignInWithTwitter.aspx.cs b/src/OAuth/OAuthClient/SignInWithTwitter.aspx.cs
new file mode 100644
index 0000000..04b302c
--- /dev/null
+++ b/src/OAuth/OAuthClient/SignInWithTwitter.aspx.cs
@@ -0,0 +1,39 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Security;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using System.Xml.Linq;
+ using System.Xml.XPath;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuth;
+
+ public partial class SignInWithTwitter : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ if (TwitterConsumer.IsTwitterConsumerConfigured) {
+ this.MultiView1.ActiveViewIndex = 1;
+
+ if (!IsPostBack) {
+ string screenName;
+ int userId;
+ if (TwitterConsumer.TryFinishSignInWithTwitter(out screenName, out userId)) {
+ this.loggedInPanel.Visible = true;
+ this.loggedInName.Text = screenName;
+
+ // In a real app, the Twitter username would likely be used
+ // to log the user into the application.
+ ////FormsAuthentication.RedirectFromLoginPage(screenName, false);
+ }
+ }
+ }
+ }
+
+ protected void signInButton_Click(object sender, ImageClickEventArgs e) {
+ TwitterConsumer.StartSignInWithTwitter(this.forceLoginCheckbox.Checked).Send();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/SignInWithTwitter.aspx.designer.cs b/src/OAuth/OAuthClient/SignInWithTwitter.aspx.designer.cs
new file mode 100644
index 0000000..00126de
--- /dev/null
+++ b/src/OAuth/OAuthClient/SignInWithTwitter.aspx.designer.cs
@@ -0,0 +1,87 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient {
+
+
+ public partial class SignInWithTwitter {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+
+ /// <summary>
+ /// View2 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View2;
+
+ /// <summary>
+ /// signInButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.ImageButton signInButton;
+
+ /// <summary>
+ /// forceLoginCheckbox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CheckBox forceLoginCheckbox;
+
+ /// <summary>
+ /// loggedInPanel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel loggedInPanel;
+
+ /// <summary>
+ /// loggedInName control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label loggedInName;
+ }
+}
diff --git a/src/OAuth/OAuthClient/TracePage.aspx b/src/OAuth/OAuthClient/TracePage.aspx
new file mode 100644
index 0000000..89c3ab6
--- /dev/null
+++ b/src/OAuth/OAuthClient/TracePage.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OAuthClient.TracePage" Codebehind="TracePage.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <p align="right">
+ <asp:Button runat="server" Text="Clear log" ID="clearLogButton" OnClick="clearLogButton_Click" />
+ </p>
+ <pre>
+ <asp:PlaceHolder runat="server" ID="placeHolder1" />
+ </pre>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthClient/TracePage.aspx.cs b/src/OAuth/OAuthClient/TracePage.aspx.cs
new file mode 100644
index 0000000..658c276
--- /dev/null
+++ b/src/OAuth/OAuthClient/TracePage.aspx.cs
@@ -0,0 +1,23 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ /// <summary>
+ /// A page to display recent log messages.
+ /// </summary>
+ public partial class TracePage : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.placeHolder1.Controls.Add(new Label { Text = HttpUtility.HtmlEncode(Logging.LogMessages.ToString()) });
+ }
+
+ protected void clearLogButton_Click(object sender, EventArgs e) {
+ Logging.LogMessages.Length = 0;
+
+ // clear the page immediately, and allow for F5 without a Postback warning.
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/TracePage.aspx.designer.cs b/src/OAuth/OAuthClient/TracePage.aspx.designer.cs
new file mode 100644
index 0000000..7db570b
--- /dev/null
+++ b/src/OAuth/OAuthClient/TracePage.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient {
+
+
+ public partial class TracePage {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// clearLogButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button clearLogButton;
+
+ /// <summary>
+ /// placeHolder1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder placeHolder1;
+ }
+}
diff --git a/src/OAuth/OAuthClient/Twitter.aspx b/src/OAuth/OAuthClient/Twitter.aspx
new file mode 100644
index 0000000..cb60851
--- /dev/null
+++ b/src/OAuth/OAuthClient/Twitter.aspx
@@ -0,0 +1,35 @@
+<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthClient.Twitter" Codebehind="Twitter.aspx.cs" %>
+
+<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
+</asp:Content>
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View ID="View1" runat="server">
+ <h2>Twitter setup</h2>
+ <p>A Twitter client app must be endorsed by a Twitter user. </p>
+ <ol>
+ <li><a target="_blank" href="https://twitter.com/oauth_clients">Visit Twitter and create
+ a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.</li>
+ </ol>
+ </asp:View>
+ <asp:View runat="server">
+ <h2>Updates</h2>
+ <p>Ok, Twitter has authorized us to download your feeds. Notice how we never asked
+ you for your Twitter username or password. </p>
+ <p>
+ Upload a new profile photo:
+ <asp:FileUpload ID="profilePhoto" runat="server" />
+ &nbsp;<asp:Button ID="uploadProfilePhotoButton" runat="server"
+ onclick="uploadProfilePhotoButton_Click" Text="Upload photo" />
+ &nbsp;<asp:Label ID="photoUploadedLabel" runat="server" EnableViewState="False"
+ Text="Done!" Visible="False"></asp:Label>
+ </p>
+ <p>
+ Click &#39;Get updates&#39; to download updates to this sample.
+ </p>
+ <asp:Button ID="downloadUpdates" runat="server" Text="Get updates" OnClick="downloadUpdates_Click" />
+ <asp:PlaceHolder runat="server" ID="resultsPlaceholder" />
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthClient/Twitter.aspx.cs b/src/OAuth/OAuthClient/Twitter.aspx.cs
new file mode 100644
index 0000000..9c0cb9a
--- /dev/null
+++ b/src/OAuth/OAuthClient/Twitter.aspx.cs
@@ -0,0 +1,96 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using System.Xml.Linq;
+ using System.Xml.XPath;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuth;
+
+ public partial class Twitter : System.Web.UI.Page {
+ private string AccessToken {
+ get { return (string)Session["TwitterAccessToken"]; }
+ set { Session["TwitterAccessToken"] = value; }
+ }
+
+ private InMemoryTokenManager TokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)Application["TwitterTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
+ if (!string.IsNullOrEmpty(consumerKey)) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Application["TwitterTokenManager"] = tokenManager;
+ }
+ }
+
+ return tokenManager;
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (this.TokenManager != null) {
+ this.MultiView1.ActiveViewIndex = 1;
+
+ if (!IsPostBack) {
+ var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
+
+ // Is Twitter calling back with authorization?
+ var accessTokenResponse = twitter.ProcessUserAuthorization();
+ if (accessTokenResponse != null) {
+ this.AccessToken = accessTokenResponse.AccessToken;
+ } else if (this.AccessToken == null) {
+ // If we don't yet have access, immediately request it.
+ twitter.Channel.Send(twitter.PrepareRequestUserAuthorization());
+ }
+ }
+ }
+ }
+
+ protected void downloadUpdates_Click(object sender, EventArgs e) {
+ var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
+ XPathDocument updates = new XPathDocument(TwitterConsumer.GetUpdates(twitter, this.AccessToken).CreateReader());
+ XPathNavigator nav = updates.CreateNavigator();
+ var parsedUpdates = from status in nav.Select("/statuses/status").OfType<XPathNavigator>()
+ where !status.SelectSingleNode("user/protected").ValueAsBoolean
+ select new {
+ User = status.SelectSingleNode("user/name").InnerXml,
+ Status = status.SelectSingleNode("text").InnerXml,
+ };
+
+ StringBuilder tableBuilder = new StringBuilder();
+ tableBuilder.Append("<table><tr><td>Name</td><td>Update</td></tr>");
+
+ foreach (var update in parsedUpdates) {
+ tableBuilder.AppendFormat(
+ "<tr><td>{0}</td><td>{1}</td></tr>",
+ HttpUtility.HtmlEncode(update.User),
+ HttpUtility.HtmlEncode(update.Status));
+ }
+ tableBuilder.Append("</table>");
+ this.resultsPlaceholder.Controls.Add(new Literal { Text = tableBuilder.ToString() });
+ }
+
+ protected void uploadProfilePhotoButton_Click(object sender, EventArgs e) {
+ if (this.profilePhoto.PostedFile.ContentType == null) {
+ this.photoUploadedLabel.Visible = true;
+ this.photoUploadedLabel.Text = "Select a file first.";
+ return;
+ }
+
+ var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
+ XDocument imageResult = TwitterConsumer.UpdateProfileImage(
+ twitter,
+ this.AccessToken,
+ this.profilePhoto.PostedFile.InputStream,
+ this.profilePhoto.PostedFile.ContentType);
+ this.photoUploadedLabel.Visible = true;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Twitter.aspx.designer.cs b/src/OAuth/OAuthClient/Twitter.aspx.designer.cs
new file mode 100644
index 0000000..e82f477
--- /dev/null
+++ b/src/OAuth/OAuthClient/Twitter.aspx.designer.cs
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient {
+
+
+ public partial class Twitter {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+
+ /// <summary>
+ /// profilePhoto control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.FileUpload profilePhoto;
+
+ /// <summary>
+ /// uploadProfilePhotoButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button uploadProfilePhotoButton;
+
+ /// <summary>
+ /// photoUploadedLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label photoUploadedLabel;
+
+ /// <summary>
+ /// downloadUpdates control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button downloadUpdates;
+
+ /// <summary>
+ /// resultsPlaceholder control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder resultsPlaceholder;
+ }
+}
diff --git a/src/OAuth/OAuthClient/Web.config b/src/OAuth/OAuthClient/Web.config
new file mode 100644
index 0000000..0e5ed14
--- /dev/null
+++ b/src/OAuth/OAuthClient/Web.config
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false" />
+ <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+ <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" />
+ <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" />
+ <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ </sectionGroup>
+ </configSections>
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <uri>
+ <idn enabled="All" />
+ <iriParsing enabled="true" />
+ </uri>
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <dotNetOpenAuth>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true" />
+ <!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. -->
+ <messaging relaxSslRequirements="true">
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
+ <!--<add name="localhost" />-->
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ <openid />
+ </dotNetOpenAuth>
+ <appSettings>
+ <!-- Fill in your various consumer keys and secrets here to make the sample work. -->
+ <!-- You must get these values by signing up with each individual service provider. -->
+ <!-- Twitter sign-up: https://twitter.com/oauth_clients -->
+ <add key="twitterConsumerKey" value="eRJd2AMcOnGqDOtF3IrBQ" />
+ <add key="twitterConsumerSecret" value="iTijQWFOSDokpkVIPnlLbdmf3wPZgUVqktXKASg0QjM" />
+ <!-- Google sign-up: https://www.google.com/accounts/ManageDomains -->
+ <add key="googleConsumerKey" value="anonymous" />
+ <add key="googleConsumerSecret" value="anonymous" />
+ <!-- Yammer sign-up: https://www.yammer.com/client_applications/new -->
+ <add key="yammerConsumerKey" value="" />
+ <add key="yammerConsumerSecret" value="" />
+ <!-- Facebook sign-up: http://developers.facebook.com/setup/ -->
+ <add key="facebookAppID" value="367207604173" />
+ <add key="facebookAppSecret" value="1df77e64055c4d7d3583cefdf2bc62d7" />
+ <!-- Windows Live sign-up: http://go.microsoft.com/fwlink/p/?LinkId=193157 -->
+ <add key="windowsLiveAppID" value="000000004408E558" />
+ <add key="windowsLiveAppSecret" value="od8NVdanEIWqmlKu9hOepBE3AfUu4jCw" />
+ </appSettings>
+ <connectionStrings />
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true" targetFramework="4.0">
+ <assemblies>
+ <remove assembly="DotNetOpenAuth.Contracts" />
+ </assemblies>
+ </compilation>
+ <!--
+ The <authentication> section enables configuration
+ of the security authentication mode used by
+ ASP.NET to identify an incoming user.
+ -->
+ <authentication mode="Windows" />
+ <!--
+ The <customErrors> section enables configuration
+ of what to do if/when an unhandled error occurs
+ during the execution of a request. Specifically,
+ it enables developers to configure html error pages
+ to be displayed in place of a error stack trace.
+
+ <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
+ <error statusCode="403" redirect="NoAccess.htm" />
+ <error statusCode="404" redirect="FileNotFound.htm" />
+ </customErrors>
+ -->
+ <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
+ </system.web>
+ <!--
+ The system.webServer section is required for running ASP.NET AJAX under Internet
+ Information Services 7.0. It is not necessary for previous version of IIS.
+ -->
+ <runtime>
+ <legacyHMACWarning enabled="0" />
+ </runtime>
+ <log4net>
+ <appender name="TracePageAppender" type="OAuthClient.TracePageAppender, OAuthClient">
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline" />
+ </layout>
+ </appender>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO" />
+ <!--<appender-ref ref="RollingFileAppender" />-->
+ <appender-ref ref="TracePageAppender" />
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="ALL" />
+ </logger>
+ </log4net>
+ <system.serviceModel>
+ <bindings>
+ <wsHttpBinding>
+ <binding name="WSHttpBinding_IDataApi" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+ <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
+ <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
+ <security mode="Message">
+ <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
+ <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" />
+ </security>
+ </binding>
+ </wsHttpBinding>
+ </bindings>
+ <client>
+ <endpoint address="http://localhost:65169/DataApi.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDataApi" contract="SampleResourceServer.IDataApi" name="WSHttpBinding_IDataApi">
+ <identity>
+ <dns value="localhost" />
+ </identity>
+ </endpoint>
+ </client>
+ </system.serviceModel>
+</configuration> \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/WindowsLive.aspx b/src/OAuth/OAuthClient/WindowsLive.aspx
new file mode 100644
index 0000000..5b8c8d4
--- /dev/null
+++ b/src/OAuth/OAuthClient/WindowsLive.aspx
@@ -0,0 +1,29 @@
+<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WindowsLive.aspx.cs" Inherits="OAuthClient.WindowsLive" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <asp:Panel runat="server" ID="localhostDoesNotWorkPanel" Visible="False">
+ <p>
+ Windows Live requires a public domain (not localhost) that matches the registered
+ client app's callback URL. You can either host this sample on a public URL and register
+ your own client, or you can modify your "%windows%\system32\drivers\etc\hosts" file
+ to temporarily add this entry:
+ </p>
+ <pre>127.0.0.1 samples.dotnetopenauth.net</pre>
+ <p>
+ Then access this sample via this url:
+ <asp:HyperLink ID="publicLink" NavigateUrl="http://samples.dotnetopenauth.net:59721/WindowsLive.aspx"
+ runat="server">http://samples.dotnetopenauth.net:59721/WindowsLive.aspx</asp:HyperLink></p>
+ </asp:Panel>
+ <div>
+ Welcome,
+ <asp:Label Text="[name]" ID="nameLabel" runat="server" />
+ </div>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthClient/WindowsLive.aspx.cs b/src/OAuth/OAuthClient/WindowsLive.aspx.cs
new file mode 100644
index 0000000..b550e17
--- /dev/null
+++ b/src/OAuth/OAuthClient/WindowsLive.aspx.cs
@@ -0,0 +1,45 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Net;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.ApplicationBlock.Facebook;
+ using DotNetOpenAuth.OAuth2;
+
+ public partial class WindowsLive : System.Web.UI.Page {
+ private static readonly WindowsLiveClient client = new WindowsLiveClient {
+ ClientIdentifier = ConfigurationManager.AppSettings["windowsLiveAppID"],
+ ClientSecret = ConfigurationManager.AppSettings["WindowsLiveAppSecret"],
+ };
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (string.Equals("localhost", this.Request.Headers["Host"].Split(':')[0], StringComparison.OrdinalIgnoreCase)) {
+ this.localhostDoesNotWorkPanel.Visible = true;
+ var builder = new UriBuilder(this.publicLink.NavigateUrl);
+ builder.Port = this.Request.Url.Port;
+ this.publicLink.NavigateUrl = builder.Uri.AbsoluteUri;
+ this.publicLink.Text = builder.Uri.AbsoluteUri;
+ } else {
+ IAuthorizationState authorization = client.ProcessUserAuthorization();
+ if (authorization == null) {
+ // Kick off authorization request
+ client.RequestUserAuthorization(scope: new[] { WindowsLiveClient.Scopes.Basic }); // this scope isn't even required just to log in
+ } else {
+ var request =
+ WebRequest.Create("https://apis.live.net/v5.0/me?access_token=" + Uri.EscapeDataString(authorization.AccessToken));
+ using (var response = request.GetResponse()) {
+ using (var responseStream = response.GetResponseStream()) {
+ var graph = WindowsLiveGraph.Deserialize(responseStream);
+ this.nameLabel.Text = HttpUtility.HtmlEncode(graph.Name);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/OAuth/OAuthClient/WindowsLive.aspx.designer.cs b/src/OAuth/OAuthClient/WindowsLive.aspx.designer.cs
new file mode 100644
index 0000000..aa47128
--- /dev/null
+++ b/src/OAuth/OAuthClient/WindowsLive.aspx.designer.cs
@@ -0,0 +1,51 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient {
+
+
+ public partial class WindowsLive {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// localhostDoesNotWorkPanel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel localhostDoesNotWorkPanel;
+
+ /// <summary>
+ /// publicLink control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.HyperLink publicLink;
+
+ /// <summary>
+ /// nameLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label nameLabel;
+ }
+}
diff --git a/src/OAuth/OAuthClient/Yammer.aspx b/src/OAuth/OAuthClient/Yammer.aspx
new file mode 100644
index 0000000..a900a2e
--- /dev/null
+++ b/src/OAuth/OAuthClient/Yammer.aspx
@@ -0,0 +1,48 @@
+<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/MasterPage.master"
+ CodeBehind="Yammer.aspx.cs" Inherits="OAuthClient.Yammer" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View ID="ClientRegistrationRequiredView" runat="server">
+ <h2>
+ Yammer setup</h2>
+ <p>
+ A Yammer client app must be registered.
+ </p>
+ <ol>
+ <li><a target="_blank" href="https://www.yammer.com/client_applications/new">Visit Yammer
+ and register a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.
+ </li>
+ </ol>
+ </asp:View>
+ <asp:View ID="BeginAuthorizationView" runat="server">
+ <asp:Label Text="An error occurred in authorization. You may try again." EnableViewState="false" Visible="false" ForeColor="Red" ID="authorizationErrorLabel" runat="server" />
+ <asp:Button Text="Obtain authorization now" runat="server" ID="obtainAuthorizationButton"
+ OnClick="obtainAuthorizationButton_Click" />
+ </asp:View>
+ <asp:View ID="CompleteAuthorizationView" runat="server">
+ After you have authorized Yammer to share your information, please enter the code
+ Yammer gives you here:
+ <asp:TextBox runat="server" ID="yammerUserCode" EnableViewState="false" />
+ <asp:RequiredFieldValidator ErrorMessage="*" ControlToValidate="yammerUserCode" runat="server" />
+ <asp:Button Text="Finish" runat="server" ID="finishAuthorizationButton" OnClick="finishAuthorizationButton_Click" />
+ </asp:View>
+ <asp:View ID="AuthorizationCompleteView" runat="server">
+ <h2>
+ Updates
+ </h2>
+ <p>The access token we have obtained is:
+ <asp:Label ID="accessTokenLabel" runat="server" />
+ </p>
+ <p>
+ Ok, Yammer has authorized us to download your messages. Click &#39;Get messages&#39;
+ to download the latest few messages to this sample. Notice how we never asked you
+ for your Yammer username or password.
+ </p>
+ <asp:Button ID="getYammerMessagesButton" runat="server" OnClick="getYammerMessages_Click"
+ Text="Get address book" />
+ <asp:PlaceHolder ID="resultsPlaceholder" runat="server" />
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthClient/Yammer.aspx.cs b/src/OAuth/OAuthClient/Yammer.aspx.cs
new file mode 100644
index 0000000..2e87a62
--- /dev/null
+++ b/src/OAuth/OAuthClient/Yammer.aspx.cs
@@ -0,0 +1,76 @@
+namespace OAuthClient {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+
+ public partial class Yammer : System.Web.UI.Page {
+ private string RequestToken {
+ get { return (string)ViewState["YammerRequestToken"]; }
+ set { ViewState["YammerRequestToken"] = value; }
+ }
+
+ private string AccessToken {
+ get { return (string)Session["YammerAccessToken"]; }
+ set { Session["YammerAccessToken"] = value; }
+ }
+
+ private InMemoryTokenManager TokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)Application["YammerTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = ConfigurationManager.AppSettings["YammerConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["YammerConsumerSecret"];
+ if (!string.IsNullOrEmpty(consumerKey)) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Application["YammerTokenManager"] = tokenManager;
+ }
+ }
+
+ return tokenManager;
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (this.TokenManager != null) {
+ this.MultiView1.SetActiveView(this.BeginAuthorizationView);
+ }
+ }
+
+ protected void getYammerMessages_Click(object sender, EventArgs e) {
+ var yammer = new WebConsumer(YammerConsumer.ServiceDescription, this.TokenManager);
+ }
+
+ protected void obtainAuthorizationButton_Click(object sender, EventArgs e) {
+ var yammer = YammerConsumer.CreateConsumer(this.TokenManager);
+ string requestToken;
+ Uri popupWindowLocation = YammerConsumer.PrepareRequestAuthorization(yammer, out requestToken);
+ this.RequestToken = requestToken;
+ string javascript = "window.open('" + popupWindowLocation.AbsoluteUri + "');";
+ this.Page.ClientScript.RegisterStartupScript(GetType(), "YammerPopup", javascript, true);
+ this.MultiView1.SetActiveView(this.CompleteAuthorizationView);
+ }
+
+ protected void finishAuthorizationButton_Click(object sender, EventArgs e) {
+ if (!Page.IsValid) {
+ return;
+ }
+
+ var yammer = YammerConsumer.CreateConsumer(this.TokenManager);
+ var authorizationResponse = YammerConsumer.CompleteAuthorization(yammer, this.RequestToken, this.yammerUserCode.Text);
+ if (authorizationResponse != null) {
+ this.accessTokenLabel.Text = HttpUtility.HtmlEncode(authorizationResponse.AccessToken);
+ this.MultiView1.SetActiveView(this.AuthorizationCompleteView);
+ } else {
+ this.MultiView1.SetActiveView(this.BeginAuthorizationView);
+ this.authorizationErrorLabel.Visible = true;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthClient/Yammer.aspx.designer.cs b/src/OAuth/OAuthClient/Yammer.aspx.designer.cs
new file mode 100644
index 0000000..84d75b8
--- /dev/null
+++ b/src/OAuth/OAuthClient/Yammer.aspx.designer.cs
@@ -0,0 +1,123 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthClient {
+
+
+ public partial class Yammer {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// ClientRegistrationRequiredView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View ClientRegistrationRequiredView;
+
+ /// <summary>
+ /// BeginAuthorizationView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View BeginAuthorizationView;
+
+ /// <summary>
+ /// authorizationErrorLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label authorizationErrorLabel;
+
+ /// <summary>
+ /// obtainAuthorizationButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button obtainAuthorizationButton;
+
+ /// <summary>
+ /// CompleteAuthorizationView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View CompleteAuthorizationView;
+
+ /// <summary>
+ /// yammerUserCode control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox yammerUserCode;
+
+ /// <summary>
+ /// finishAuthorizationButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button finishAuthorizationButton;
+
+ /// <summary>
+ /// AuthorizationCompleteView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthorizationCompleteView;
+
+ /// <summary>
+ /// accessTokenLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label accessTokenLabel;
+
+ /// <summary>
+ /// getYammerMessagesButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getYammerMessagesButton;
+
+ /// <summary>
+ /// resultsPlaceholder control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder resultsPlaceholder;
+ }
+}
diff --git a/src/OAuth/OAuthClient/favicon.ico b/src/OAuth/OAuthClient/favicon.ico
new file mode 100644
index 0000000..e227dbe
--- /dev/null
+++ b/src/OAuth/OAuthClient/favicon.ico
Binary files differ
diff --git a/src/OAuth/OAuthClient/images/Sign-in-with-Twitter-darker.png b/src/OAuth/OAuthClient/images/Sign-in-with-Twitter-darker.png
new file mode 100644
index 0000000..746b6b9
--- /dev/null
+++ b/src/OAuth/OAuthClient/images/Sign-in-with-Twitter-darker.png
Binary files differ
diff --git a/src/OAuth/OAuthClient/packages.config b/src/OAuth/OAuthClient/packages.config
new file mode 100644
index 0000000..7704415
--- /dev/null
+++ b/src/OAuth/OAuthClient/packages.config
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CodeContracts.Unofficial" version="1.0.0.2" />
+ <package id="DotNetOpenAuth.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Common" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Consumer" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.ServiceProvider" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth2.Client" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.Client" version="0.23.0-draft2" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft2" />
+ <package id="DotNetOpenAuth.OpenId.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OpenIdOAuth" version="4.0.0.12084" />
+ <package id="log4net" version="2.0.0" />
+</packages> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Code/Logging.cs b/src/OAuth/OAuthConsumer/Code/Logging.cs
new file mode 100644
index 0000000..510ea85
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Code/Logging.cs
@@ -0,0 +1,22 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+
+ /// <summary>
+ /// Logging tools for this sample.
+ /// </summary>
+ public static class Logging {
+ /// <summary>
+ /// An application memory cache of recent log messages.
+ /// </summary>
+ public static StringBuilder LogMessages = new StringBuilder();
+
+ /// <summary>
+ /// The logger for this sample to use.
+ /// </summary>
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthConsumer");
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Code/TracePageAppender.cs b/src/OAuth/OAuthConsumer/Code/TracePageAppender.cs
new file mode 100644
index 0000000..5d3ba36
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Code/TracePageAppender.cs
@@ -0,0 +1,13 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Web;
+
+ public class TracePageAppender : log4net.Appender.AppenderSkeleton {
+ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
+ StringWriter sw = new StringWriter(Logging.LogMessages);
+ Layout.Format(sw, loggingEvent);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Default.aspx b/src/OAuth/OAuthConsumer/Default.aspx
new file mode 100644
index 0000000..c952877
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Default.aspx
@@ -0,0 +1,14 @@
+<%@ Page Title="DotNetOpenAuth Consumer samples" Language="C#" MasterPageFile="~/MasterPage.master"
+ AutoEventWireup="true" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <p>OAuth allows this web site to access your private data with your authorization, but
+ without you having to give up your password. </p>
+ <p>Select a demo:</p>
+ <ul>
+ <li><a href="GoogleAddressBook.aspx">Download your Gmail address book</a></li>
+ <li><a href="Twitter.aspx">Get your Twitter updates</a></li>
+ <li><a href="SignInWithTwitter.aspx">Sign In With Twitter</a></li>
+ <li><a href="SampleWcf.aspx">Interop with Service Provider sample using WCF w/ OAuth</a></li>
+ </ul>
+</asp:Content>
diff --git a/src/OAuth/OAuthConsumer/Global.asax b/src/OAuth/OAuthConsumer/Global.asax
new file mode 100644
index 0000000..06ffcd8
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Global.asax
@@ -0,0 +1 @@
+<%@ Application Language="C#" Inherits="OAuthConsumer.Global" CodeBehind="Global.asax.cs" %>
diff --git a/src/OAuth/OAuthConsumer/Global.asax.cs b/src/OAuth/OAuthConsumer/Global.asax.cs
new file mode 100644
index 0000000..10f297e
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Global.asax.cs
@@ -0,0 +1,35 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ public partial class Global : HttpApplication {
+ protected void Application_Start(object sender, EventArgs e) {
+ log4net.Config.XmlConfigurator.Configure();
+ Logging.Logger.Info("Sample starting...");
+ }
+
+ protected void Application_End(object sender, EventArgs e) {
+ Logging.Logger.Info("Sample shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ protected void Application_Error(object sender, EventArgs e) {
+ Logging.Logger.ErrorFormat("An unhandled exception was raised. Details follow: {0}", HttpContext.Current.Server.GetLastError());
+ }
+
+ protected void Session_Start(object sender, EventArgs e) {
+ // Code that runs when a new session is started
+ }
+
+ protected void Session_End(object sender, EventArgs e) {
+ // Code that runs when a session ends.
+ // Note: The Session_End event is raised only when the sessionstate mode
+ // is set to InProc in the Web.config file. If session mode is set to StateServer
+ // or SQLServer, the event is not raised.
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx b/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx
new file mode 100644
index 0000000..19fb505
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx
@@ -0,0 +1,26 @@
+<%@ Page Title="Gmail address book demo" Language="C#" MasterPageFile="~/MasterPage.master"
+ AutoEventWireup="true" Inherits="OAuthConsumer.GoogleAddressBook" Codebehind="GoogleAddressBook.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View runat="server">
+ <h2>Google setup</h2>
+ <p>A Google client app must be endorsed by a Google user. </p>
+ <ol>
+ <li><a target="_blank" href="https://www.google.com/accounts/ManageDomains">Visit Google
+ and create a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.
+ </li>
+ </ol>
+ </asp:View>
+ <asp:View runat="server">
+ <h2>Updates</h2>
+ <p>Ok, Google has authorized us to download your contacts. Click &#39;Get address book&#39;
+ to download the first 5 contacts to this sample. Notice how we never asked you
+ for your Google username or password. </p>
+ <asp:Button ID="getAddressBookButton" runat="server" OnClick="getAddressBookButton_Click"
+ Text="Get address book" />
+ <asp:PlaceHolder ID="resultsPlaceholder" runat="server" />
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx.cs b/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx.cs
new file mode 100644
index 0000000..ddca7e4
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx.cs
@@ -0,0 +1,75 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Configuration;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using System.Xml.Linq;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuth;
+
+ /// <summary>
+ /// A page to demonstrate downloading a Gmail address book using OAuth.
+ /// </summary>
+ public partial class GoogleAddressBook : System.Web.UI.Page {
+ private string AccessToken {
+ get { return (string)Session["GoogleAccessToken"]; }
+ set { Session["GoogleAccessToken"] = value; }
+ }
+
+ private InMemoryTokenManager TokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)Application["GoogleTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = ConfigurationManager.AppSettings["googleConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"];
+ if (!string.IsNullOrEmpty(consumerKey)) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Application["GoogleTokenManager"] = tokenManager;
+ }
+ }
+
+ return tokenManager;
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (this.TokenManager != null) {
+ this.MultiView1.ActiveViewIndex = 1;
+
+ if (!IsPostBack) {
+ var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
+
+ // Is Google calling back with authorization?
+ var accessTokenResponse = google.ProcessUserAuthorization();
+ if (accessTokenResponse != null) {
+ this.AccessToken = accessTokenResponse.AccessToken;
+ } else if (this.AccessToken == null) {
+ // If we don't yet have access, immediately request it.
+ GoogleConsumer.RequestAuthorization(google, GoogleConsumer.Applications.Contacts);
+ }
+ }
+ }
+ }
+
+ protected void getAddressBookButton_Click(object sender, EventArgs e) {
+ var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
+
+ XDocument contactsDocument = GoogleConsumer.GetContacts(google, this.AccessToken, 5, 1);
+ var contacts = from entry in contactsDocument.Root.Elements(XName.Get("entry", "http://www.w3.org/2005/Atom"))
+ select new { Name = entry.Element(XName.Get("title", "http://www.w3.org/2005/Atom")).Value, Email = entry.Element(XName.Get("email", "http://schemas.google.com/g/2005")).Attribute("address").Value };
+ StringBuilder tableBuilder = new StringBuilder();
+ tableBuilder.Append("<table><tr><td>Name</td><td>Email</td></tr>");
+ foreach (var contact in contacts) {
+ tableBuilder.AppendFormat(
+ "<tr><td>{0}</td><td>{1}</td></tr>",
+ HttpUtility.HtmlEncode(contact.Name),
+ HttpUtility.HtmlEncode(contact.Email));
+ }
+ tableBuilder.Append("</table>");
+ this.resultsPlaceholder.Controls.Add(new Literal { Text = tableBuilder.ToString() });
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx.designer.cs b/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx.designer.cs
new file mode 100644
index 0000000..64558d5
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/GoogleAddressBook.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class GoogleAddressBook {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// getAddressBookButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAddressBookButton;
+
+ /// <summary>
+ /// resultsPlaceholder control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder resultsPlaceholder;
+ }
+}
diff --git a/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx b/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx
new file mode 100644
index 0000000..cd9d9a1
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx
@@ -0,0 +1,25 @@
+<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/MasterPage.master"CodeBehind="GoogleApps2Legged.aspx.cs" Inherits="OAuthConsumer.GoogleApps2Legged" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View runat="server">
+ <h2>Google setup</h2>
+ <p>A Google client app must be endorsed by a Google user. </p>
+ <ol>
+ <li><a target="_blank" href="https://www.google.com/accounts/ManageDomains">Visit Google
+ and create a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.
+ </li>
+ </ol>
+ </asp:View>
+ <asp:View runat="server">
+ <h2>Updates</h2>
+ <p>Ok, Google has authorized us to download your contacts. Click &#39;Get address book&#39;
+ to download the first 5 contacts to this sample. Notice how we never asked you
+ for your Google username or password. </p>
+ <asp:Button ID="getAddressBookButton" runat="server" OnClick="getAddressBookButton_Click"
+ Text="Get address book" />
+ <asp:PlaceHolder ID="resultsPlaceholder" runat="server" />
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx.cs b/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx.cs
new file mode 100644
index 0000000..afb156b
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx.cs
@@ -0,0 +1,39 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ public partial class GoogleApps2Legged : System.Web.UI.Page {
+ private InMemoryTokenManager TokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)Application["GoogleTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = ConfigurationManager.AppSettings["googleConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"];
+ if (!string.IsNullOrEmpty(consumerKey)) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Application["GoogleTokenManager"] = tokenManager;
+ }
+ }
+
+ return tokenManager;
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ var google = new WebConsumer(GoogleConsumer.ServiceDescription, this.TokenManager);
+ string accessToken = google.RequestNewClientAccount();
+ ////string tokenSecret = google.TokenManager.GetTokenSecret(accessToken);
+ MessageReceivingEndpoint ep = null; // set up your authorized call here.
+ google.PrepareAuthorizedRequestAndSend(ep, accessToken);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx.designer.cs b/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx.designer.cs
new file mode 100644
index 0000000..f952937
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/GoogleApps2Legged.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class GoogleApps2Legged {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// getAddressBookButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAddressBookButton;
+
+ /// <summary>
+ /// resultsPlaceholder control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder resultsPlaceholder;
+ }
+}
diff --git a/src/OAuth/OAuthConsumer/MasterPage.master b/src/OAuth/OAuthConsumer/MasterPage.master
new file mode 100644
index 0000000..0044208
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/MasterPage.master
@@ -0,0 +1,23 @@
+<%@ Master Language="C#" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<script runat="server">
+
+</script>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>DotNetOpenAuth Consumer sample</title>
+ <asp:ContentPlaceHolder ID="head" runat="server"/>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <h1>DotNetOpenAuth Consumer ASP.NET WebForms sample</h1>
+ <div>
+ <asp:ContentPlaceHolder ID="Body" runat="server">
+ </asp:ContentPlaceHolder>
+ </div>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthConsumer/OAuthConsumer.csproj b/src/OAuth/OAuthConsumer/OAuthConsumer.csproj
new file mode 100644
index 0000000..2e362f2
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/OAuthConsumer.csproj
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{2BF1FFD1-607E-40D0-8AB5-EDA677EF932D}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>OAuthConsumer</RootNamespace>
+ <AssemblyName>OAuthConsumer</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <TargetFrameworkProfile />
+ <UseIISExpress>false</UseIISExpress>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DefineConstants>$(DefineConstants);SAMPLESONLY</DefineConstants>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="DotNetOpenAuth.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.Common, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Common.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.Consumer, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Consumer.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.Consumer.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.ServiceProvider, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.ServiceProvider.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.ServiceProvider.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OpenId, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OpenId.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OpenId.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OpenIdOAuth, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246, processorArchitecture=MSIL">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OpenIdOAuth.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OpenIdOAuth.dll</HintPath>
+ </Reference>
+ <Reference Include="log4net">
+ <HintPath>..\..\..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Runtime.Serialization" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.ApplicationServices" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.DynamicData" />
+ <Reference Include="System.Web.Entity" />
+ <Reference Include="System.Xml.Linq" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Default.aspx" />
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="GoogleAddressBook.aspx" />
+ <Content Include="GoogleApps2Legged.aspx" />
+ <Content Include="images\Sign-in-with-Twitter-darker.png" />
+ <Content Include="SampleWcf.aspx" />
+ <Content Include="Yammer.aspx" />
+ <Content Include="packages.config" />
+ <None Include="Service References\SampleServiceProvider\DataApi.disco" />
+ <None Include="Service References\SampleServiceProvider\configuration91.svcinfo" />
+ <None Include="Service References\SampleServiceProvider\configuration.svcinfo" />
+ <None Include="Service References\SampleServiceProvider\Reference.svcmap">
+ <Generator>WCF Proxy Generator</Generator>
+ <LastGenOutput>Reference.cs</LastGenOutput>
+ </None>
+ <Content Include="SignInWithTwitter.aspx" />
+ <Content Include="TracePage.aspx" />
+ <Content Include="Twitter.aspx" />
+ <Content Include="Web.config" />
+ <None Include="Service References\SampleServiceProvider\DataApi1.xsd">
+ <SubType>Designer</SubType>
+ </None>
+ <None Include="Service References\SampleServiceProvider\DataApi2.xsd">
+ <SubType>Designer</SubType>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="GoogleAddressBook.aspx.designer.cs">
+ <DependentUpon>GoogleAddressBook.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="GoogleApps2Legged.aspx.cs">
+ <DependentUpon>GoogleApps2Legged.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="GoogleApps2Legged.aspx.designer.cs">
+ <DependentUpon>GoogleApps2Legged.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="SampleWcf.aspx.cs">
+ <DependentUpon>SampleWcf.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="SampleWcf.aspx.designer.cs">
+ <DependentUpon>SampleWcf.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Service References\SampleServiceProvider\Reference.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Reference.svcmap</DependentUpon>
+ </Compile>
+ <Compile Include="SignInWithTwitter.aspx.cs">
+ <DependentUpon>SignInWithTwitter.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="SignInWithTwitter.aspx.designer.cs">
+ <DependentUpon>SignInWithTwitter.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="TracePage.aspx.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.designer.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Twitter.aspx.cs">
+ <DependentUpon>Twitter.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Code\Logging.cs" />
+ <Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="GoogleAddressBook.aspx.cs">
+ <DependentUpon>GoogleAddressBook.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Twitter.aspx.designer.cs">
+ <DependentUpon>Twitter.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Yammer.aspx.cs">
+ <DependentUpon>Yammer.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Yammer.aspx.designer.cs">
+ <DependentUpon>Yammer.aspx</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="MasterPage.master" />
+ <None Include="Service References\SampleServiceProvider\DataApi.wsdl" />
+ <None Include="Service References\SampleServiceProvider\DataApi.xsd">
+ <SubType>Designer</SubType>
+ </None>
+ <None Include="Settings.StyleCop" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\DotNetOpenAuth.ApplicationBlock\DotNetOpenAuth.ApplicationBlock.csproj">
+ <Project>{AA78D112-D889-414B-A7D4-467B34C7B663}</Project>
+ <Name>DotNetOpenAuth.ApplicationBlock</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <WCFMetadata Include="Service References\" />
+ </ItemGroup>
+ <ItemGroup>
+ <WCFMetadataStorage Include="Service References\SampleServiceProvider\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>False</AutoAssignPort>
+ <DevelopmentServerPort>59721</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+</Project> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Properties/AssemblyInfo.cs b/src/OAuth/OAuthConsumer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..35efa1c
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OAuthConsumer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OAuthConsumer")]
+[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("12549916-9ec2-4cf6-9fe3-82ea1f6ea665")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/OAuth/OAuthConsumer/SampleWcf.aspx b/src/OAuth/OAuthConsumer/SampleWcf.aspx
new file mode 100644
index 0000000..fb318ce
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/SampleWcf.aspx
@@ -0,0 +1,23 @@
+<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthConsumer.SampleWcf" Codebehind="SampleWcf.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <fieldset title="Authorization">
+ <asp:CheckBoxList runat="server" ID="scopeList">
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetName">GetName</asp:ListItem>
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetAge">GetAge</asp:ListItem>
+ <asp:ListItem Value="http://tempuri.org/IDataApi/GetFavoriteSites">GetFavoriteSites</asp:ListItem>
+ </asp:CheckBoxList>
+ <asp:Button ID="getAuthorizationButton" runat="server" Text="Get Authorization" OnClick="getAuthorizationButton_Click" />
+ <asp:Label ID="authorizationLabel" runat="server" />
+ </fieldset>
+ <br />
+ <asp:Button ID="getNameButton" runat="server" Text="Get Name" OnClick="getNameButton_Click" />
+ <asp:Label ID="nameLabel" runat="server" />
+ <br />
+ <asp:Button ID="getAgeButton" runat="server" Text="Get Age" OnClick="getAgeButton_Click" />
+ <asp:Label ID="ageLabel" runat="server" />
+ <br />
+ <asp:Button ID="getFavoriteSites" runat="server" Text="Get Favorite Sites"
+ onclick="getFavoriteSites_Click" />
+ <asp:Label ID="favoriteSitesLabel" runat="server" />
+</asp:Content>
diff --git a/src/OAuth/OAuthConsumer/SampleWcf.aspx.cs b/src/OAuth/OAuthConsumer/SampleWcf.aspx.cs
new file mode 100644
index 0000000..d56a161
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/SampleWcf.aspx.cs
@@ -0,0 +1,119 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Globalization;
+ using System.Linq;
+ using System.Net;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Security;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using OAuthConsumer.SampleServiceProvider;
+
+ /// <summary>
+ /// Sample consumer of our Service Provider sample's WCF service.
+ /// </summary>
+ public partial class SampleWcf : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ if (!IsPostBack) {
+ if (Session["WcfTokenManager"] != null) {
+ WebConsumer consumer = this.CreateConsumer();
+ var accessTokenMessage = consumer.ProcessUserAuthorization();
+ if (accessTokenMessage != null) {
+ Session["WcfAccessToken"] = accessTokenMessage.AccessToken;
+ this.authorizationLabel.Text = "Authorized! Access token: " + accessTokenMessage.AccessToken;
+ }
+ }
+ }
+ }
+
+ protected void getAuthorizationButton_Click(object sender, EventArgs e) {
+ WebConsumer consumer = this.CreateConsumer();
+ UriBuilder callback = new UriBuilder(Request.Url);
+ callback.Query = null;
+ string[] scopes = (from item in this.scopeList.Items.OfType<ListItem>()
+ where item.Selected
+ select item.Value).ToArray();
+ string scope = string.Join("|", scopes);
+ var requestParams = new Dictionary<string, string> {
+ { "scope", scope },
+ };
+ var response = consumer.PrepareRequestUserAuthorization(callback.Uri, requestParams, null);
+ consumer.Channel.Send(response);
+ }
+
+ protected void getNameButton_Click(object sender, EventArgs e) {
+ try {
+ this.nameLabel.Text = this.CallService(client => client.GetName());
+ } catch (SecurityAccessDeniedException) {
+ this.nameLabel.Text = "Access denied!";
+ }
+ }
+
+ protected void getAgeButton_Click(object sender, EventArgs e) {
+ try {
+ int? age = this.CallService(client => client.GetAge());
+ this.ageLabel.Text = age.HasValue ? age.Value.ToString(CultureInfo.CurrentCulture) : "not available";
+ } catch (SecurityAccessDeniedException) {
+ this.ageLabel.Text = "Access denied!";
+ }
+ }
+
+ protected void getFavoriteSites_Click(object sender, EventArgs e) {
+ try {
+ string[] favoriteSites = this.CallService(client => client.GetFavoriteSites());
+ this.favoriteSitesLabel.Text = string.Join(", ", favoriteSites);
+ } catch (SecurityAccessDeniedException) {
+ this.favoriteSitesLabel.Text = "Access denied!";
+ }
+ }
+
+ private T CallService<T>(Func<DataApiClient, T> predicate) {
+ DataApiClient client = new DataApiClient();
+ var serviceEndpoint = new MessageReceivingEndpoint(client.Endpoint.Address.Uri, HttpDeliveryMethods.AuthorizationHeaderRequest | HttpDeliveryMethods.PostRequest);
+ var accessToken = Session["WcfAccessToken"] as string;
+ if (accessToken == null) {
+ throw new InvalidOperationException("No access token!");
+ }
+ WebConsumer consumer = this.CreateConsumer();
+ WebRequest httpRequest = consumer.PrepareAuthorizedRequest(serviceEndpoint, accessToken);
+
+ HttpRequestMessageProperty httpDetails = new HttpRequestMessageProperty();
+ httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization];
+ using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) {
+ OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpDetails;
+ return predicate(client);
+ }
+ }
+
+ private WebConsumer CreateConsumer() {
+ string consumerKey = "sampleconsumer";
+ string consumerSecret = "samplesecret";
+ var tokenManager = Session["WcfTokenManager"] as InMemoryTokenManager;
+ if (tokenManager == null) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Session["WcfTokenManager"] = tokenManager;
+ }
+ MessageReceivingEndpoint oauthEndpoint = new MessageReceivingEndpoint(
+ new Uri("http://localhost:65169/OAuth.ashx"),
+ HttpDeliveryMethods.PostRequest);
+ WebConsumer consumer = new WebConsumer(
+ new ServiceProviderDescription {
+ RequestTokenEndpoint = oauthEndpoint,
+ UserAuthorizationEndpoint = oauthEndpoint,
+ AccessTokenEndpoint = oauthEndpoint,
+ TamperProtectionElements = new DotNetOpenAuth.Messaging.ITamperProtectionChannelBindingElement[] {
+ new HmacSha1SigningBindingElement(),
+ },
+ },
+ tokenManager);
+
+ return consumer;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/SampleWcf.aspx.designer.cs b/src/OAuth/OAuthConsumer/SampleWcf.aspx.designer.cs
new file mode 100644
index 0000000..c041338
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/SampleWcf.aspx.designer.cs
@@ -0,0 +1,96 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class SampleWcf {
+
+ /// <summary>
+ /// scopeList control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CheckBoxList scopeList;
+
+ /// <summary>
+ /// getAuthorizationButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAuthorizationButton;
+
+ /// <summary>
+ /// authorizationLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label authorizationLabel;
+
+ /// <summary>
+ /// getNameButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getNameButton;
+
+ /// <summary>
+ /// nameLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label nameLabel;
+
+ /// <summary>
+ /// getAgeButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getAgeButton;
+
+ /// <summary>
+ /// ageLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label ageLabel;
+
+ /// <summary>
+ /// getFavoriteSites control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getFavoriteSites;
+
+ /// <summary>
+ /// favoriteSitesLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label favoriteSitesLabel;
+ }
+}
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.disco b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.disco
new file mode 100644
index 0000000..f8d5e5b
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.disco
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
+ <contractRef ref="http://localhost:65169/DataApi.svc?wsdl" docRef="http://localhost:65169/DataApi.svc" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
+</discovery> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.wsdl b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.wsdl
new file mode 100644
index 0000000..702762a
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.wsdl
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wsdl:definitions xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:tns="http://tempuri.org/" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="DataApi" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:ProtectionToken>
+ <wsp:Policy>
+ <sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:RequireDerivedKeys />
+ <sp:BootstrapPolicy>
+ <wsp:Policy>
+ <sp:SignedParts>
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts>
+ <sp:Body />
+ </sp:EncryptedParts>
+ <sp:SymmetricBinding>
+ <wsp:Policy>
+ <sp:ProtectionToken>
+ <wsp:Policy>
+ <sp:SpnegoContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:RequireDerivedKeys />
+ </wsp:Policy>
+ </sp:SpnegoContextToken>
+ </wsp:Policy>
+ </sp:ProtectionToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Strict />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:EncryptSignature />
+ <sp:OnlySignEntireHeadersAndBody />
+ </wsp:Policy>
+ </sp:SymmetricBinding>
+ <sp:Wss11>
+ <wsp:Policy>
+ <sp:MustSupportRefKeyIdentifier />
+ <sp:MustSupportRefIssuerSerial />
+ <sp:MustSupportRefThumbprint />
+ <sp:MustSupportRefEncryptedKey />
+ </wsp:Policy>
+ </sp:Wss11>
+ <sp:Trust10>
+ <wsp:Policy>
+ <sp:MustSupportIssuedTokens />
+ <sp:RequireClientEntropy />
+ <sp:RequireServerEntropy />
+ </wsp:Policy>
+ </sp:Trust10>
+ </wsp:Policy>
+ </sp:BootstrapPolicy>
+ </wsp:Policy>
+ </sp:SecureConversationToken>
+ </wsp:Policy>
+ </sp:ProtectionToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Strict />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:EncryptSignature />
+ <sp:OnlySignEntireHeadersAndBody />
+ </wsp:Policy>
+ </sp:SymmetricBinding>
+ <sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:MustSupportRefKeyIdentifier />
+ <sp:MustSupportRefIssuerSerial />
+ <sp:MustSupportRefThumbprint />
+ <sp:MustSupportRefEncryptedKey />
+ </wsp:Policy>
+ </sp:Wss11>
+ <sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:MustSupportIssuedTokens />
+ <sp:RequireClientEntropy />
+ <sp:RequireServerEntropy />
+ </wsp:Policy>
+ </sp:Trust10>
+ <wsaw:UsingAddressing />
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetAge_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetAge_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetName_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetName_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetFavoriteSites_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetFavoriteSites_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsdl:types>
+ <xsd:schema targetNamespace="http://tempuri.org/Imports">
+ <xsd:import schemaLocation="http://localhost:65169/DataApi.svc?xsd=xsd0" namespace="http://tempuri.org/" />
+ <xsd:import schemaLocation="http://localhost:65169/DataApi.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
+ <xsd:import schemaLocation="http://localhost:65169/DataApi.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
+ </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="IDataApi_GetAge_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetAge" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetAge_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetAgeResponse" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetName_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetName" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetName_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetNameResponse" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetFavoriteSites_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetFavoriteSites" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetFavoriteSites_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetFavoriteSitesResponse" />
+ </wsdl:message>
+ <wsdl:portType name="IDataApi">
+ <wsdl:operation name="GetAge">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetAge" message="tns:IDataApi_GetAge_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetAgeResponse" message="tns:IDataApi_GetAge_OutputMessage" />
+ </wsdl:operation>
+ <wsdl:operation name="GetName">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetName" message="tns:IDataApi_GetName_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetNameResponse" message="tns:IDataApi_GetName_OutputMessage" />
+ </wsdl:operation>
+ <wsdl:operation name="GetFavoriteSites">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetFavoriteSites" message="tns:IDataApi_GetFavoriteSites_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetFavoriteSitesResponse" message="tns:IDataApi_GetFavoriteSites_OutputMessage" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="WSHttpBinding_IDataApi" type="tns:IDataApi">
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_policy" />
+ <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetAge">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetAge" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetAge_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetAge_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetName">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetName" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetName_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetName_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetFavoriteSites">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetFavoriteSites" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetFavoriteSites_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetFavoriteSites_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="DataApi">
+ <wsdl:port name="WSHttpBinding_IDataApi" binding="tns:WSHttpBinding_IDataApi">
+ <soap12:address location="http://localhost:65169/DataApi.svc" />
+ <wsa10:EndpointReference>
+ <wsa10:Address>http://localhost:65169/DataApi.svc</wsa10:Address>
+ <Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
+ <Dns>localhost</Dns>
+ </Identity>
+ </wsa10:EndpointReference>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.xsd b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.xsd
new file mode 100644
index 0000000..3109534
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi.xsd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:import schemaLocation="http://localhost:65169/DataApi.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
+ <xs:element name="GetAge">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetAgeResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="GetAgeResult" nillable="true" type="xs:int" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetName">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetNameResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="GetNameResult" nillable="true" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetFavoriteSites">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetFavoriteSitesResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="GetFavoriteSitesResult" nillable="true" type="q1:ArrayOfstring" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi1.xsd b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi1.xsd
new file mode 100644
index 0000000..d58e7f3
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi1.xsd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="anyType" nillable="true" type="xs:anyType" />
+ <xs:element name="anyURI" nillable="true" type="xs:anyURI" />
+ <xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
+ <xs:element name="boolean" nillable="true" type="xs:boolean" />
+ <xs:element name="byte" nillable="true" type="xs:byte" />
+ <xs:element name="dateTime" nillable="true" type="xs:dateTime" />
+ <xs:element name="decimal" nillable="true" type="xs:decimal" />
+ <xs:element name="double" nillable="true" type="xs:double" />
+ <xs:element name="float" nillable="true" type="xs:float" />
+ <xs:element name="int" nillable="true" type="xs:int" />
+ <xs:element name="long" nillable="true" type="xs:long" />
+ <xs:element name="QName" nillable="true" type="xs:QName" />
+ <xs:element name="short" nillable="true" type="xs:short" />
+ <xs:element name="string" nillable="true" type="xs:string" />
+ <xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
+ <xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
+ <xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
+ <xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
+ <xs:element name="char" nillable="true" type="tns:char" />
+ <xs:simpleType name="char">
+ <xs:restriction base="xs:int" />
+ </xs:simpleType>
+ <xs:element name="duration" nillable="true" type="tns:duration" />
+ <xs:simpleType name="duration">
+ <xs:restriction base="xs:duration">
+ <xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
+ <xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
+ <xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="guid" nillable="true" type="tns:guid" />
+ <xs:simpleType name="guid">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:attribute name="FactoryType" type="xs:QName" />
+ <xs:attribute name="Id" type="xs:ID" />
+ <xs:attribute name="Ref" type="xs:IDREF" />
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi2.xsd b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi2.xsd
new file mode 100644
index 0000000..04a74a4
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/DataApi2.xsd
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType name="ArrayOfstring">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="ArrayOfstring" nillable="true" type="tns:ArrayOfstring" />
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/Reference.cs b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/Reference.cs
new file mode 100644
index 0000000..5451c9f
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/Reference.cs
@@ -0,0 +1,67 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.17379
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer.SampleServiceProvider {
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ [System.ServiceModel.ServiceContractAttribute(ConfigurationName="SampleServiceProvider.IDataApi")]
+ public interface IDataApi {
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetAge", ReplyAction="http://tempuri.org/IDataApi/GetAgeResponse")]
+ System.Nullable<int> GetAge();
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetName", ReplyAction="http://tempuri.org/IDataApi/GetNameResponse")]
+ string GetName();
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetFavoriteSites", ReplyAction="http://tempuri.org/IDataApi/GetFavoriteSitesResponse")]
+ string[] GetFavoriteSites();
+ }
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ public interface IDataApiChannel : OAuthConsumer.SampleServiceProvider.IDataApi, System.ServiceModel.IClientChannel {
+ }
+
+ [System.Diagnostics.DebuggerStepThroughAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ public partial class DataApiClient : System.ServiceModel.ClientBase<OAuthConsumer.SampleServiceProvider.IDataApi>, OAuthConsumer.SampleServiceProvider.IDataApi {
+
+ public DataApiClient() {
+ }
+
+ public DataApiClient(string endpointConfigurationName) :
+ base(endpointConfigurationName) {
+ }
+
+ public DataApiClient(string endpointConfigurationName, string remoteAddress) :
+ base(endpointConfigurationName, remoteAddress) {
+ }
+
+ public DataApiClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
+ base(endpointConfigurationName, remoteAddress) {
+ }
+
+ public DataApiClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
+ base(binding, remoteAddress) {
+ }
+
+ public System.Nullable<int> GetAge() {
+ return base.Channel.GetAge();
+ }
+
+ public string GetName() {
+ return base.Channel.GetName();
+ }
+
+ public string[] GetFavoriteSites() {
+ return base.Channel.GetFavoriteSites();
+ }
+ }
+}
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/Reference.svcmap b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/Reference.svcmap
new file mode 100644
index 0000000..4463f99
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/Reference.svcmap
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ReferenceGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="41652b7a-0e9d-40be-8e75-8ccd843850c4" xmlns="urn:schemas-microsoft-com:xml-wcfservicemap">
+ <ClientOptions>
+ <GenerateAsynchronousMethods>false</GenerateAsynchronousMethods>
+ <EnableDataBinding>true</EnableDataBinding>
+ <ExcludedTypes />
+ <ImportXmlTypes>false</ImportXmlTypes>
+ <GenerateInternalTypes>false</GenerateInternalTypes>
+ <GenerateMessageContracts>false</GenerateMessageContracts>
+ <NamespaceMappings />
+ <CollectionMappings />
+ <GenerateSerializableTypes>true</GenerateSerializableTypes>
+ <Serializer>Auto</Serializer>
+ <UseSerializerForFaults>true</UseSerializerForFaults>
+ <ReferenceAllAssemblies>true</ReferenceAllAssemblies>
+ <ReferencedAssemblies />
+ <ReferencedDataContractTypes />
+ <ServiceContractMappings />
+ </ClientOptions>
+ <MetadataSources>
+ <MetadataSource Address="http://localhost:65169/DataApi.svc" Protocol="http" SourceId="1" />
+ </MetadataSources>
+ <Metadata>
+ <MetadataFile FileName="DataApi.xsd" MetadataType="Schema" ID="82a34da8-d721-4c35-aaf9-fc5d08771cd2" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?xsd=xsd0" />
+ <MetadataFile FileName="DataApi.wsdl" MetadataType="Wsdl" ID="96350220-1df2-429e-8cb5-4fc33703bcc7" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?wsdl" />
+ <MetadataFile FileName="DataApi.disco" MetadataType="Disco" ID="c4f66dee-ac01-4476-afb0-34f7350c06ad" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?disco" />
+ <MetadataFile FileName="DataApi1.xsd" MetadataType="Schema" ID="7aaf262f-6342-421b-8f44-0e624be7a5fb" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?xsd=xsd1" />
+ <MetadataFile FileName="DataApi2.xsd" MetadataType="Schema" ID="67c1ea8d-12c4-4a0c-aa33-7226018cf16e" SourceId="1" SourceUrl="http://localhost:65169/DataApi.svc?xsd=xsd2" />
+ </Metadata>
+ <Extensions>
+ <ExtensionFile FileName="configuration91.svcinfo" Name="configuration91.svcinfo" />
+ <ExtensionFile FileName="configuration.svcinfo" Name="configuration.svcinfo" />
+ </Extensions>
+</ReferenceGroup> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/configuration.svcinfo b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/configuration.svcinfo
new file mode 100644
index 0000000..24b13a5
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/configuration.svcinfo
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configurationSnapshot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:schemas-microsoft-com:xml-wcfconfigurationsnapshot">
+ <behaviors />
+ <bindings>
+ <binding digest="System.ServiceModel.Configuration.WSHttpBindingElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data hostNameComparisonMode=&quot;StrongWildcard&quot; messageEncoding=&quot;Text&quot; name=&quot;WSHttpBinding_IDataApi1&quot; textEncoding=&quot;utf-8&quot; transactionFlow=&quot;false&quot;&gt;&lt;readerQuotas maxArrayLength=&quot;16384&quot; maxBytesPerRead=&quot;4096&quot; maxDepth=&quot;32&quot; maxNameTableCharCount=&quot;16384&quot; maxStringContentLength=&quot;8192&quot; /&gt;&lt;reliableSession enabled=&quot;false&quot; inactivityTimeout=&quot;00:10:00&quot; ordered=&quot;true&quot; /&gt;&lt;security mode=&quot;Message&quot;&gt;&lt;message algorithmSuite=&quot;Default&quot; clientCredentialType=&quot;Windows&quot; negotiateServiceCredential=&quot;true&quot; /&gt;&lt;transport clientCredentialType=&quot;Windows&quot; proxyCredentialType=&quot;None&quot; realm=&quot;&quot; /&gt;&lt;/security&gt;&lt;/Data&gt;" bindingType="wsHttpBinding" name="WSHttpBinding_IDataApi1" />
+ </bindings>
+ <endpoints>
+ <endpoint normalizedDigest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://localhost:65169/DataApi.svc&quot; binding=&quot;wsHttpBinding&quot; bindingConfiguration=&quot;WSHttpBinding_IDataApi1&quot; contract=&quot;SampleServiceProvider.IDataApi&quot; name=&quot;WSHttpBinding_IDataApi1&quot;&gt;&lt;identity&gt;&lt;dns value=&quot;localhost&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" digest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://localhost:65169/DataApi.svc&quot; binding=&quot;wsHttpBinding&quot; bindingConfiguration=&quot;WSHttpBinding_IDataApi1&quot; contract=&quot;SampleServiceProvider.IDataApi&quot; name=&quot;WSHttpBinding_IDataApi1&quot;&gt;&lt;identity&gt;&lt;dns value=&quot;localhost&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" contractName="SampleServiceProvider.IDataApi" name="WSHttpBinding_IDataApi1" />
+ </endpoints>
+</configurationSnapshot> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/configuration91.svcinfo b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/configuration91.svcinfo
new file mode 100644
index 0000000..822d218
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Service References/SampleServiceProvider/configuration91.svcinfo
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="utf-8"?>
+<SavedWcfConfigurationInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="9.1" CheckSum="GUEgzgg89GpE4CgPbgPkvKCNLCE=">
+ <bindingConfigurations>
+ <bindingConfiguration bindingType="wsHttpBinding" name="WSHttpBinding_IDataApi1">
+ <properties>
+ <property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi1</serializedValue>
+ </property>
+ <property path="/closeTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/openTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/receiveTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:10:00</serializedValue>
+ </property>
+ <property path="/sendTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/bypassProxyOnLocal" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/transactionFlow" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/hostNameComparisonMode" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HostNameComparisonMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>StrongWildcard</serializedValue>
+ </property>
+ <property path="/maxBufferPoolSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>524288</serializedValue>
+ </property>
+ <property path="/maxReceivedMessageSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>65536</serializedValue>
+ </property>
+ <property path="/messageEncoding" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.WSMessageEncoding, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Text</serializedValue>
+ </property>
+ <property path="/proxyAddress" isComplexType="false" isExplicitlyDefined="false" clrType="System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/readerQuotas" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxDepth" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>32</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxStringContentLength" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>8192</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxArrayLength" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>16384</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxBytesPerRead" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>4096</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxNameTableCharCount" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>16384</serializedValue>
+ </property>
+ <property path="/reliableSession" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.StandardBindingOptionalReliableSessionElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.StandardBindingOptionalReliableSessionElement</serializedValue>
+ </property>
+ <property path="/reliableSession/ordered" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/reliableSession/inactivityTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:10:00</serializedValue>
+ </property>
+ <property path="/reliableSession/enabled" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/textEncoding" isComplexType="false" isExplicitlyDefined="true" clrType="System.Text.Encoding, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.Text.UTF8Encoding</serializedValue>
+ </property>
+ <property path="/useDefaultWebProxy" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/allowCookies" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/security" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.WSHttpSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.WSHttpSecurityElement</serializedValue>
+ </property>
+ <property path="/security/mode" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.SecurityMode, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Message</serializedValue>
+ </property>
+ <property path="/security/transport" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.WSHttpTransportSecurityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.WSHttpTransportSecurityElement</serializedValue>
+ </property>
+ <property path="/security/transport/clientCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HttpClientCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Windows</serializedValue>
+ </property>
+ <property path="/security/transport/proxyCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HttpProxyCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>None</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/policyEnforcement" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.PolicyEnforcement, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Never</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/protectionScenario" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.ProtectionScenario, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>TransportSelected</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/customServiceNames" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ServiceNameElementCollection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>(Collection)</serializedValue>
+ </property>
+ <property path="/security/transport/realm" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/security/message" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.NonDualMessageSecurityOverHttpElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.NonDualMessageSecurityOverHttpElement</serializedValue>
+ </property>
+ <property path="/security/message/clientCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.MessageCredentialType, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Windows</serializedValue>
+ </property>
+ <property path="/security/message/negotiateServiceCredential" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/security/message/algorithmSuite" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.Security.SecurityAlgorithmSuite, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Default</serializedValue>
+ </property>
+ <property path="/security/message/establishSecurityContext" isComplexType="false" isExplicitlyDefined="false" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ </properties>
+ </bindingConfiguration>
+ </bindingConfigurations>
+ <endpoints>
+ <endpoint name="WSHttpBinding_IDataApi1" contract="SampleServiceProvider.IDataApi" bindingType="wsHttpBinding" address="http://localhost:65169/DataApi.svc" bindingConfiguration="WSHttpBinding_IDataApi1">
+ <properties>
+ <property path="/address" isComplexType="false" isExplicitlyDefined="true" clrType="System.Uri, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>http://localhost:65169/DataApi.svc</serializedValue>
+ </property>
+ <property path="/behaviorConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/binding" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>wsHttpBinding</serializedValue>
+ </property>
+ <property path="/bindingConfiguration" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi1</serializedValue>
+ </property>
+ <property path="/contract" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>SampleServiceProvider.IDataApi</serializedValue>
+ </property>
+ <property path="/headers" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.AddressHeaderCollectionElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.AddressHeaderCollectionElement</serializedValue>
+ </property>
+ <property path="/headers/headers" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.Channels.AddressHeaderCollection, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>&lt;Header /&gt;</serializedValue>
+ </property>
+ <property path="/identity" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.IdentityElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.IdentityElement</serializedValue>
+ </property>
+ <property path="/identity/userPrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.UserPrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.UserPrincipalNameElement</serializedValue>
+ </property>
+ <property path="/identity/userPrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/servicePrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.ServicePrincipalNameElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.ServicePrincipalNameElement</serializedValue>
+ </property>
+ <property path="/identity/servicePrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/dns" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.DnsElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.DnsElement</serializedValue>
+ </property>
+ <property path="/identity/dns/value" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>localhost</serializedValue>
+ </property>
+ <property path="/identity/rsa" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.RsaElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.RsaElement</serializedValue>
+ </property>
+ <property path="/identity/rsa/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificate" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.CertificateElement</serializedValue>
+ </property>
+ <property path="/identity/certificate/encodedValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificateReference" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateReferenceElement, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.CertificateReferenceElement</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/storeName" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreName, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>My</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/storeLocation" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreLocation, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>LocalMachine</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/x509FindType" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.X509FindType, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>FindBySubjectDistinguishedName</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/findValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificateReference/isChainIncluded" isComplexType="false" isExplicitlyDefined="false" clrType="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi1</serializedValue>
+ </property>
+ <property path="/kind" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/endpointConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ </properties>
+ </endpoint>
+ </endpoints>
+</SavedWcfConfigurationInformation> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Settings.StyleCop b/src/OAuth/OAuthConsumer/Settings.StyleCop
new file mode 100644
index 0000000..7f55ce6
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Settings.StyleCop
@@ -0,0 +1 @@
+<StyleCopSettings Version="4.3" /> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx b/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx
new file mode 100644
index 0000000..86d29a4
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx
@@ -0,0 +1,38 @@
+<%@ Page Language="C#" AutoEventWireup="true"
+ Inherits="OAuthConsumer.SignInWithTwitter" Codebehind="SignInWithTwitter.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>Sign-in with Twitter</title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <div>
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View ID="View1" runat="server">
+ <h2>
+ Twitter setup</h2>
+ <p>
+ A Twitter client app must be endorsed by a Twitter user.
+ </p>
+ <ol>
+ <li><a target="_blank" href="https://twitter.com/oauth_clients">Visit Twitter and create
+ a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.</li>
+ </ol>
+ </asp:View>
+ <asp:View ID="View2" runat="server">
+ <asp:ImageButton ImageUrl="~/images/Sign-in-with-Twitter-darker.png" runat="server"
+ AlternateText="Sign In With Twitter" ID="signInButton" OnClick="signInButton_Click" />
+ <asp:CheckBox Text="force re-login" runat="server" ID="forceLoginCheckbox" />
+ <br />
+ <asp:Panel runat="server" ID="loggedInPanel" Visible="false">
+ Now logged in as
+ <asp:Label Text="[name]" runat="server" ID="loggedInName" />
+ </asp:Panel>
+ </asp:View>
+ </asp:MultiView>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx.cs b/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx.cs
new file mode 100644
index 0000000..e104f3a
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx.cs
@@ -0,0 +1,39 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Web;
+ using System.Web.Security;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using System.Xml.Linq;
+ using System.Xml.XPath;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuth;
+
+ public partial class SignInWithTwitter : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ if (TwitterConsumer.IsTwitterConsumerConfigured) {
+ this.MultiView1.ActiveViewIndex = 1;
+
+ if (!IsPostBack) {
+ string screenName;
+ int userId;
+ if (TwitterConsumer.TryFinishSignInWithTwitter(out screenName, out userId)) {
+ this.loggedInPanel.Visible = true;
+ this.loggedInName.Text = screenName;
+
+ // In a real app, the Twitter username would likely be used
+ // to log the user into the application.
+ ////FormsAuthentication.RedirectFromLoginPage(screenName, false);
+ }
+ }
+ }
+ }
+
+ protected void signInButton_Click(object sender, ImageClickEventArgs e) {
+ TwitterConsumer.StartSignInWithTwitter(this.forceLoginCheckbox.Checked).Send();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx.designer.cs b/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx.designer.cs
new file mode 100644
index 0000000..962a1af
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/SignInWithTwitter.aspx.designer.cs
@@ -0,0 +1,87 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class SignInWithTwitter {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+
+ /// <summary>
+ /// View2 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View2;
+
+ /// <summary>
+ /// signInButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.ImageButton signInButton;
+
+ /// <summary>
+ /// forceLoginCheckbox control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.CheckBox forceLoginCheckbox;
+
+ /// <summary>
+ /// loggedInPanel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel loggedInPanel;
+
+ /// <summary>
+ /// loggedInName control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label loggedInName;
+ }
+}
diff --git a/src/OAuth/OAuthConsumer/TracePage.aspx b/src/OAuth/OAuthConsumer/TracePage.aspx
new file mode 100644
index 0000000..d3539fb
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/TracePage.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OAuthConsumer.TracePage" Codebehind="TracePage.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <p align="right">
+ <asp:Button runat="server" Text="Clear log" ID="clearLogButton" OnClick="clearLogButton_Click" />
+ </p>
+ <pre>
+ <asp:PlaceHolder runat="server" ID="placeHolder1" />
+ </pre>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthConsumer/TracePage.aspx.cs b/src/OAuth/OAuthConsumer/TracePage.aspx.cs
new file mode 100644
index 0000000..b9ca260
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/TracePage.aspx.cs
@@ -0,0 +1,23 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ /// <summary>
+ /// A page to display recent log messages.
+ /// </summary>
+ public partial class TracePage : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.placeHolder1.Controls.Add(new Label { Text = HttpUtility.HtmlEncode(Logging.LogMessages.ToString()) });
+ }
+
+ protected void clearLogButton_Click(object sender, EventArgs e) {
+ Logging.LogMessages.Length = 0;
+
+ // clear the page immediately, and allow for F5 without a Postback warning.
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/TracePage.aspx.designer.cs b/src/OAuth/OAuthConsumer/TracePage.aspx.designer.cs
new file mode 100644
index 0000000..73184b5
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/TracePage.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class TracePage {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// clearLogButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button clearLogButton;
+
+ /// <summary>
+ /// placeHolder1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder placeHolder1;
+ }
+}
diff --git a/src/OAuth/OAuthConsumer/Twitter.aspx b/src/OAuth/OAuthConsumer/Twitter.aspx
new file mode 100644
index 0000000..a24c7bd
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Twitter.aspx
@@ -0,0 +1,35 @@
+<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthConsumer.Twitter" Codebehind="Twitter.aspx.cs" %>
+
+<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">
+</asp:Content>
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View ID="View1" runat="server">
+ <h2>Twitter setup</h2>
+ <p>A Twitter client app must be endorsed by a Twitter user. </p>
+ <ol>
+ <li><a target="_blank" href="https://twitter.com/oauth_clients">Visit Twitter and create
+ a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.</li>
+ </ol>
+ </asp:View>
+ <asp:View runat="server">
+ <h2>Updates</h2>
+ <p>Ok, Twitter has authorized us to download your feeds. Notice how we never asked
+ you for your Twitter username or password. </p>
+ <p>
+ Upload a new profile photo:
+ <asp:FileUpload ID="profilePhoto" runat="server" />
+ &nbsp;<asp:Button ID="uploadProfilePhotoButton" runat="server"
+ onclick="uploadProfilePhotoButton_Click" Text="Upload photo" />
+ &nbsp;<asp:Label ID="photoUploadedLabel" runat="server" EnableViewState="False"
+ Text="Done!" Visible="False"></asp:Label>
+ </p>
+ <p>
+ Click &#39;Get updates&#39; to download updates to this sample.
+ </p>
+ <asp:Button ID="downloadUpdates" runat="server" Text="Get updates" OnClick="downloadUpdates_Click" />
+ <asp:PlaceHolder runat="server" ID="resultsPlaceholder" />
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthConsumer/Twitter.aspx.cs b/src/OAuth/OAuthConsumer/Twitter.aspx.cs
new file mode 100644
index 0000000..8288ed0
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Twitter.aspx.cs
@@ -0,0 +1,96 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Text;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using System.Xml.Linq;
+ using System.Xml.XPath;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuth;
+
+ public partial class Twitter : System.Web.UI.Page {
+ private string AccessToken {
+ get { return (string)Session["TwitterAccessToken"]; }
+ set { Session["TwitterAccessToken"] = value; }
+ }
+
+ private InMemoryTokenManager TokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)Application["TwitterTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
+ if (!string.IsNullOrEmpty(consumerKey)) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Application["TwitterTokenManager"] = tokenManager;
+ }
+ }
+
+ return tokenManager;
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (this.TokenManager != null) {
+ this.MultiView1.ActiveViewIndex = 1;
+
+ if (!IsPostBack) {
+ var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
+
+ // Is Twitter calling back with authorization?
+ var accessTokenResponse = twitter.ProcessUserAuthorization();
+ if (accessTokenResponse != null) {
+ this.AccessToken = accessTokenResponse.AccessToken;
+ } else if (this.AccessToken == null) {
+ // If we don't yet have access, immediately request it.
+ twitter.Channel.Send(twitter.PrepareRequestUserAuthorization());
+ }
+ }
+ }
+ }
+
+ protected void downloadUpdates_Click(object sender, EventArgs e) {
+ var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
+ XPathDocument updates = new XPathDocument(TwitterConsumer.GetUpdates(twitter, this.AccessToken).CreateReader());
+ XPathNavigator nav = updates.CreateNavigator();
+ var parsedUpdates = from status in nav.Select("/statuses/status").OfType<XPathNavigator>()
+ where !status.SelectSingleNode("user/protected").ValueAsBoolean
+ select new {
+ User = status.SelectSingleNode("user/name").InnerXml,
+ Status = status.SelectSingleNode("text").InnerXml,
+ };
+
+ StringBuilder tableBuilder = new StringBuilder();
+ tableBuilder.Append("<table><tr><td>Name</td><td>Update</td></tr>");
+
+ foreach (var update in parsedUpdates) {
+ tableBuilder.AppendFormat(
+ "<tr><td>{0}</td><td>{1}</td></tr>",
+ HttpUtility.HtmlEncode(update.User),
+ HttpUtility.HtmlEncode(update.Status));
+ }
+ tableBuilder.Append("</table>");
+ this.resultsPlaceholder.Controls.Add(new Literal { Text = tableBuilder.ToString() });
+ }
+
+ protected void uploadProfilePhotoButton_Click(object sender, EventArgs e) {
+ if (this.profilePhoto.PostedFile.ContentType == null) {
+ this.photoUploadedLabel.Visible = true;
+ this.photoUploadedLabel.Text = "Select a file first.";
+ return;
+ }
+
+ var twitter = new WebConsumer(TwitterConsumer.ServiceDescription, this.TokenManager);
+ XDocument imageResult = TwitterConsumer.UpdateProfileImage(
+ twitter,
+ this.AccessToken,
+ this.profilePhoto.PostedFile.InputStream,
+ this.profilePhoto.PostedFile.ContentType);
+ this.photoUploadedLabel.Visible = true;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Twitter.aspx.designer.cs b/src/OAuth/OAuthConsumer/Twitter.aspx.designer.cs
new file mode 100644
index 0000000..7c37271
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Twitter.aspx.designer.cs
@@ -0,0 +1,78 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class Twitter {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+
+ /// <summary>
+ /// profilePhoto control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.FileUpload profilePhoto;
+
+ /// <summary>
+ /// uploadProfilePhotoButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button uploadProfilePhotoButton;
+
+ /// <summary>
+ /// photoUploadedLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label photoUploadedLabel;
+
+ /// <summary>
+ /// downloadUpdates control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button downloadUpdates;
+
+ /// <summary>
+ /// resultsPlaceholder control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder resultsPlaceholder;
+ }
+}
diff --git a/src/OAuth/OAuthConsumer/Web.config b/src/OAuth/OAuthConsumer/Web.config
new file mode 100644
index 0000000..3963433
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Web.config
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false" />
+ <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+ <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" />
+ <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" />
+ </sectionGroup>
+ </configSections>
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <appSettings>
+ <!-- Fill in your various consumer keys and secrets here to make the sample work. -->
+ <!-- You must get these values by signing up with each individual service provider. -->
+ <!-- Twitter sign-up: https://twitter.com/oauth_clients -->
+ <add key="twitterConsumerKey" value="" />
+ <add key="twitterConsumerSecret" value="" />
+ <!-- Google sign-up: https://www.google.com/accounts/ManageDomains -->
+ <add key="googleConsumerKey" value="anonymous" />
+ <add key="googleConsumerSecret" value="anonymous" />
+ <!-- Yammer sign-up: https://www.yammer.com/client_applications/new -->
+ <add key="yammerConsumerKey" value="" />
+ <add key="yammerConsumerSecret" value="" />
+ </appSettings>
+ <connectionStrings />
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true" targetFramework="4.0">
+ <assemblies>
+ <remove assembly="DotNetOpenAuth.Contracts" />
+ </assemblies>
+ </compilation>
+ <!--
+ The <authentication> section enables configuration
+ of the security authentication mode used by
+ ASP.NET to identify an incoming user.
+ -->
+ <authentication mode="Windows" />
+ <!--
+ The <customErrors> section enables configuration
+ of what to do if/when an unhandled error occurs
+ during the execution of a request. Specifically,
+ it enables developers to configure html error pages
+ to be displayed in place of a error stack trace.
+
+ <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
+ <error statusCode="403" redirect="NoAccess.htm" />
+ <error statusCode="404" redirect="FileNotFound.htm" />
+ </customErrors>
+ -->
+ <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
+ </system.web>
+ <!--
+ The system.webServer section is required for running ASP.NET AJAX under Internet
+ Information Services 7.0. It is not necessary for previous version of IIS.
+ -->
+ <log4net>
+ <appender name="TracePageAppender" type="OAuthConsumer.TracePageAppender, OAuthConsumer">
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline" />
+ </layout>
+ </appender>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO" />
+ <!--<appender-ref ref="RollingFileAppender" />-->
+ <appender-ref ref="TracePageAppender" />
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="ALL" />
+ </logger>
+ </log4net>
+ <system.serviceModel>
+ <bindings>
+ <wsHttpBinding>
+ <binding name="WSHttpBinding_IDataApi" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+ <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
+ <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
+ <security mode="Message">
+ <transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
+ <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true" />
+ </security>
+ </binding>
+ </wsHttpBinding>
+ </bindings>
+ <client>
+ <endpoint address="http://localhost:65169/DataApi.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDataApi" contract="SampleServiceProvider.IDataApi" name="WSHttpBinding_IDataApi">
+ <identity>
+ <dns value="localhost" />
+ </identity>
+ </endpoint>
+ </client>
+ </system.serviceModel>
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+ <runtime>
+ <!-- This prevents the Windows Event Log from frequently logging that HMAC1 is being used (when the other party needs it). -->
+ <legacyHMACWarning enabled="0" />
+ </runtime>
+ <dotNetOpenAuth>
+ <messaging>
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
+ <!--<add name="localhost" />-->
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true" />
+ <openid></openid>
+ </dotNetOpenAuth>
+ <uri>
+ <!-- See an error due to this section? When targeting .NET 3.5, please add the following line to your <configSections> at the top of this file:
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ -->
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <idn enabled="All" />
+ <iriParsing enabled="true" />
+ </uri>
+</configuration> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Yammer.aspx b/src/OAuth/OAuthConsumer/Yammer.aspx
new file mode 100644
index 0000000..90b61b8
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Yammer.aspx
@@ -0,0 +1,48 @@
+<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="~/MasterPage.master"
+ CodeBehind="Yammer.aspx.cs" Inherits="OAuthConsumer.Yammer" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
+ <asp:View ID="ClientRegistrationRequiredView" runat="server">
+ <h2>
+ Yammer setup</h2>
+ <p>
+ A Yammer client app must be registered.
+ </p>
+ <ol>
+ <li><a target="_blank" href="https://www.yammer.com/client_applications/new">Visit Yammer
+ and register a client app</a>. </li>
+ <li>Modify your web.config file to include your consumer key and consumer secret.
+ </li>
+ </ol>
+ </asp:View>
+ <asp:View ID="BeginAuthorizationView" runat="server">
+ <asp:Label Text="An error occurred in authorization. You may try again." EnableViewState="false" Visible="false" ForeColor="Red" ID="authorizationErrorLabel" runat="server" />
+ <asp:Button Text="Obtain authorization now" runat="server" ID="obtainAuthorizationButton"
+ OnClick="obtainAuthorizationButton_Click" />
+ </asp:View>
+ <asp:View ID="CompleteAuthorizationView" runat="server">
+ After you have authorized Yammer to share your information, please enter the code
+ Yammer gives you here:
+ <asp:TextBox runat="server" ID="yammerUserCode" EnableViewState="false" />
+ <asp:RequiredFieldValidator ErrorMessage="*" ControlToValidate="yammerUserCode" runat="server" />
+ <asp:Button Text="Finish" runat="server" ID="finishAuthorizationButton" OnClick="finishAuthorizationButton_Click" />
+ </asp:View>
+ <asp:View ID="AuthorizationCompleteView" runat="server">
+ <h2>
+ Updates
+ </h2>
+ <p>The access token we have obtained is:
+ <asp:Label ID="accessTokenLabel" runat="server" />
+ </p>
+ <p>
+ Ok, Yammer has authorized us to download your messages. Click &#39;Get messages&#39;
+ to download the latest few messages to this sample. Notice how we never asked you
+ for your Yammer username or password.
+ </p>
+ <asp:Button ID="getYammerMessagesButton" runat="server" OnClick="getYammerMessages_Click"
+ Text="Get address book" />
+ <asp:PlaceHolder ID="resultsPlaceholder" runat="server" />
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthConsumer/Yammer.aspx.cs b/src/OAuth/OAuthConsumer/Yammer.aspx.cs
new file mode 100644
index 0000000..d8993fe
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Yammer.aspx.cs
@@ -0,0 +1,76 @@
+namespace OAuthConsumer {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+
+ public partial class Yammer : System.Web.UI.Page {
+ private string RequestToken {
+ get { return (string)ViewState["YammerRequestToken"]; }
+ set { ViewState["YammerRequestToken"] = value; }
+ }
+
+ private string AccessToken {
+ get { return (string)Session["YammerAccessToken"]; }
+ set { Session["YammerAccessToken"] = value; }
+ }
+
+ private InMemoryTokenManager TokenManager {
+ get {
+ var tokenManager = (InMemoryTokenManager)Application["YammerTokenManager"];
+ if (tokenManager == null) {
+ string consumerKey = ConfigurationManager.AppSettings["YammerConsumerKey"];
+ string consumerSecret = ConfigurationManager.AppSettings["YammerConsumerSecret"];
+ if (!string.IsNullOrEmpty(consumerKey)) {
+ tokenManager = new InMemoryTokenManager(consumerKey, consumerSecret);
+ Application["YammerTokenManager"] = tokenManager;
+ }
+ }
+
+ return tokenManager;
+ }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (this.TokenManager != null) {
+ this.MultiView1.SetActiveView(this.BeginAuthorizationView);
+ }
+ }
+
+ protected void getYammerMessages_Click(object sender, EventArgs e) {
+ var yammer = new WebConsumer(YammerConsumer.ServiceDescription, this.TokenManager);
+ }
+
+ protected void obtainAuthorizationButton_Click(object sender, EventArgs e) {
+ var yammer = YammerConsumer.CreateConsumer(this.TokenManager);
+ string requestToken;
+ Uri popupWindowLocation = YammerConsumer.PrepareRequestAuthorization(yammer, out requestToken);
+ this.RequestToken = requestToken;
+ string javascript = "window.open('" + popupWindowLocation.AbsoluteUri + "');";
+ this.Page.ClientScript.RegisterStartupScript(GetType(), "YammerPopup", javascript, true);
+ this.MultiView1.SetActiveView(this.CompleteAuthorizationView);
+ }
+
+ protected void finishAuthorizationButton_Click(object sender, EventArgs e) {
+ if (!Page.IsValid) {
+ return;
+ }
+
+ var yammer = YammerConsumer.CreateConsumer(this.TokenManager);
+ var authorizationResponse = YammerConsumer.CompleteAuthorization(yammer, this.RequestToken, this.yammerUserCode.Text);
+ if (authorizationResponse != null) {
+ this.accessTokenLabel.Text = HttpUtility.HtmlEncode(authorizationResponse.AccessToken);
+ this.MultiView1.SetActiveView(this.AuthorizationCompleteView);
+ } else {
+ this.MultiView1.SetActiveView(this.BeginAuthorizationView);
+ this.authorizationErrorLabel.Visible = true;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumer/Yammer.aspx.designer.cs b/src/OAuth/OAuthConsumer/Yammer.aspx.designer.cs
new file mode 100644
index 0000000..57f6db5
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/Yammer.aspx.designer.cs
@@ -0,0 +1,123 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthConsumer {
+
+
+ public partial class Yammer {
+
+ /// <summary>
+ /// MultiView1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView MultiView1;
+
+ /// <summary>
+ /// ClientRegistrationRequiredView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View ClientRegistrationRequiredView;
+
+ /// <summary>
+ /// BeginAuthorizationView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View BeginAuthorizationView;
+
+ /// <summary>
+ /// authorizationErrorLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label authorizationErrorLabel;
+
+ /// <summary>
+ /// obtainAuthorizationButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button obtainAuthorizationButton;
+
+ /// <summary>
+ /// CompleteAuthorizationView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View CompleteAuthorizationView;
+
+ /// <summary>
+ /// yammerUserCode control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.TextBox yammerUserCode;
+
+ /// <summary>
+ /// finishAuthorizationButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button finishAuthorizationButton;
+
+ /// <summary>
+ /// AuthorizationCompleteView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View AuthorizationCompleteView;
+
+ /// <summary>
+ /// accessTokenLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label accessTokenLabel;
+
+ /// <summary>
+ /// getYammerMessagesButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button getYammerMessagesButton;
+
+ /// <summary>
+ /// resultsPlaceholder control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder resultsPlaceholder;
+ }
+}
diff --git a/src/OAuth/OAuthConsumer/favicon.ico b/src/OAuth/OAuthConsumer/favicon.ico
new file mode 100644
index 0000000..e227dbe
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/favicon.ico
Binary files differ
diff --git a/src/OAuth/OAuthConsumer/images/Sign-in-with-Twitter-darker.png b/src/OAuth/OAuthConsumer/images/Sign-in-with-Twitter-darker.png
new file mode 100644
index 0000000..746b6b9
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/images/Sign-in-with-Twitter-darker.png
Binary files differ
diff --git a/src/OAuth/OAuthConsumer/packages.config b/src/OAuth/OAuthConsumer/packages.config
new file mode 100644
index 0000000..56ae497
--- /dev/null
+++ b/src/OAuth/OAuthConsumer/packages.config
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CodeContracts.Unofficial" version="1.0.0.2" />
+ <package id="DotNetOpenAuth.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Common" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Consumer" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.ServiceProvider" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OpenId.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OpenIdOAuth" version="4.0.0.12084" />
+ <package id="log4net" version="2.0.0" />
+</packages> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/App.config b/src/OAuth/OAuthConsumerWpf/App.config
new file mode 100644
index 0000000..472f77a
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/App.config
@@ -0,0 +1,98 @@
+<?xml version="1.0"?>
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false"/>
+ <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+ <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true"/>
+ <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true"/>
+ <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true"/>
+ <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true"/>
+ </sectionGroup>
+ </configSections>
+
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <uri>
+ <idn enabled="All"/>
+ <iriParsing enabled="true"/>
+ </uri>
+
+ <system.net>
+ <defaultProxy enabled="true"/>
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <dotNetOpenAuth>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true"/>
+
+ <!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. -->
+ <messaging relaxSslRequirements="true"/>
+ </dotNetOpenAuth>
+
+ <appSettings>
+ <!-- Fill in your various consumer keys and secrets here to make the sample work. -->
+ <!-- You must get these values by signing up with each individual service provider. -->
+ <!-- Google sign-up: https://www.google.com/accounts/ManageDomains -->
+ <add key="googleConsumerKey" value="anonymous"/>
+ <!-- Google requires either a secret or an X.509 certificate. This sample will use
+ the certificate if it is specified, otherwise it will use the shared secret. -->
+ <add key="googleConsumerSecret" value="anonymous"/>
+ <add key="googleConsumerCertificateFile" value=""/>
+ <add key="googleConsumerCertificatePassword" value=""/>
+ </appSettings>
+
+ <log4net>
+ <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
+ <file value="Testing.log"/>
+ <appendToFile value="true"/>
+ <rollingStyle value="Size"/>
+ <maxSizeRollBackups value="10"/>
+ <maximumFileSize value="1024KB"/>
+ <staticLogFileName value="true"/>
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
+ </layout>
+ </appender>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO"/>
+ <appender-ref ref="RollingFileAppender"/>
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="ALL"/>
+ </logger>
+ </log4net>
+ <system.serviceModel>
+ <bindings>
+ <wsHttpBinding>
+ <binding name="WSHttpBinding_IDataApi" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+ <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
+ <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
+ <security mode="Message">
+ <transport clientCredentialType="Windows" proxyCredentialType="None" realm="">
+ <extendedProtectionPolicy policyEnforcement="Never"/>
+ </transport>
+ <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true"/>
+ </security>
+ </binding>
+ </wsHttpBinding>
+ </bindings>
+ <client>
+ <endpoint address="http://localhost:65169/DataApi.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDataApi" contract="WcfSampleService.IDataApi" name="WSHttpBinding_IDataApi">
+ <identity>
+ <dns value="localhost"/>
+ </identity>
+ </endpoint>
+ </client>
+ </system.serviceModel>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
diff --git a/src/OAuth/OAuthConsumerWpf/App.xaml b/src/OAuth/OAuthConsumerWpf/App.xaml
new file mode 100644
index 0000000..630ed5f
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/App.xaml
@@ -0,0 +1,8 @@
+<Application x:Class="OAuthConsumerWpf.App"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ StartupUri="MainWindow.xaml">
+ <Application.Resources>
+
+ </Application.Resources>
+</Application>
diff --git a/src/OAuth/OAuthConsumerWpf/App.xaml.cs b/src/OAuth/OAuthConsumerWpf/App.xaml.cs
new file mode 100644
index 0000000..1cfc286
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/App.xaml.cs
@@ -0,0 +1,14 @@
+namespace OAuthConsumerWpf {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Data;
+ using System.Linq;
+ using System.Windows;
+
+ /// <summary>
+ /// Interaction logic for App.xaml
+ /// </summary>
+ public partial class App : Application {
+ }
+}
diff --git a/src/OAuth/OAuthConsumerWpf/Authorize.xaml b/src/OAuth/OAuthConsumerWpf/Authorize.xaml
new file mode 100644
index 0000000..5aa2349
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Authorize.xaml
@@ -0,0 +1,12 @@
+<Window x:Class="DotNetOpenAuth.Samples.OAuthConsumerWpf.Authorize"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ Title="Authorize" Width="300" ShowInTaskbar="False">
+ <StackPanel>
+ <TextBlock TextWrapping="Wrap">Complete authorization at your service provider,
+ then enter the verification code below and click Finish:</TextBlock>
+ <TextBox Name="verifierBox"/>
+ <Button Name="finishButton" Click="finishButton_Click">Finish</Button>
+ <Button Name="cancelButton" Click="cancelButton_Click">Cancel</Button>
+ </StackPanel>
+</Window>
diff --git a/src/OAuth/OAuthConsumerWpf/Authorize.xaml.cs b/src/OAuth/OAuthConsumerWpf/Authorize.xaml.cs
new file mode 100644
index 0000000..4ed1932
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Authorize.xaml.cs
@@ -0,0 +1,58 @@
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Threading;
+ using System.Windows;
+ using System.Windows.Controls;
+ using System.Windows.Data;
+ using System.Windows.Documents;
+ using System.Windows.Input;
+ using System.Windows.Media;
+ using System.Windows.Media.Imaging;
+ using System.Windows.Shapes;
+ using System.Xml.Linq;
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.OAuth;
+
+ /// <summary>
+ /// Interaction logic for Authorize.xaml
+ /// </summary>
+ public partial class Authorize : Window {
+ private DesktopConsumer consumer;
+ private string requestToken;
+
+ internal Authorize(DesktopConsumer consumer, FetchUri fetchUriCallback) {
+ this.InitializeComponent();
+
+ this.consumer = consumer;
+ Cursor original = this.Cursor;
+ this.Cursor = Cursors.Wait;
+ ThreadPool.QueueUserWorkItem(delegate(object state) {
+ Uri browserAuthorizationLocation = fetchUriCallback(this.consumer, out this.requestToken);
+ System.Diagnostics.Process.Start(browserAuthorizationLocation.AbsoluteUri);
+ this.Dispatcher.BeginInvoke(new Action(() => {
+ this.Cursor = original;
+ finishButton.IsEnabled = true;
+ }));
+ });
+ }
+
+ internal delegate Uri FetchUri(DesktopConsumer consumer, out string requestToken);
+
+ internal string AccessToken { get; set; }
+
+ private void finishButton_Click(object sender, RoutedEventArgs e) {
+ var grantedAccess = this.consumer.ProcessUserAuthorization(this.requestToken, this.verifierBox.Text);
+ this.AccessToken = grantedAccess.AccessToken;
+ DialogResult = true;
+ Close();
+ }
+
+ private void cancelButton_Click(object sender, RoutedEventArgs e) {
+ DialogResult = false;
+ Close();
+ }
+ }
+}
diff --git a/src/OAuth/OAuthConsumerWpf/Authorize2.xaml b/src/OAuth/OAuthConsumerWpf/Authorize2.xaml
new file mode 100644
index 0000000..b4bb9d8
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Authorize2.xaml
@@ -0,0 +1,11 @@
+<Window x:Class="DotNetOpenAuth.Samples.OAuthConsumerWpf.Authorize2"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:oauth2="clr-namespace:DotNetOpenAuth.OAuth2;assembly=DotNetOpenAuth.OAuth2.Client.UI"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ Title="Authorize" Height="500" Width="500">
+ <DockPanel LastChildFill="True">
+ <WindowsFormsHost>
+ <oauth2:ClientAuthorizationView x:Name="clientAuthorizationView" Completed="clientAuthorizationView_Completed" />
+ </WindowsFormsHost>
+ </DockPanel>
+</Window>
diff --git a/src/OAuth/OAuthConsumerWpf/Authorize2.xaml.cs b/src/OAuth/OAuthConsumerWpf/Authorize2.xaml.cs
new file mode 100644
index 0000000..64a10e2
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Authorize2.xaml.cs
@@ -0,0 +1,26 @@
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf {
+
+ using System.Windows;
+ using DotNetOpenAuth.OAuth2;
+
+ /// <summary>
+ /// Interaction logic for Authorize2.xaml
+ /// </summary>
+ public partial class Authorize2 : Window {
+ internal Authorize2(UserAgentClient client) {
+ //System.Diagnostics.Contracts.Contract.Requires(client != null, "client");
+
+ this.InitializeComponent();
+ this.clientAuthorizationView.Client = client;
+ }
+
+ public IAuthorizationState Authorization {
+ get { return this.clientAuthorizationView.Authorization; }
+ }
+
+ private void clientAuthorizationView_Completed(object sender, ClientAuthorizationCompleteEventArgs e) {
+ this.DialogResult = e.Authorization != null;
+ this.Close();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/InMemoryTokenManager.cs b/src/OAuth/OAuthConsumerWpf/InMemoryTokenManager.cs
new file mode 100644
index 0000000..5266404
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/InMemoryTokenManager.cs
@@ -0,0 +1,58 @@
+//-----------------------------------------------------------------------
+// <copyright file="InMemoryTokenManager.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ internal class InMemoryTokenManager : IConsumerTokenManager {
+ private Dictionary<string, string> tokensAndSecrets = new Dictionary<string, string>();
+
+ internal InMemoryTokenManager() {
+ }
+
+ public string ConsumerKey { get; internal set; }
+
+ public string ConsumerSecret { get; internal set; }
+
+ #region ITokenManager Members
+
+ public string GetConsumerSecret(string consumerKey) {
+ if (consumerKey == this.ConsumerKey) {
+ return this.ConsumerSecret;
+ } else {
+ throw new ArgumentException("Unrecognized consumer key.", "consumerKey");
+ }
+ }
+
+ public string GetTokenSecret(string token) {
+ return this.tokensAndSecrets[token];
+ }
+
+ public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) {
+ this.tokensAndSecrets[response.Token] = response.TokenSecret;
+ }
+
+ public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) {
+ this.tokensAndSecrets.Remove(requestToken);
+ this.tokensAndSecrets[accessToken] = accessTokenSecret;
+ }
+
+ /// <summary>
+ /// Classifies a token as a request token or an access token.
+ /// </summary>
+ /// <param name="token">The token to classify.</param>
+ /// <returns>Request or Access token, or invalid if the token is not recognized.</returns>
+ public TokenType GetTokenType(string token) {
+ throw new NotImplementedException();
+ }
+
+ #endregion
+ }
+}
diff --git a/src/OAuth/OAuthConsumerWpf/MainWindow.xaml b/src/OAuth/OAuthConsumerWpf/MainWindow.xaml
new file mode 100644
index 0000000..48eb0c4
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/MainWindow.xaml
@@ -0,0 +1,195 @@
+<Window x:Class="DotNetOpenAuth.Samples.OAuthConsumerWpf.MainWindow"
+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ Title="DotNetOpenAuth Consumer (sample)" Height="400" Width="442">
+ <TabControl Name="outerTabControl" Margin="0,10,0,0">
+ <TabItem Header="Google" Name="googleTab">
+ <Grid Margin="5">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <Button Grid.Column="1" Grid.Row="3" Name="beginAuthorizationButton" Click="beginAuthorizationButton_Click">Authorize</Button>
+ <TabControl Grid.ColumnSpan="2" Grid.Row="4" Name="tabControl1" Margin="0,10,0,0">
+ <TabItem Header="Gmail Contacts" Name="gmailContactsTab">
+ <Grid Name="contactsGrid">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="Auto" />
+ </Grid.ColumnDefinitions>
+ </Grid>
+ </TabItem>
+ <TabItem Header="Blogger" Name="bloggerTab">
+ <Grid>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition Width="*" />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ </Grid.RowDefinitions>
+ <Label>Blog URL</Label>
+ <TextBox Grid.Column="1" x:Name="blogUrlBox"/>
+ <Label Grid.Row="1">Title</Label>
+ <TextBox Grid.Row="1" Grid.Column="1" x:Name="postTitleBox">OAuth Rocks!</TextBox>
+ <Label Grid.Row="2">Body</Label>
+ <TextBox Grid.Row="2" Grid.Column="1" x:Name="postBodyBox" AcceptsReturn="True" AcceptsTab="True" AutoWordSelection="True" TextWrapping="WrapWithOverflow">&lt;p xmlns="http://www.w3.org/1999/xhtml"&gt;Oauth is cool&lt;/p&gt;</TextBox>
+ <Button x:Name="postButton" Grid.Row="3" Grid.Column="1" Click="postButton_Click" IsEnabled="False">Post</Button>
+ </Grid>
+ </TabItem>
+ </TabControl>
+ </Grid>
+ </TabItem>
+ <TabItem Header="WCF sample">
+ <Grid Margin="5">
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="Auto" />
+ <ColumnDefinition />
+ </Grid.ColumnDefinitions>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition Height="Auto" />
+ <RowDefinition />
+ </Grid.RowDefinitions>
+ <Button Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Name="beginWcfAuthorizationButton" Click="beginWcfAuthorizationButton_Click">Authorize</Button>
+ <Label Content="Name" Grid.Row="1" />
+ <Label Grid.Row="1" Grid.Column="1" Name="wcfName" />
+ <Label Content="Age" Grid.Row="2" />
+ <Label Grid.Row="2" Grid.Column="1" Name="wcfAge" />
+ <Label Content="Favorite sites" Grid.Row="3" />
+ <Label Grid.Row="3" Grid.Column="1" Name="wcfFavoriteSites" />
+ </Grid>
+ </TabItem>
+ <TabItem Header="Generic 1.0(a)">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="auto" />
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="auto" />
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="0">Request Token URL</Label>
+ <TextBox Grid.Column="1" x:Name="requestTokenUrlBox" />
+ <ComboBox Grid.Column="2" x:Name="requestTokenHttpMethod" SelectedIndex="1">
+ <ComboBox.Items>
+ <ComboBoxItem>GET</ComboBoxItem>
+ <ComboBoxItem>POST</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="1">Authorize URL</Label>
+ <TextBox Grid.Row="1" Grid.Column="1" x:Name="authorizeUrlBox" />
+ <Label Grid.Row="1" Grid.Column="2">GET</Label>
+ <Label Grid.Row="2">Access Token URL</Label>
+ <TextBox Grid.Row="2" Grid.Column="1" x:Name="accessTokenUrlBox" />
+ <ComboBox Grid.Row="2" Grid.Column="2" x:Name="accessTokenHttpMethod" SelectedIndex="1">
+ <ComboBox.Items>
+ <ComboBoxItem>GET</ComboBoxItem>
+ <ComboBoxItem>POST</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="3">Resource URL</Label>
+ <TextBox Grid.Row="3" Grid.Column="1" x:Name="resourceUrlBox" />
+ <ComboBox Grid.Row="3" Grid.Column="2" x:Name="resourceHttpMethodList" SelectedIndex="0">
+ <ComboBox.Items>
+ <ComboBoxItem>GET w/ header</ComboBoxItem>
+ <ComboBoxItem>GET w/ querystring</ComboBoxItem>
+ <ComboBoxItem>POST</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="4">Consumer key</Label>
+ <TextBox Grid.Row="4" Grid.Column="1" x:Name="consumerKeyBox" Grid.ColumnSpan="2"/>
+ <Label Grid.Row="5">Consumer secret</Label>
+ <TextBox Grid.Row="5" Grid.Column="1" x:Name="consumerSecretBox" Grid.ColumnSpan="2"/>
+ <Label Grid.Row="6">OAuth version</Label>
+ <ComboBox Grid.Row="6" Grid.Column="1" SelectedIndex="1" x:Name="oauthVersion">
+ <ComboBox.Items>
+ <ComboBoxItem>1.0</ComboBoxItem>
+ <ComboBoxItem>1.0a</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Button Grid.Row="7" Grid.Column="1" x:Name="beginButton" Click="beginButton_Click">Begin</Button>
+ <TextBox Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="3" Name="resultsBox" IsReadOnly="True" />
+ </Grid>
+ </TabItem>
+ <TabItem Header="Generic 2.0">
+ <Grid>
+ <Grid.RowDefinitions>
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="auto" />
+ <RowDefinition Height="*" />
+ </Grid.RowDefinitions>
+ <Grid.ColumnDefinitions>
+ <ColumnDefinition Width="auto" />
+ <ColumnDefinition Width="*" />
+ <ColumnDefinition Width="auto" />
+ </Grid.ColumnDefinitions>
+ <Label Grid.Row="1" TabIndex="202">Token Endpoint URL</Label>
+ <TextBox Grid.Row="1" Grid.Column="1" x:Name="oauth2TokenEndpointBox" Text="http://localhost:18916/OAuthTokenEndpoint.ashx" TabIndex="203" />
+ <Label Grid.Row="1" Grid.Column="2" TabIndex="204">POST</Label>
+ <Label Grid.Row="2" TabIndex="205">User Authorization URL</Label>
+ <TextBox Grid.Row="2" Grid.Column="1" x:Name="oauth2AuthorizationUrlBox" Text="http://localhost:18916/Account/Authorize" TabIndex="206" />
+ <Label Grid.Row="2" Grid.Column="2" TabIndex="207">GET</Label>
+ <Label Grid.Row="0" TabIndex="200">Grant Type</Label>
+ <ComboBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" x:Name="flowBox" SelectedIndex="0" TabIndex="201">
+ <ComboBox.Items>
+ <ComboBoxItem>Authorization Code</ComboBoxItem>
+ <ComboBoxItem>Implicit Grant</ComboBoxItem>
+ <ComboBoxItem>Resource Owner Password Credentials</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="3" TabIndex="207">Resource URL</Label>
+ <TextBox Grid.Row="3" Grid.Column="1" x:Name="oauth2ResourceUrlBox" Text="http://localhost:18916/" TabIndex="208" />
+ <ComboBox Grid.Row="3" Grid.Column="2" x:Name="oauth2ResourceHttpMethodList" SelectedIndex="0" TabIndex="209">
+ <ComboBox.Items>
+ <ComboBoxItem>GET w/ header</ComboBoxItem>
+ <ComboBoxItem>GET w/ querystring</ComboBoxItem>
+ <ComboBoxItem>POST</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Label Grid.Row="4" TabIndex="210">Client Identifier</Label>
+ <TextBox Grid.Row="4" Grid.Column="1" x:Name="oauth2ClientIdentifierBox" Grid.ColumnSpan="2" Text="a" TabIndex="211" />
+ <Label Grid.Row="5" TabIndex="212">Client Secret</Label>
+ <TextBox Grid.Row="5" Grid.Column="1" x:Name="oauth2ClientSecretBox" Grid.ColumnSpan="2" Text="b" TabIndex="213" />
+ <Label Grid.Row="6" TabIndex="214">Scope</Label>
+ <TextBox Grid.Row="6" Grid.Column="1" x:Name="oauth2ScopeBox" TabIndex="215" Text="some scope" />
+ <Label Grid.Row="7" TabIndex="216">OAuth 2.0 version</Label>
+ <ComboBox Grid.Row="7" Grid.Column="1" SelectedIndex="0" x:Name="oauth2Version" TabIndex="217">
+ <ComboBox.Items>
+ <ComboBoxItem>2.0 DRAFT 16</ComboBoxItem>
+ </ComboBox.Items>
+ </ComboBox>
+ <Button Grid.Row="8" Grid.Column="1" x:Name="oauth2BeginButton" Click="oauth2BeginButton_Click" TabIndex="218">Begin</Button>
+ <TextBox Grid.Column="0" Grid.Row="9" Grid.ColumnSpan="3" Name="oauth2ResultsBox" IsReadOnly="True" TabIndex="219" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"/>
+ </Grid>
+ </TabItem>
+ </TabControl>
+</Window>
diff --git a/src/OAuth/OAuthConsumerWpf/MainWindow.xaml.cs b/src/OAuth/OAuthConsumerWpf/MainWindow.xaml.cs
new file mode 100644
index 0000000..310c2c6
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/MainWindow.xaml.cs
@@ -0,0 +1,233 @@
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.Diagnostics;
+ using System.IO;
+ using System.Linq;
+ using System.Net;
+ using System.Security.Cryptography.X509Certificates;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.Windows;
+ using System.Windows.Controls;
+ using System.Xml.Linq;
+
+ using DotNetOpenAuth.ApplicationBlock;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.Samples.OAuthConsumerWpf.WcfSampleService;
+
+ using OAuth2;
+
+ using OAuth2 = DotNetOpenAuth.OAuth2;
+ using ProtocolVersion = DotNetOpenAuth.OAuth.ProtocolVersion;
+
+ /// <summary>
+ /// Interaction logic for MainWindow.xaml
+ /// </summary>
+ public partial class MainWindow : Window {
+ private InMemoryTokenManager googleTokenManager = new InMemoryTokenManager();
+ private DesktopConsumer google;
+ private string googleAccessToken;
+ private UserAgentClient wcf;
+ private IAuthorizationState wcfAccessToken;
+
+ public MainWindow() {
+ this.InitializeComponent();
+
+ this.InitializeGoogleConsumer();
+ this.InitializeWcfConsumer();
+ }
+
+ private void InitializeGoogleConsumer() {
+ this.googleTokenManager.ConsumerKey = ConfigurationManager.AppSettings["googleConsumerKey"];
+ this.googleTokenManager.ConsumerSecret = ConfigurationManager.AppSettings["googleConsumerSecret"];
+
+ string pfxFile = ConfigurationManager.AppSettings["googleConsumerCertificateFile"];
+ if (string.IsNullOrEmpty(pfxFile)) {
+ this.google = new DesktopConsumer(GoogleConsumer.ServiceDescription, this.googleTokenManager);
+ } else {
+ string pfxPassword = ConfigurationManager.AppSettings["googleConsumerCertificatePassword"];
+ var signingCertificate = new X509Certificate2(pfxFile, pfxPassword);
+ var service = GoogleConsumer.CreateRsaSha1ServiceDescription(signingCertificate);
+ this.google = new DesktopConsumer(service, this.googleTokenManager);
+ }
+ }
+
+ private void InitializeWcfConsumer() {
+ var authServer = new AuthorizationServerDescription() {
+ AuthorizationEndpoint = new Uri("http://localhost:50172/OAuth/Authorize"),
+ TokenEndpoint = new Uri("http://localhost:50172/OAuth/Token"),
+ };
+ this.wcf = new UserAgentClient(authServer, "sampleconsumer", "samplesecret");
+ }
+
+ private void beginAuthorizationButton_Click(object sender, RoutedEventArgs e) {
+ if (string.IsNullOrEmpty(this.googleTokenManager.ConsumerKey)) {
+ MessageBox.Show(this, "You must modify the App.config or OAuthConsumerWpf.exe.config file for this application to include your Google OAuth consumer key first.", "Configuration required", MessageBoxButton.OK, MessageBoxImage.Stop);
+ return;
+ }
+
+ var auth = new Authorize(
+ this.google,
+ (DesktopConsumer consumer, out string requestToken) =>
+ GoogleConsumer.RequestAuthorization(
+ consumer,
+ GoogleConsumer.Applications.Contacts | GoogleConsumer.Applications.Blogger,
+ out requestToken));
+ bool? result = auth.ShowDialog();
+ if (result.HasValue && result.Value) {
+ this.googleAccessToken = auth.AccessToken;
+ this.postButton.IsEnabled = true;
+
+ XDocument contactsDocument = GoogleConsumer.GetContacts(this.google, this.googleAccessToken, 25, 1);
+ var contacts = from entry in contactsDocument.Root.Elements(XName.Get("entry", "http://www.w3.org/2005/Atom"))
+ select new { Name = entry.Element(XName.Get("title", "http://www.w3.org/2005/Atom")).Value, Email = entry.Element(XName.Get("email", "http://schemas.google.com/g/2005")).Attribute("address").Value };
+ this.contactsGrid.Children.Clear();
+ foreach (var contact in contacts) {
+ this.contactsGrid.RowDefinitions.Add(new RowDefinition());
+ TextBlock name = new TextBlock { Text = contact.Name };
+ TextBlock email = new TextBlock { Text = contact.Email };
+ Grid.SetRow(name, this.contactsGrid.RowDefinitions.Count - 1);
+ Grid.SetRow(email, this.contactsGrid.RowDefinitions.Count - 1);
+ Grid.SetColumn(email, 1);
+ this.contactsGrid.Children.Add(name);
+ this.contactsGrid.Children.Add(email);
+ }
+ }
+ }
+
+ private void postButton_Click(object sender, RoutedEventArgs e) {
+ XElement postBodyXml = XElement.Parse(this.postBodyBox.Text);
+ GoogleConsumer.PostBlogEntry(this.google, this.googleAccessToken, this.blogUrlBox.Text, this.postTitleBox.Text, postBodyXml);
+ }
+
+ private void beginWcfAuthorizationButton_Click(object sender, RoutedEventArgs e) {
+ var auth = new Authorize2(this.wcf);
+ auth.Authorization.Scope.AddRange(OAuthUtilities.SplitScopes("http://tempuri.org/IDataApi/GetName http://tempuri.org/IDataApi/GetAge http://tempuri.org/IDataApi/GetFavoriteSites"));
+ auth.Authorization.Callback = new Uri("http://localhost:59721/");
+ auth.Owner = this;
+ bool? result = auth.ShowDialog();
+ if (result.HasValue && result.Value) {
+ this.wcfAccessToken = auth.Authorization;
+ this.wcfName.Content = this.CallService(client => client.GetName());
+ this.wcfAge.Content = this.CallService(client => client.GetAge());
+ this.wcfFavoriteSites.Content = this.CallService(client => string.Join(", ", client.GetFavoriteSites()));
+ }
+ }
+
+ private T CallService<T>(Func<DataApiClient, T> predicate) {
+ DataApiClient client = new DataApiClient();
+ if (this.wcfAccessToken == null) {
+ throw new InvalidOperationException("No access token!");
+ }
+
+ var httpRequest = (HttpWebRequest)WebRequest.Create(client.Endpoint.Address.Uri);
+ this.wcf.AuthorizeRequest(httpRequest, this.wcfAccessToken);
+
+ HttpRequestMessageProperty httpDetails = new HttpRequestMessageProperty();
+ httpDetails.Headers[HttpRequestHeader.Authorization] = httpRequest.Headers[HttpRequestHeader.Authorization];
+ using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) {
+ OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpDetails;
+ return predicate(client);
+ }
+ }
+
+ private void beginButton_Click(object sender, RoutedEventArgs e) {
+ try {
+ var service = new ServiceProviderDescription {
+ RequestTokenEndpoint = new MessageReceivingEndpoint(this.requestTokenUrlBox.Text, this.requestTokenHttpMethod.SelectedIndex == 0 ? HttpDeliveryMethods.GetRequest : HttpDeliveryMethods.PostRequest),
+ UserAuthorizationEndpoint = new MessageReceivingEndpoint(this.authorizeUrlBox.Text, HttpDeliveryMethods.GetRequest),
+ AccessTokenEndpoint = new MessageReceivingEndpoint(this.accessTokenUrlBox.Text, this.accessTokenHttpMethod.SelectedIndex == 0 ? HttpDeliveryMethods.GetRequest : HttpDeliveryMethods.PostRequest),
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] { new HmacSha1SigningBindingElement() },
+ ProtocolVersion = this.oauthVersion.SelectedIndex == 0 ? ProtocolVersion.V10 : ProtocolVersion.V10a,
+ };
+ var tokenManager = new InMemoryTokenManager();
+ tokenManager.ConsumerKey = this.consumerKeyBox.Text;
+ tokenManager.ConsumerSecret = this.consumerSecretBox.Text;
+
+ var consumer = new DesktopConsumer(service, tokenManager);
+ string accessToken;
+ if (service.ProtocolVersion == ProtocolVersion.V10) {
+ string requestToken;
+ Uri authorizeUrl = consumer.RequestUserAuthorization(null, null, out requestToken);
+ Process.Start(authorizeUrl.AbsoluteUri);
+ MessageBox.Show(this, "Click OK when you've authorized the app.");
+ var authorizationResponse = consumer.ProcessUserAuthorization(requestToken, null);
+ accessToken = authorizationResponse.AccessToken;
+ } else {
+ var authorizePopup = new Authorize(
+ consumer,
+ (DesktopConsumer c, out string requestToken) => c.RequestUserAuthorization(null, null, out requestToken));
+ authorizePopup.Owner = this;
+ bool? result = authorizePopup.ShowDialog();
+ if (result.HasValue && result.Value) {
+ accessToken = authorizePopup.AccessToken;
+ } else {
+ return;
+ }
+ }
+ HttpDeliveryMethods resourceHttpMethod = this.resourceHttpMethodList.SelectedIndex < 2 ? HttpDeliveryMethods.GetRequest : HttpDeliveryMethods.PostRequest;
+ if (this.resourceHttpMethodList.SelectedIndex == 1) {
+ resourceHttpMethod |= HttpDeliveryMethods.AuthorizationHeaderRequest;
+ }
+ var resourceEndpoint = new MessageReceivingEndpoint(this.resourceUrlBox.Text, resourceHttpMethod);
+ using (IncomingWebResponse resourceResponse = consumer.PrepareAuthorizedRequestAndSend(resourceEndpoint, accessToken)) {
+ this.resultsBox.Text = resourceResponse.GetResponseReader().ReadToEnd();
+ }
+ } catch (DotNetOpenAuth.Messaging.ProtocolException ex) {
+ MessageBox.Show(this, ex.Message);
+ }
+ }
+
+ private void oauth2BeginButton_Click(object sender, RoutedEventArgs e) {
+ var authServer = new DotNetOpenAuth.OAuth2.AuthorizationServerDescription {
+ AuthorizationEndpoint = new Uri(this.oauth2AuthorizationUrlBox.Text),
+ };
+ if (this.oauth2TokenEndpointBox.Text.Length > 0) {
+ authServer.TokenEndpoint = new Uri(this.oauth2TokenEndpointBox.Text);
+ }
+
+ try {
+ var client = new OAuth2.UserAgentClient(authServer, this.oauth2ClientIdentifierBox.Text, this.oauth2ClientSecretBox.Text);
+
+ var authorizePopup = new Authorize2(client);
+ authorizePopup.Authorization.Scope.AddRange(OAuthUtilities.SplitScopes(this.oauth2ScopeBox.Text));
+ authorizePopup.Owner = this;
+ bool? result = authorizePopup.ShowDialog();
+ if (result.HasValue && result.Value) {
+ var requestUri = new UriBuilder(this.oauth2ResourceUrlBox.Text);
+ if (this.oauth2ResourceHttpMethodList.SelectedIndex > 0) {
+ requestUri.AppendQueryArgument("access_token", authorizePopup.Authorization.AccessToken);
+ }
+
+ var request = (HttpWebRequest)WebRequest.Create(requestUri.Uri);
+ request.Method = this.oauth2ResourceHttpMethodList.SelectedIndex < 2 ? "GET" : "POST";
+ if (this.oauth2ResourceHttpMethodList.SelectedIndex == 0) {
+ client.AuthorizeRequest(request, authorizePopup.Authorization);
+ }
+
+ using (var resourceResponse = request.GetResponse()) {
+ using (var responseStream = new StreamReader(resourceResponse.GetResponseStream())) {
+ this.oauth2ResultsBox.Text = responseStream.ReadToEnd();
+ }
+ }
+ } else {
+ return;
+ }
+ } catch (Messaging.ProtocolException ex) {
+ MessageBox.Show(this, ex.Message);
+ } catch (WebException ex) {
+ string responseText = string.Empty;
+ if (ex.Response != null) {
+ using (var responseReader = new StreamReader(ex.Response.GetResponseStream())) {
+ responseText = responseReader.ReadToEnd();
+ }
+ }
+ MessageBox.Show(this, ex.Message + " " + responseText);
+ }
+ }
+ }
+}
diff --git a/src/OAuth/OAuthConsumerWpf/OAuthConsumerWpf.csproj b/src/OAuth/OAuthConsumerWpf/OAuthConsumerWpf.csproj
new file mode 100644
index 0000000..98e4a82
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/OAuthConsumerWpf.csproj
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{6EC36418-DBC5-4AD1-A402-413604AA7A08}</ProjectGuid>
+ <OutputType>WinExe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>DotNetOpenAuth.Samples.OAuthConsumerWpf</RootNamespace>
+ <AssemblyName>OAuthConsumerWpf</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <WarningLevel>4</WarningLevel>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <OldToolsVersion>3.5</OldToolsVersion>
+ <UpgradeBackupLocation />
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <TargetFrameworkProfile />
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <OutputPath>bin\CodeAnalysis\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DebugType>full</DebugType>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+ <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+ <ErrorReport>prompt</ErrorReport>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="DotNetOpenAuth.Core">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.Consumer">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Consumer.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.Consumer.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.Core.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2.Client">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.Client.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.Client.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2.Client.UI">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.Client.UI.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.Client.UI.dll</HintPath>
+ </Reference>
+ <Reference Include="log4net">
+ <HintPath>..\..\..\packages\log4net.2.0.0\lib\net35-full\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.Contracts">
+ <HintPath>..\..\..\packages\CodeContracts.Unofficial.1.0.0.2\lib\net35-client\Microsoft.Contracts.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.configuration" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Runtime.Serialization">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.ServiceModel">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ <Reference Include="WindowsFormsIntegration" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="UIAutomationProvider">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="WindowsBase">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="PresentationCore">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="PresentationFramework">
+ <RequiredTargetFramework>3.0</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xaml" Condition=" '$(TargetFrameworkVersion)' != 'v3.5' ">
+ <RequiredTargetFramework>4.0</RequiredTargetFramework>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <ApplicationDefinition Include="App.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </ApplicationDefinition>
+ <Page Include="Authorize.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Page Include="Authorize2.xaml">
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ </Page>
+ <Page Include="MainWindow.xaml">
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ <Generator>MSBuild:Compile</Generator>
+ <SubType>Designer</SubType>
+ </Page>
+ <Compile Include="App.xaml.cs">
+ <DependentUpon>App.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Authorize2.xaml.cs">
+ <DependentUpon>Authorize2.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="MainWindow.xaml.cs">
+ <DependentUpon>MainWindow.xaml</DependentUpon>
+ <SubType>Code</SubType>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Authorize.xaml.cs">
+ <DependentUpon>Authorize.xaml</DependentUpon>
+ </Compile>
+ <Compile Include="InMemoryTokenManager.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs">
+ <SubType>Code</SubType>
+ </Compile>
+ <Compile Include="Properties\Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\Settings.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DependentUpon>Settings.settings</DependentUpon>
+ <DesignTimeSharedInput>True</DesignTimeSharedInput>
+ </Compile>
+ <Compile Include="Service References\WcfSampleService\Reference.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Reference.svcmap</DependentUpon>
+ </Compile>
+ <EmbeddedResource Include="Properties\Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ </EmbeddedResource>
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ <None Include="Properties\Settings.settings">
+ <Generator>SettingsSingleFileGenerator</Generator>
+ <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+ </None>
+ <None Include="Service References\WcfSampleService\DataApi.wsdl" />
+ <None Include="Service References\WcfSampleService\DataApi.xsd" />
+ <None Include="Service References\WcfSampleService\DataApi1.xsd" />
+ <AppDesigner Include="Properties\" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\DotNetOpenAuth.ApplicationBlock\DotNetOpenAuth.ApplicationBlock.csproj">
+ <Project>{AA78D112-D889-414B-A7D4-467B34C7B663}</Project>
+ <Name>DotNetOpenAuth.ApplicationBlock</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <WCFMetadata Include="Service References\" />
+ </ItemGroup>
+ <ItemGroup>
+ <WCFMetadataStorage Include="Service References\WcfSampleService\" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Service References\WcfSampleService\DataApi.disco" />
+ <None Include="Service References\WcfSampleService\DataApi2.xsd" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Service References\WcfSampleService\configuration91.svcinfo" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Service References\WcfSampleService\configuration.svcinfo" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Service References\WcfSampleService\Reference.svcmap">
+ <Generator>WCF Proxy Generator</Generator>
+ <LastGenOutput>Reference.cs</LastGenOutput>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+</Project> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Properties/AssemblyInfo.cs b/src/OAuth/OAuthConsumerWpf/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..59ee9c9
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Properties/AssemblyInfo.cs
@@ -0,0 +1,48 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OAuthConsumerWpf")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OAuthConsumerWpf")]
+[assembly: AssemblyCopyright("Copyright © 2011 Outercurve Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: log4net.Config.XmlConfigurator(Watch = true)]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// In order to begin building localizable applications, set
+// <UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
+// inside a <PropertyGroup>. For example, if you are using US english
+// in your source files, set the <UICulture> to en-US. Then uncomment
+// the NeutralResourceLanguage attribute below. Update the "en-US" in
+// the line below to match the UICulture setting in the project file.
+
+////[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/OAuth/OAuthConsumerWpf/Properties/Resources.Designer.cs b/src/OAuth/OAuthConsumerWpf/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..84d1540
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.17379
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf.Properties {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DotNetOpenAuth.Samples.OAuthConsumerWpf.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+ }
+}
diff --git a/src/OAuth/OAuthConsumerWpf/Properties/Resources.resx b/src/OAuth/OAuthConsumerWpf/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+</root> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Properties/Settings.Designer.cs b/src/OAuth/OAuthConsumerWpf/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..582982a
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.17379
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf.Properties {
+
+
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+ internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+ private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+ public static Settings Default {
+ get {
+ return defaultInstance;
+ }
+ }
+ }
+}
diff --git a/src/OAuth/OAuthConsumerWpf/Properties/Settings.settings b/src/OAuth/OAuthConsumerWpf/Properties/Settings.settings
new file mode 100644
index 0000000..033d7a5
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+ <Profiles>
+ <Profile Name="(Default)" />
+ </Profiles>
+ <Settings />
+</SettingsFile> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.disco b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.disco
new file mode 100644
index 0000000..a3cecd3
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.disco
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<discovery xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/disco/">
+ <contractRef ref="http://localhost:65169/OAuthServiceProvider/DataApi.svc?wsdl" docRef="http://localhost:65169/OAuthServiceProvider/DataApi.svc" xmlns="http://schemas.xmlsoap.org/disco/scl/" />
+</discovery> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.wsdl b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.wsdl
new file mode 100644
index 0000000..46a07e1
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.wsdl
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="utf-8"?>
+<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:wsap="http://schemas.xmlsoap.org/ws/2004/08/addressing/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msc="http://schemas.microsoft.com/ws/2005/12/wsdl/contract" xmlns:tns="http://tempuri.org/" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsa10="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" name="DataApi" targetNamespace="http://tempuri.org/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SymmetricBinding xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:ProtectionToken>
+ <wsp:Policy>
+ <sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:RequireDerivedKeys />
+ <sp:BootstrapPolicy>
+ <wsp:Policy>
+ <sp:SignedParts>
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts>
+ <sp:Body />
+ </sp:EncryptedParts>
+ <sp:SymmetricBinding>
+ <wsp:Policy>
+ <sp:ProtectionToken>
+ <wsp:Policy>
+ <sp:SpnegoContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:RequireDerivedKeys />
+ </wsp:Policy>
+ </sp:SpnegoContextToken>
+ </wsp:Policy>
+ </sp:ProtectionToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Strict />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:EncryptSignature />
+ <sp:OnlySignEntireHeadersAndBody />
+ </wsp:Policy>
+ </sp:SymmetricBinding>
+ <sp:Wss11>
+ <wsp:Policy>
+ <sp:MustSupportRefKeyIdentifier />
+ <sp:MustSupportRefIssuerSerial />
+ <sp:MustSupportRefThumbprint />
+ <sp:MustSupportRefEncryptedKey />
+ </wsp:Policy>
+ </sp:Wss11>
+ <sp:Trust10>
+ <wsp:Policy>
+ <sp:MustSupportIssuedTokens />
+ <sp:RequireClientEntropy />
+ <sp:RequireServerEntropy />
+ </wsp:Policy>
+ </sp:Trust10>
+ </wsp:Policy>
+ </sp:BootstrapPolicy>
+ </wsp:Policy>
+ </sp:SecureConversationToken>
+ </wsp:Policy>
+ </sp:ProtectionToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Strict />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:EncryptSignature />
+ <sp:OnlySignEntireHeadersAndBody />
+ </wsp:Policy>
+ </sp:SymmetricBinding>
+ <sp:Wss11 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:MustSupportRefKeyIdentifier />
+ <sp:MustSupportRefIssuerSerial />
+ <sp:MustSupportRefThumbprint />
+ <sp:MustSupportRefEncryptedKey />
+ </wsp:Policy>
+ </sp:Wss11>
+ <sp:Trust10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:MustSupportIssuedTokens />
+ <sp:RequireClientEntropy />
+ <sp:RequireServerEntropy />
+ </wsp:Policy>
+ </sp:Trust10>
+ <wsaw:UsingAddressing />
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetAge_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetAge_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetName_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetName_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetFavoriteSites_Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsp:Policy wsu:Id="WSHttpBinding_IDataApi_GetFavoriteSites_output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+ <wsdl:types>
+ <xsd:schema targetNamespace="http://tempuri.org/Imports">
+ <xsd:import schemaLocation="http://localhost:65169/OAuthServiceProvider/DataApi.svc?xsd=xsd0" namespace="http://tempuri.org/" />
+ <xsd:import schemaLocation="http://localhost:65169/OAuthServiceProvider/DataApi.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
+ <xsd:import schemaLocation="http://localhost:65169/OAuthServiceProvider/DataApi.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
+ </xsd:schema>
+ </wsdl:types>
+ <wsdl:message name="IDataApi_GetAge_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetAge" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetAge_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetAgeResponse" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetName_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetName" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetName_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetNameResponse" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetFavoriteSites_InputMessage">
+ <wsdl:part name="parameters" element="tns:GetFavoriteSites" />
+ </wsdl:message>
+ <wsdl:message name="IDataApi_GetFavoriteSites_OutputMessage">
+ <wsdl:part name="parameters" element="tns:GetFavoriteSitesResponse" />
+ </wsdl:message>
+ <wsdl:portType name="IDataApi">
+ <wsdl:operation name="GetAge">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetAge" message="tns:IDataApi_GetAge_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetAgeResponse" message="tns:IDataApi_GetAge_OutputMessage" />
+ </wsdl:operation>
+ <wsdl:operation name="GetName">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetName" message="tns:IDataApi_GetName_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetNameResponse" message="tns:IDataApi_GetName_OutputMessage" />
+ </wsdl:operation>
+ <wsdl:operation name="GetFavoriteSites">
+ <wsdl:input wsaw:Action="http://tempuri.org/IDataApi/GetFavoriteSites" message="tns:IDataApi_GetFavoriteSites_InputMessage" />
+ <wsdl:output wsaw:Action="http://tempuri.org/IDataApi/GetFavoriteSitesResponse" message="tns:IDataApi_GetFavoriteSites_OutputMessage" />
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="WSHttpBinding_IDataApi" type="tns:IDataApi">
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_policy" />
+ <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
+ <wsdl:operation name="GetAge">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetAge" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetAge_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetAge_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetName">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetName" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetName_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetName_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ <wsdl:operation name="GetFavoriteSites">
+ <soap12:operation soapAction="http://tempuri.org/IDataApi/GetFavoriteSites" style="document" />
+ <wsdl:input>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetFavoriteSites_Input_policy" />
+ <soap12:body use="literal" />
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#WSHttpBinding_IDataApi_GetFavoriteSites_output_policy" />
+ <soap12:body use="literal" />
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="DataApi">
+ <wsdl:port name="WSHttpBinding_IDataApi" binding="tns:WSHttpBinding_IDataApi">
+ <soap12:address location="http://localhost:65169/OAuthServiceProvider/DataApi.svc" />
+ <wsa10:EndpointReference>
+ <wsa10:Address>http://localhost:65169/OAuthServiceProvider/DataApi.svc</wsa10:Address>
+ <Identity xmlns="http://schemas.xmlsoap.org/ws/2006/02/addressingidentity">
+ <Dns>localhost</Dns>
+ </Identity>
+ </wsa10:EndpointReference>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.xsd b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.xsd
new file mode 100644
index 0000000..04a74a4
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi.xsd
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/Arrays" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType name="ArrayOfstring">
+ <xs:sequence>
+ <xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="ArrayOfstring" nillable="true" type="tns:ArrayOfstring" />
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi1.xsd b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi1.xsd
new file mode 100644
index 0000000..bcb9ef8
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi1.xsd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://tempuri.org/" elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:import schemaLocation="http://localhost:65169/OAuthServiceProvider/DataApi.svc?xsd=xsd2" namespace="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
+ <xs:element name="GetAge">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetAgeResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="GetAgeResult" nillable="true" type="xs:int" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetName">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetNameResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element minOccurs="0" name="GetNameResult" nillable="true" type="xs:string" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetFavoriteSites">
+ <xs:complexType>
+ <xs:sequence />
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="GetFavoriteSitesResponse">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" minOccurs="0" name="GetFavoriteSitesResult" nillable="true" type="q1:ArrayOfstring" />
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi2.xsd b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi2.xsd
new file mode 100644
index 0000000..d58e7f3
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/DataApi2.xsd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:tns="http://schemas.microsoft.com/2003/10/Serialization/" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://schemas.microsoft.com/2003/10/Serialization/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="anyType" nillable="true" type="xs:anyType" />
+ <xs:element name="anyURI" nillable="true" type="xs:anyURI" />
+ <xs:element name="base64Binary" nillable="true" type="xs:base64Binary" />
+ <xs:element name="boolean" nillable="true" type="xs:boolean" />
+ <xs:element name="byte" nillable="true" type="xs:byte" />
+ <xs:element name="dateTime" nillable="true" type="xs:dateTime" />
+ <xs:element name="decimal" nillable="true" type="xs:decimal" />
+ <xs:element name="double" nillable="true" type="xs:double" />
+ <xs:element name="float" nillable="true" type="xs:float" />
+ <xs:element name="int" nillable="true" type="xs:int" />
+ <xs:element name="long" nillable="true" type="xs:long" />
+ <xs:element name="QName" nillable="true" type="xs:QName" />
+ <xs:element name="short" nillable="true" type="xs:short" />
+ <xs:element name="string" nillable="true" type="xs:string" />
+ <xs:element name="unsignedByte" nillable="true" type="xs:unsignedByte" />
+ <xs:element name="unsignedInt" nillable="true" type="xs:unsignedInt" />
+ <xs:element name="unsignedLong" nillable="true" type="xs:unsignedLong" />
+ <xs:element name="unsignedShort" nillable="true" type="xs:unsignedShort" />
+ <xs:element name="char" nillable="true" type="tns:char" />
+ <xs:simpleType name="char">
+ <xs:restriction base="xs:int" />
+ </xs:simpleType>
+ <xs:element name="duration" nillable="true" type="tns:duration" />
+ <xs:simpleType name="duration">
+ <xs:restriction base="xs:duration">
+ <xs:pattern value="\-?P(\d*D)?(T(\d*H)?(\d*M)?(\d*(\.\d*)?S)?)?" />
+ <xs:minInclusive value="-P10675199DT2H48M5.4775808S" />
+ <xs:maxInclusive value="P10675199DT2H48M5.4775807S" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:element name="guid" nillable="true" type="tns:guid" />
+ <xs:simpleType name="guid">
+ <xs:restriction base="xs:string">
+ <xs:pattern value="[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}" />
+ </xs:restriction>
+ </xs:simpleType>
+ <xs:attribute name="FactoryType" type="xs:QName" />
+ <xs:attribute name="Id" type="xs:ID" />
+ <xs:attribute name="Ref" type="xs:IDREF" />
+</xs:schema> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/Reference.cs b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/Reference.cs
new file mode 100644
index 0000000..47a35ea
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/Reference.cs
@@ -0,0 +1,67 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.17379
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace DotNetOpenAuth.Samples.OAuthConsumerWpf.WcfSampleService {
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ [System.ServiceModel.ServiceContractAttribute(ConfigurationName="WcfSampleService.IDataApi")]
+ public interface IDataApi {
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetAge", ReplyAction="http://tempuri.org/IDataApi/GetAgeResponse")]
+ System.Nullable<int> GetAge();
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetName", ReplyAction="http://tempuri.org/IDataApi/GetNameResponse")]
+ string GetName();
+
+ [System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IDataApi/GetFavoriteSites", ReplyAction="http://tempuri.org/IDataApi/GetFavoriteSitesResponse")]
+ string[] GetFavoriteSites();
+ }
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ public interface IDataApiChannel : DotNetOpenAuth.Samples.OAuthConsumerWpf.WcfSampleService.IDataApi, System.ServiceModel.IClientChannel {
+ }
+
+ [System.Diagnostics.DebuggerStepThroughAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
+ public partial class DataApiClient : System.ServiceModel.ClientBase<DotNetOpenAuth.Samples.OAuthConsumerWpf.WcfSampleService.IDataApi>, DotNetOpenAuth.Samples.OAuthConsumerWpf.WcfSampleService.IDataApi {
+
+ public DataApiClient() {
+ }
+
+ public DataApiClient(string endpointConfigurationName) :
+ base(endpointConfigurationName) {
+ }
+
+ public DataApiClient(string endpointConfigurationName, string remoteAddress) :
+ base(endpointConfigurationName, remoteAddress) {
+ }
+
+ public DataApiClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
+ base(endpointConfigurationName, remoteAddress) {
+ }
+
+ public DataApiClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
+ base(binding, remoteAddress) {
+ }
+
+ public System.Nullable<int> GetAge() {
+ return base.Channel.GetAge();
+ }
+
+ public string GetName() {
+ return base.Channel.GetName();
+ }
+
+ public string[] GetFavoriteSites() {
+ return base.Channel.GetFavoriteSites();
+ }
+ }
+}
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/Reference.svcmap b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/Reference.svcmap
new file mode 100644
index 0000000..60bdc90
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/Reference.svcmap
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ReferenceGroup xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ID="2ed8bfde-ddd6-4e80-8c91-c4c0ee21026d" xmlns="urn:schemas-microsoft-com:xml-wcfservicemap">
+ <ClientOptions>
+ <GenerateAsynchronousMethods>false</GenerateAsynchronousMethods>
+ <EnableDataBinding>true</EnableDataBinding>
+ <ExcludedTypes />
+ <ImportXmlTypes>false</ImportXmlTypes>
+ <GenerateInternalTypes>false</GenerateInternalTypes>
+ <GenerateMessageContracts>false</GenerateMessageContracts>
+ <NamespaceMappings />
+ <CollectionMappings />
+ <GenerateSerializableTypes>true</GenerateSerializableTypes>
+ <Serializer>Auto</Serializer>
+ <ReferenceAllAssemblies>true</ReferenceAllAssemblies>
+ <ReferencedAssemblies />
+ <ReferencedDataContractTypes />
+ <ServiceContractMappings />
+ </ClientOptions>
+ <MetadataSources>
+ <MetadataSource Address="http://localhost:65169/OAuthServiceProvider/DataApi.svc" Protocol="http" SourceId="1" />
+ </MetadataSources>
+ <Metadata>
+ <MetadataFile FileName="DataApi.wsdl" MetadataType="Wsdl" ID="3e4bf2a2-224e-4651-bbfb-67b29c58b1e8" SourceId="1" SourceUrl="http://localhost:65169/OAuthServiceProvider/DataApi.svc?wsdl" />
+ <MetadataFile FileName="DataApi.xsd" MetadataType="Schema" ID="431abff0-dec3-4e99-9173-9f8b69a27f94" SourceId="1" SourceUrl="http://localhost:65169/OAuthServiceProvider/DataApi.svc?xsd=xsd2" />
+ <MetadataFile FileName="DataApi1.xsd" MetadataType="Schema" ID="150d6701-aa42-49bc-8042-108207e19493" SourceId="1" SourceUrl="http://localhost:65169/OAuthServiceProvider/DataApi.svc?xsd=xsd0" />
+ <MetadataFile FileName="DataApi.disco" MetadataType="Disco" ID="d9c6ecfd-3dc0-4b71-80ba-b2b25c42238a" SourceId="1" SourceUrl="http://localhost:65169/OAuthServiceProvider/DataApi.svc?disco" />
+ <MetadataFile FileName="DataApi2.xsd" MetadataType="Schema" ID="3f8e1950-7d27-4def-acf9-8e1a0e4e03df" SourceId="1" SourceUrl="http://localhost:65169/OAuthServiceProvider/DataApi.svc?xsd=xsd1" />
+ </Metadata>
+ <Extensions>
+ <ExtensionFile FileName="configuration91.svcinfo" Name="configuration91.svcinfo" />
+ <ExtensionFile FileName="configuration.svcinfo" Name="configuration.svcinfo" />
+ </Extensions>
+</ReferenceGroup> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/configuration.svcinfo b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/configuration.svcinfo
new file mode 100644
index 0000000..83fa826
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/configuration.svcinfo
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configurationSnapshot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:schemas-microsoft-com:xml-wcfconfigurationsnapshot">
+ <behaviors />
+ <bindings>
+ <binding digest="System.ServiceModel.Configuration.WSHttpBindingElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089:&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data hostNameComparisonMode=&quot;StrongWildcard&quot; messageEncoding=&quot;Text&quot; name=&quot;WSHttpBinding_IDataApi&quot; textEncoding=&quot;utf-8&quot; transactionFlow=&quot;false&quot;&gt;&lt;readerQuotas maxArrayLength=&quot;16384&quot; maxBytesPerRead=&quot;4096&quot; maxDepth=&quot;32&quot; maxNameTableCharCount=&quot;16384&quot; maxStringContentLength=&quot;8192&quot; /&gt;&lt;reliableSession enabled=&quot;false&quot; inactivityTimeout=&quot;00:10:00&quot; ordered=&quot;true&quot; /&gt;&lt;security mode=&quot;Message&quot;&gt;&lt;message algorithmSuite=&quot;Default&quot; clientCredentialType=&quot;Windows&quot; establishSecurityContext=&quot;true&quot; negotiateServiceCredential=&quot;true&quot; /&gt;&lt;transport clientCredentialType=&quot;Windows&quot; proxyCredentialType=&quot;None&quot; realm=&quot;&quot; /&gt;&lt;/security&gt;&lt;/Data&gt;" bindingType="wsHttpBinding" name="WSHttpBinding_IDataApi" />
+ </bindings>
+ <endpoints>
+ <endpoint normalizedDigest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://localhost:65169/OAuthServiceProvider/DataApi.svc&quot; binding=&quot;wsHttpBinding&quot; bindingConfiguration=&quot;WSHttpBinding_IDataApi&quot; contract=&quot;WcfSampleService.IDataApi&quot; name=&quot;WSHttpBinding_IDataApi&quot;&gt;&lt;identity&gt;&lt;dns value=&quot;localhost&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" digest="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-16&quot;?&gt;&lt;Data address=&quot;http://localhost:65169/OAuthServiceProvider/DataApi.svc&quot; binding=&quot;wsHttpBinding&quot; bindingConfiguration=&quot;WSHttpBinding_IDataApi&quot; contract=&quot;WcfSampleService.IDataApi&quot; name=&quot;WSHttpBinding_IDataApi&quot;&gt;&lt;identity&gt;&lt;dns value=&quot;localhost&quot; /&gt;&lt;/identity&gt;&lt;/Data&gt;" contractName="WcfSampleService.IDataApi" name="WSHttpBinding_IDataApi" />
+ </endpoints>
+</configurationSnapshot> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/configuration91.svcinfo b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/configuration91.svcinfo
new file mode 100644
index 0000000..de1eabf
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/Service References/WcfSampleService/configuration91.svcinfo
@@ -0,0 +1,210 @@
+<?xml version="1.0" encoding="utf-8"?>
+<SavedWcfConfigurationInformation xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Version="9.1" CheckSum="euCgt24VN7V3aZNjvZhw/CrojFo=">
+ <bindingConfigurations>
+ <bindingConfiguration bindingType="wsHttpBinding" name="WSHttpBinding_IDataApi">
+ <properties>
+ <property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi</serializedValue>
+ </property>
+ <property path="/closeTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/openTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/receiveTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:10:00</serializedValue>
+ </property>
+ <property path="/sendTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:01:00</serializedValue>
+ </property>
+ <property path="/bypassProxyOnLocal" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/transactionFlow" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/hostNameComparisonMode" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HostNameComparisonMode, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>StrongWildcard</serializedValue>
+ </property>
+ <property path="/maxBufferPoolSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>524288</serializedValue>
+ </property>
+ <property path="/maxReceivedMessageSize" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>65536</serializedValue>
+ </property>
+ <property path="/messageEncoding" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.WSMessageEncoding, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Text</serializedValue>
+ </property>
+ <property path="/proxyAddress" isComplexType="false" isExplicitlyDefined="false" clrType="System.Uri, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/readerQuotas" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.XmlDictionaryReaderQuotasElement</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxDepth" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>32</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxStringContentLength" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>8192</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxArrayLength" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>16384</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxBytesPerRead" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>4096</serializedValue>
+ </property>
+ <property path="/readerQuotas/maxNameTableCharCount" isComplexType="false" isExplicitlyDefined="true" clrType="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>16384</serializedValue>
+ </property>
+ <property path="/reliableSession" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.StandardBindingOptionalReliableSessionElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.StandardBindingOptionalReliableSessionElement</serializedValue>
+ </property>
+ <property path="/reliableSession/ordered" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/reliableSession/inactivityTimeout" isComplexType="false" isExplicitlyDefined="true" clrType="System.TimeSpan, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>00:10:00</serializedValue>
+ </property>
+ <property path="/reliableSession/enabled" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/textEncoding" isComplexType="false" isExplicitlyDefined="true" clrType="System.Text.Encoding, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.Text.UTF8Encoding</serializedValue>
+ </property>
+ <property path="/useDefaultWebProxy" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/allowCookies" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/security" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.WSHttpSecurityElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.WSHttpSecurityElement</serializedValue>
+ </property>
+ <property path="/security/mode" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.SecurityMode, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Message</serializedValue>
+ </property>
+ <property path="/security/transport" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.WSHttpTransportSecurityElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.WSHttpTransportSecurityElement</serializedValue>
+ </property>
+ <property path="/security/transport/clientCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HttpClientCredentialType, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Windows</serializedValue>
+ </property>
+ <property path="/security/transport/proxyCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.HttpProxyCredentialType, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>None</serializedValue>
+ </property>
+ <property path="/security/transport/realm" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.Security.Authentication.ExtendedProtection.Configuration.ExtendedProtectionPolicyElement</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/policyEnforcement" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.PolicyEnforcement, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Never</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/protectionScenario" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.ProtectionScenario, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>TransportSelected</serializedValue>
+ </property>
+ <property path="/security/transport/extendedProtectionPolicy/customServiceNames" isComplexType="true" isExplicitlyDefined="false" clrType="System.Security.Authentication.ExtendedProtection.Configuration.ServiceNameElementCollection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>(Collection)</serializedValue>
+ </property>
+ <property path="/security/message" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.NonDualMessageSecurityOverHttpElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.NonDualMessageSecurityOverHttpElement</serializedValue>
+ </property>
+ <property path="/security/message/clientCredentialType" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.MessageCredentialType, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Windows</serializedValue>
+ </property>
+ <property path="/security/message/negotiateServiceCredential" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ <property path="/security/message/algorithmSuite" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.Security.SecurityAlgorithmSuite, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>Basic256</serializedValue>
+ </property>
+ <property path="/security/message/establishSecurityContext" isComplexType="false" isExplicitlyDefined="true" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>True</serializedValue>
+ </property>
+ </properties>
+ </bindingConfiguration>
+ </bindingConfigurations>
+ <endpoints>
+ <endpoint name="WSHttpBinding_IDataApi" contract="WcfSampleService.IDataApi" bindingType="wsHttpBinding" address="http://localhost:65169/OAuthServiceProvider/DataApi.svc" bindingConfiguration="WSHttpBinding_IDataApi">
+ <properties>
+ <property path="/address" isComplexType="false" isExplicitlyDefined="true" clrType="System.Uri, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>http://localhost:65169/OAuthServiceProvider/DataApi.svc</serializedValue>
+ </property>
+ <property path="/behaviorConfiguration" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/binding" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>wsHttpBinding</serializedValue>
+ </property>
+ <property path="/bindingConfiguration" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi</serializedValue>
+ </property>
+ <property path="/contract" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WcfSampleService.IDataApi</serializedValue>
+ </property>
+ <property path="/headers" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.AddressHeaderCollectionElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.AddressHeaderCollectionElement</serializedValue>
+ </property>
+ <property path="/headers/headers" isComplexType="false" isExplicitlyDefined="true" clrType="System.ServiceModel.Channels.AddressHeaderCollection, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>&lt;Header /&gt;</serializedValue>
+ </property>
+ <property path="/identity" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.IdentityElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.IdentityElement</serializedValue>
+ </property>
+ <property path="/identity/userPrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.UserPrincipalNameElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.UserPrincipalNameElement</serializedValue>
+ </property>
+ <property path="/identity/userPrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/servicePrincipalName" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.ServicePrincipalNameElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.ServicePrincipalNameElement</serializedValue>
+ </property>
+ <property path="/identity/servicePrincipalName/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/dns" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.DnsElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.DnsElement</serializedValue>
+ </property>
+ <property path="/identity/dns/value" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>localhost</serializedValue>
+ </property>
+ <property path="/identity/rsa" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.RsaElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.RsaElement</serializedValue>
+ </property>
+ <property path="/identity/rsa/value" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificate" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.CertificateElement</serializedValue>
+ </property>
+ <property path="/identity/certificate/encodedValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificateReference" isComplexType="true" isExplicitlyDefined="false" clrType="System.ServiceModel.Configuration.CertificateReferenceElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>System.ServiceModel.Configuration.CertificateReferenceElement</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/storeName" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreName, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>My</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/storeLocation" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.StoreLocation, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>LocalMachine</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/x509FindType" isComplexType="false" isExplicitlyDefined="false" clrType="System.Security.Cryptography.X509Certificates.X509FindType, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>FindBySubjectDistinguishedName</serializedValue>
+ </property>
+ <property path="/identity/certificateReference/findValue" isComplexType="false" isExplicitlyDefined="false" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue />
+ </property>
+ <property path="/identity/certificateReference/isChainIncluded" isComplexType="false" isExplicitlyDefined="false" clrType="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>False</serializedValue>
+ </property>
+ <property path="/name" isComplexType="false" isExplicitlyDefined="true" clrType="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <serializedValue>WSHttpBinding_IDataApi</serializedValue>
+ </property>
+ </properties>
+ </endpoint>
+ </endpoints>
+</SavedWcfConfigurationInformation> \ No newline at end of file
diff --git a/src/OAuth/OAuthConsumerWpf/favicon.ico b/src/OAuth/OAuthConsumerWpf/favicon.ico
new file mode 100644
index 0000000..e227dbe
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/favicon.ico
Binary files differ
diff --git a/src/OAuth/OAuthConsumerWpf/packages.config b/src/OAuth/OAuthConsumerWpf/packages.config
new file mode 100644
index 0000000..23deca0
--- /dev/null
+++ b/src/OAuth/OAuthConsumerWpf/packages.config
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CodeContracts.Unofficial" version="1.0.0.2" />
+ <package id="DotNetOpenAuth.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Consumer" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth2.Client" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.Client" version="0.23.0-draft2" />
+ <package id="DotNetOpenAuth.OAuth2.Client.UI" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.Client.UI" version="0.23.0-draft2" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft2" />
+ <package id="log4net" version="2.0.0" />
+</packages> \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Code/Global.cs b/src/OAuth/OAuthResourceServer/Code/Global.cs
new file mode 100644
index 0000000..a48baff
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/Global.cs
@@ -0,0 +1,106 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.ServiceModel;
+ using System.Text;
+ using System.Web;
+ using DotNetOpenAuth.OAuth2;
+ using DotNetOpenAuth.OAuth2.Messages;
+
+ /// <summary>
+ /// The web application global events and properties.
+ /// </summary>
+ public class Global : HttpApplication {
+#if SAMPLESONLY
+ /// <summary>
+ /// The FOR SAMPLE ONLY hard-coded public key of the authorization server that is used to verify the signature on access tokens.
+ /// </summary>
+ /// <remarks>
+ /// In a real app, the authorization server public key would likely come from the server's HTTPS certificate,
+ /// but in any case would be determined by the authorization server and its policies.
+ /// The hard-coded value used here is so this sample works well with the OAuthAuthorizationServer sample,
+ /// which has the corresponding sample private key.
+ /// </remarks>
+ public static readonly RSAParameters AuthorizationServerSigningPublicKey = new RSAParameters {
+ Exponent = new byte[] { 1, 0, 1 },
+ Modulus = new byte[] { 210, 95, 53, 12, 203, 114, 150, 23, 23, 88, 4, 200, 47, 219, 73, 54, 146, 253, 126, 121, 105, 91, 118, 217, 182, 167, 140, 6, 67, 112, 97, 183, 66, 112, 245, 103, 136, 222, 205, 28, 196, 45, 6, 223, 192, 76, 56, 180, 90, 120, 144, 19, 31, 193, 37, 129, 186, 214, 36, 53, 204, 53, 108, 133, 112, 17, 133, 244, 3, 12, 230, 29, 243, 51, 79, 253, 10, 111, 185, 23, 74, 230, 99, 94, 78, 49, 209, 39, 95, 213, 248, 212, 22, 4, 222, 145, 77, 190, 136, 230, 134, 70, 228, 241, 194, 216, 163, 234, 52, 1, 64, 181, 139, 128, 90, 255, 214, 60, 168, 233, 254, 110, 31, 102, 58, 67, 201, 33 },
+ };
+#else
+ [Obsolete("You must use a real key for a real app.", true)]
+ public static readonly RSAParameters AuthorizationServerSigningPublicKey = new RSAParameters();
+#endif
+
+ /// <summary>
+ /// An application memory cache of recent log messages.
+ /// </summary>
+ public static StringBuilder LogMessages = new StringBuilder();
+
+ /// <summary>
+ /// The logger for this sample to use.
+ /// </summary>
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthResourceServer");
+
+#if SAMPLESONLY
+ /// <summary>
+ /// The FOR SAMPLE ONLY hard-coded private key used to decrypt access tokens intended for this resource server.
+ /// </summary>
+ /// <remarks>
+ /// In a real app, the resource server would likely use its own HTTPS certificate or some other certificate stored securely
+ /// on the server rather than hard-coded in compiled code for security and ease of changing the certificate in case it was compromised.
+ /// </remarks>
+ internal static readonly RSAParameters ResourceServerEncryptionPrivateKey = new RSAParameters {
+ Exponent = new byte[] { 1, 0, 1 },
+ Modulus = new byte[] { 166, 175, 117, 169, 211, 251, 45, 215, 55, 53, 202, 65, 153, 155, 92, 219, 235, 243, 61, 170, 101, 250, 221, 214, 239, 175, 238, 175, 239, 20, 144, 72, 227, 221, 4, 219, 32, 225, 101, 96, 18, 33, 117, 176, 110, 123, 109, 23, 29, 85, 93, 50, 129, 163, 113, 57, 122, 212, 141, 145, 17, 31, 67, 165, 181, 91, 117, 23, 138, 251, 198, 132, 188, 213, 10, 157, 116, 229, 48, 168, 8, 127, 28, 156, 239, 124, 117, 36, 232, 100, 222, 23, 52, 186, 239, 5, 63, 207, 185, 16, 137, 73, 137, 147, 252, 71, 9, 239, 113, 27, 88, 255, 91, 56, 192, 142, 210, 21, 34, 81, 204, 239, 57, 60, 140, 249, 15, 101 },
+ P = new byte[] { 227, 25, 96, 71, 220, 99, 11, 55, 15, 241, 153, 20, 32, 213, 68, 127, 246, 162, 153, 204, 98, 26, 10, 99, 46, 189, 35, 18, 162, 180, 184, 134, 230, 198, 156, 87, 52, 174, 74, 155, 163, 204, 252, 51, 232, 189, 135, 172, 88, 24, 52, 174, 72, 157, 81, 90, 118, 59, 142, 154, 152, 201, 62, 177 },
+ Q = new byte[] { 187, 229, 223, 233, 118, 20, 5, 251, 85, 8, 196, 3, 220, 232, 38, 159, 15, 95, 174, 162, 36, 13, 138, 239, 16, 85, 220, 104, 4, 162, 174, 160, 234, 133, 156, 33, 117, 139, 22, 112, 108, 214, 97, 178, 100, 191, 13, 177, 164, 30, 124, 48, 33, 118, 21, 137, 38, 59, 191, 13, 183, 5, 16, 245 },
+ DP = new byte[] { 225, 112, 117, 117, 160, 191, 233, 136, 53, 153, 158, 94, 174, 225, 71, 104, 200, 75, 77, 229, 232, 148, 245, 46, 212, 93, 9, 142, 28, 90, 206, 187, 140, 40, 41, 87, 32, 130, 204, 169, 136, 135, 154, 237, 100, 227, 144, 229, 115, 102, 68, 21, 167, 28, 20, 128, 122, 210, 80, 148, 3, 139, 243, 97 },
+ DQ = new byte[] { 133, 252, 100, 207, 232, 184, 92, 143, 157, 82, 115, 220, 65, 81, 118, 0, 228, 136, 153, 81, 219, 157, 160, 157, 218, 171, 47, 81, 41, 69, 12, 123, 136, 224, 159, 182, 40, 72, 119, 70, 210, 5, 137, 131, 25, 94, 55, 152, 157, 236, 115, 40, 43, 36, 54, 53, 39, 131, 97, 56, 153, 114, 206, 101 },
+ InverseQ = new byte[] { 129, 119, 84, 118, 29, 35, 194, 186, 96, 169, 7, 7, 200, 22, 187, 34, 72, 131, 200, 246, 79, 120, 49, 242, 8, 220, 74, 114, 195, 95, 90, 108, 80, 2, 212, 71, 125, 100, 184, 77, 203, 236, 64, 122, 108, 212, 150, 129, 66, 248, 218, 3, 186, 71, 213, 236, 142, 66, 33, 196, 150, 216, 138, 114 },
+ D = new byte[] { 94, 20, 94, 119, 18, 92, 141, 13, 17, 238, 92, 80, 22, 96, 232, 82, 128, 164, 115, 195, 191, 119, 142, 202, 135, 210, 103, 8, 10, 11, 51, 60, 208, 207, 168, 179, 253, 164, 250, 80, 245, 42, 201, 128, 97, 123, 108, 161, 69, 63, 47, 49, 24, 150, 165, 139, 105, 214, 154, 104, 172, 159, 86, 208, 64, 134, 158, 156, 234, 125, 140, 210, 3, 32, 60, 28, 62, 154, 198, 21, 132, 191, 236, 10, 158, 12, 247, 159, 177, 77, 178, 53, 238, 95, 165, 9, 200, 28, 148, 242, 35, 70, 189, 121, 169, 248, 97, 91, 111, 45, 103, 1, 167, 220, 67, 250, 175, 89, 122, 238, 192, 144, 142, 248, 198, 101, 96, 129 },
+ };
+#else
+ [Obsolete("You must use a real key for a real app.", true)]
+ internal static readonly RSAParameters ResourceServerEncryptionPrivateKey = new RSAParameters();
+#endif
+
+ /// <summary>
+ /// Creates the crypto service provider for this resource server that contains the private key used to decrypt an access token.
+ /// </summary>
+ /// <returns>An RSA crypto service provider.</returns>
+ internal static RSACryptoServiceProvider CreateResourceServerEncryptionServiceProvider() {
+ var resourceServerEncryptionServiceProvider = new RSACryptoServiceProvider();
+ resourceServerEncryptionServiceProvider.ImportParameters(ResourceServerEncryptionPrivateKey);
+ return resourceServerEncryptionServiceProvider;
+ }
+
+ /// <summary>
+ /// Creates the crypto service provider for the authorization server that contains the public key used to verify an access token signature.
+ /// </summary>
+ /// <returns>An RSA crypto service provider.</returns>
+ internal static RSACryptoServiceProvider CreateAuthorizationServerSigningServiceProvider() {
+ var authorizationServerSigningServiceProvider = new RSACryptoServiceProvider();
+ authorizationServerSigningServiceProvider.ImportParameters(AuthorizationServerSigningPublicKey);
+ return authorizationServerSigningServiceProvider;
+ }
+
+ private void Application_Start(object sender, EventArgs e) {
+ log4net.Config.XmlConfigurator.Configure();
+ Logger.Info("Sample starting...");
+ }
+
+ private void Application_End(object sender, EventArgs e) {
+ Logger.Info("Sample shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ private void Application_Error(object sender, EventArgs e) {
+ Logger.Error("An unhandled exception occurred in ASP.NET processing: " + Server.GetLastError(), Server.GetLastError());
+ }
+
+ private void Application_EndRequest(object sender, EventArgs e) {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Code/IDataApi.cs b/src/OAuth/OAuthResourceServer/Code/IDataApi.cs
new file mode 100644
index 0000000..7ba189d
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/IDataApi.cs
@@ -0,0 +1,21 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Runtime.Serialization;
+ using System.ServiceModel;
+ using System.ServiceModel.Web;
+ using System.Text;
+
+ [ServiceContract]
+ public interface IDataApi {
+ [OperationContract, WebGet(UriTemplate = "/age", ResponseFormat = WebMessageFormat.Json)]
+ int? GetAge();
+
+ [OperationContract, WebGet(UriTemplate = "/name", ResponseFormat = WebMessageFormat.Json)]
+ string GetName();
+
+ [OperationContract, WebGet(UriTemplate = "/favoritesites", ResponseFormat = WebMessageFormat.Json)]
+ string[] GetFavoriteSites();
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Code/OAuthAuthorizationManager.cs b/src/OAuth/OAuthResourceServer/Code/OAuthAuthorizationManager.cs
new file mode 100644
index 0000000..8d0c13d
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/OAuthAuthorizationManager.cs
@@ -0,0 +1,80 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IdentityModel.Policy;
+ using System.Linq;
+ using System.Security.Principal;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Security;
+
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth2;
+
+ using ProtocolException = System.ServiceModel.ProtocolException;
+
+ /// <summary>
+ /// A WCF extension to authenticate incoming messages using OAuth.
+ /// </summary>
+ public class OAuthAuthorizationManager : ServiceAuthorizationManager {
+ public OAuthAuthorizationManager() {
+ }
+
+ protected override bool CheckAccessCore(OperationContext operationContext) {
+ if (!base.CheckAccessCore(operationContext)) {
+ return false;
+ }
+
+ var httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
+ var requestUri = operationContext.RequestContext.RequestMessage.Properties.Via;
+
+ try {
+ var principal = VerifyOAuth2(httpDetails, requestUri);
+ if (principal != null) {
+ var policy = new OAuthPrincipalAuthorizationPolicy(principal);
+ var policies = new List<IAuthorizationPolicy> {
+ policy,
+ };
+
+ var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
+ if (operationContext.IncomingMessageProperties.Security != null) {
+ operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
+ } else {
+ operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
+ ServiceSecurityContext = securityContext,
+ };
+ }
+
+ securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
+ principal.Identity,
+ };
+
+ // Only allow this method call if the access token scope permits it.
+ return principal.IsInRole(operationContext.IncomingMessageHeaders.Action ?? operationContext.IncomingMessageHeaders.To.AbsolutePath);
+ } else {
+ return false;
+ }
+ } catch (ProtocolException ex) {
+ Global.Logger.Error("Error processing OAuth messages.", ex);
+ }
+
+ return false;
+ }
+
+ private static IPrincipal VerifyOAuth2(HttpRequestMessageProperty httpDetails, Uri requestUri) {
+ // for this sample where the auth server and resource server are the same site,
+ // we use the same public/private key.
+ using (var signing = Global.CreateAuthorizationServerSigningServiceProvider()) {
+ using (var encrypting = Global.CreateResourceServerEncryptionServiceProvider()) {
+ var resourceServer = new ResourceServer(new StandardAccessTokenAnalyzer(signing, encrypting));
+
+ IPrincipal result;
+ var error = resourceServer.VerifyAccess(HttpRequestInfo.Create(httpDetails, requestUri), out result);
+
+ // TODO: return the prepared error code.
+ return error != null ? null : result;
+ }
+ }
+ }
+ }
+}
diff --git a/src/OAuth/OAuthResourceServer/Code/OAuthPrincipalAuthorizationPolicy.cs b/src/OAuth/OAuthResourceServer/Code/OAuthPrincipalAuthorizationPolicy.cs
new file mode 100644
index 0000000..ac01c4d
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/OAuthPrincipalAuthorizationPolicy.cs
@@ -0,0 +1,47 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IdentityModel.Claims;
+ using System.IdentityModel.Policy;
+ using System.Linq;
+ using System.Security.Principal;
+ using System.Web;
+
+ public class OAuthPrincipalAuthorizationPolicy : IAuthorizationPolicy {
+ private readonly Guid uniqueId = Guid.NewGuid();
+ private readonly IPrincipal principal;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OAuthPrincipalAuthorizationPolicy"/> class.
+ /// </summary>
+ /// <param name="principal">The principal.</param>
+ public OAuthPrincipalAuthorizationPolicy(IPrincipal principal) {
+ this.principal = principal;
+ }
+
+ #region IAuthorizationComponent Members
+
+ /// <summary>
+ /// Gets a unique ID for this instance.
+ /// </summary>
+ public string Id {
+ get { return this.uniqueId.ToString(); }
+ }
+
+ #endregion
+
+ #region IAuthorizationPolicy Members
+
+ public ClaimSet Issuer {
+ get { return ClaimSet.System; }
+ }
+
+ public bool Evaluate(EvaluationContext evaluationContext, ref object state) {
+ evaluationContext.AddClaimSet(this, new DefaultClaimSet(Claim.CreateNameClaim(this.principal.Identity.Name)));
+ evaluationContext.Properties["Principal"] = this.principal;
+ return true;
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Code/TracePageAppender.cs b/src/OAuth/OAuthResourceServer/Code/TracePageAppender.cs
new file mode 100644
index 0000000..4dc543f
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Code/TracePageAppender.cs
@@ -0,0 +1,13 @@
+namespace OAuthResourceServer.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Web;
+
+ public class TracePageAppender : log4net.Appender.AppenderSkeleton {
+ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
+ StringWriter sw = new StringWriter(Global.LogMessages);
+ Layout.Format(sw, loggingEvent);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/DataApi.cs b/src/OAuth/OAuthResourceServer/DataApi.cs
new file mode 100644
index 0000000..f1ac19e
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/DataApi.cs
@@ -0,0 +1,42 @@
+namespace OAuthResourceServer {
+ using System.Linq;
+ using System.Security.Principal;
+ using System.ServiceModel;
+
+ using Code;
+
+ /// <summary>
+ /// The WCF service API.
+ /// </summary>
+ /// <remarks>
+ /// Note how there is no code here that is bound to OAuth or any other
+ /// credential/authorization scheme. That's all part of the channel/binding elsewhere.
+ /// And the reference to OperationContext.Current.ServiceSecurityContext.PrimaryIdentity
+ /// is the user being impersonated by the WCF client.
+ /// In the OAuth case, it is the user who authorized the OAuth access token that was used
+ /// to gain access to the service.
+ /// </remarks>
+ public class DataApi : IDataApi {
+ private IIdentity User {
+ get { return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity; }
+ }
+
+ public int? GetAge() {
+ // We'll just make up an age personalized to the user by counting the length of the username.
+ return this.User.Name.Length;
+ }
+
+ public string GetName() {
+ return this.User.Name;
+ }
+
+ public string[] GetFavoriteSites() {
+ // Just return a hard-coded list, to avoid having to have a database in a sample.
+ return new string[] {
+ "http://www.dotnetopenauth.net/",
+ "http://www.oauth.net/",
+ "http://www.openid.net/",
+ };
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/DataApi.svc b/src/OAuth/OAuthResourceServer/DataApi.svc
new file mode 100644
index 0000000..9a36ef6
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/DataApi.svc
@@ -0,0 +1 @@
+<%@ ServiceHost Language="C#" Debug="true" Service="OAuthResourceServer.DataApi" CodeBehind="DataApi.cs" %>
diff --git a/src/OAuth/OAuthResourceServer/Default.aspx b/src/OAuth/OAuthResourceServer/Default.aspx
new file mode 100644
index 0000000..a333313
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Default.aspx
@@ -0,0 +1,4 @@
+<%@ Page Title="DotNetOpenAuth Service Provider Sample" Language="C#" MasterPageFile="~/MasterPage.master" CodeBehind="~/Default.aspx.cs" Inherits="OAuthResourceServer._Default" AutoEventWireup="True" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+</asp:Content>
diff --git a/src/OAuth/OAuthResourceServer/Default.aspx.cs b/src/OAuth/OAuthResourceServer/Default.aspx.cs
new file mode 100644
index 0000000..46ca65e
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Default.aspx.cs
@@ -0,0 +1,10 @@
+namespace OAuthResourceServer {
+ using System;
+ using System.Configuration;
+ using System.IO;
+
+ using Code;
+
+ public partial class _Default : System.Web.UI.Page {
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Default.aspx.designer.cs b/src/OAuth/OAuthResourceServer/Default.aspx.designer.cs
new file mode 100644
index 0000000..4fa5152
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Default.aspx.designer.cs
@@ -0,0 +1,15 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthResourceServer {
+
+
+ public partial class _Default {
+ }
+}
diff --git a/src/OAuth/OAuthResourceServer/Global.asax b/src/OAuth/OAuthResourceServer/Global.asax
new file mode 100644
index 0000000..0f290d5
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Global.asax
@@ -0,0 +1 @@
+<%@ Application Inherits="OAuthResourceServer.Code.Global" CodeBehind="Code\Global.cs" %>
diff --git a/src/OAuth/OAuthResourceServer/Login.aspx b/src/OAuth/OAuthResourceServer/Login.aspx
new file mode 100644
index 0000000..9593faa
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Login.aspx
@@ -0,0 +1,11 @@
+<%@ Page Title="Login" Language="C#" MasterPageFile="~/MasterPage.master" %>
+
+<%@ Register Assembly="DotNetOpenAuth.OpenId.RelyingParty.UI" Namespace="DotNetOpenAuth.OpenId.RelyingParty" TagPrefix="rp" %>
+<script runat="server">
+ protected void Page_Load(object sender, EventArgs e) {
+ OpenIdLogin1.Focus();
+ }
+</script>
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <rp:OpenIdLogin runat="server" TabIndex='1' ID="OpenIdLogin1" />
+</asp:Content>
diff --git a/src/OAuth/OAuthResourceServer/MasterPage.master b/src/OAuth/OAuthResourceServer/MasterPage.master
new file mode 100644
index 0000000..3147153
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/MasterPage.master
@@ -0,0 +1,23 @@
+<%@ Master Language="C#" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<script runat="server">
+
+</script>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>DotNetOpenAuth OAuth 2.0 Resource Server sample</title>
+ <asp:ContentPlaceHolder ID="head" runat="server"/>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <h1>DotNetOpenAuth OAuth 2.0 Resource Server sample</h1>
+ <div>
+ <asp:ContentPlaceHolder ID="Body" runat="server">
+ </asp:ContentPlaceHolder>
+ </div>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthResourceServer/Members/Logoff.aspx b/src/OAuth/OAuthResourceServer/Members/Logoff.aspx
new file mode 100644
index 0000000..afa9dd9
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Members/Logoff.aspx
@@ -0,0 +1,8 @@
+<%@ Page Title="Log off" Language="C#" MasterPageFile="~/MasterPage.master" %>
+
+<script runat="server">
+ private void Page_Load(object sender, EventArgs e) {
+ FormsAuthentication.SignOut();
+ Response.Redirect("~/");
+ }
+</script>
diff --git a/src/OAuth/OAuthResourceServer/Members/Web.config b/src/OAuth/OAuthResourceServer/Members/Web.config
new file mode 100644
index 0000000..50fab27
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Members/Web.config
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<configuration>
+ <system.web>
+ <authorization>
+ <deny users="?"/>
+ </authorization>
+ </system.web>
+</configuration>
diff --git a/src/OAuth/OAuthResourceServer/OAuthResourceServer.csproj b/src/OAuth/OAuthResourceServer/OAuthResourceServer.csproj
new file mode 100644
index 0000000..9904726
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/OAuthResourceServer.csproj
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E135F455-0669-49F8-9207-07FCA8C8FC79}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>OAuthResourceServer</RootNamespace>
+ <AssemblyName>OAuthResourceServer</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <UseIISExpress>false</UseIISExpress>
+ <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\</SolutionDir>
+ <RestorePackages>true</RestorePackages>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;DEBUG;SAMPLESONLY</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE;SAMPLESONLY</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="DotNetOpenAuth.Core">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.Core.4.0.0.12084\lib\net40-full\DotNetOpenAuth.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth.Common">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth.Common.4.0.0.12084\lib\net40-full\DotNetOpenAuth.OAuth.Common.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.Core.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.dll</HintPath>
+ </Reference>
+ <Reference Include="DotNetOpenAuth.OAuth2.ResourceServer">
+ <HintPath>..\..\..\packages\DotNetOpenAuth.OAuth2.ResourceServer.0.23.0-draft2\lib\net40-full\DotNetOpenAuth.OAuth2.ResourceServer.dll</HintPath>
+ </Reference>
+ <Reference Include="log4net">
+ <HintPath>..\..\..\packages\log4net.2.0.0\lib\net40-full\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data.Linq" />
+ <Reference Include="System.IdentityModel" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.ServiceModel.Web" />
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.ApplicationServices" />
+ <Reference Include="System.Web.DynamicData" />
+ <Reference Include="System.Web.Entity" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ <Reference Include="System.Xml.Linq" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="DataApi.svc" />
+ <Content Include="Default.aspx" />
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="Login.aspx" />
+ <Content Include="Members\Logoff.aspx" />
+ <Content Include="TracePage.aspx" />
+ <Content Include="Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Default.aspx.designer.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="DataApi.cs">
+ <DependentUpon>DataApi.svc</DependentUpon>
+ </Compile>
+ <Compile Include="Code\Global.cs" />
+ <Compile Include="Code\IDataApi.cs" />
+ <Compile Include="Code\OAuthAuthorizationManager.cs" />
+ <Compile Include="Code\OAuthPrincipalAuthorizationPolicy.cs" />
+ <Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="Default.aspx.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.designer.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="MasterPage.master" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Members\Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>False</AutoAssignPort>
+ <DevelopmentServerPort>65169</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+ <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+</Project> \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/Properties/AssemblyInfo.cs b/src/OAuth/OAuthResourceServer/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c553ba4
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OAuthResourceServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OAuthResourceServer")]
+[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("B6206451-6557-4568-8D25-84AF93EC8B7B")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/OAuth/OAuthResourceServer/Settings.StyleCop b/src/OAuth/OAuthResourceServer/Settings.StyleCop
new file mode 100644
index 0000000..7f55ce6
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Settings.StyleCop
@@ -0,0 +1 @@
+<StyleCopSettings Version="4.3" /> \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/TracePage.aspx b/src/OAuth/OAuthResourceServer/TracePage.aspx
new file mode 100644
index 0000000..c347830
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/TracePage.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OAuthResourceServer.TracePage" Codebehind="TracePage.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <p align="right">
+ <asp:Button runat="server" Text="Clear log" ID="clearLogButton" OnClick="clearLogButton_Click" />
+ </p>
+ <pre>
+ <asp:PlaceHolder runat="server" ID="placeHolder1" />
+ </pre>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthResourceServer/TracePage.aspx.cs b/src/OAuth/OAuthResourceServer/TracePage.aspx.cs
new file mode 100644
index 0000000..4841c89
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/TracePage.aspx.cs
@@ -0,0 +1,24 @@
+namespace OAuthResourceServer {
+ using System;
+ using System.Collections.Generic;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using Code;
+
+ /// <summary>
+ /// A page to display recent log messages.
+ /// </summary>
+ public partial class TracePage : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.placeHolder1.Controls.Add(new Label { Text = HttpUtility.HtmlEncode(Global.LogMessages.ToString()) });
+ }
+
+ protected void clearLogButton_Click(object sender, EventArgs e) {
+ Global.LogMessages.Length = 0;
+
+ // clear the page immediately, and allow for F5 without a Postback warning.
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/TracePage.aspx.designer.cs b/src/OAuth/OAuthResourceServer/TracePage.aspx.designer.cs
new file mode 100644
index 0000000..58dc5d1
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/TracePage.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthResourceServer {
+
+
+ public partial class TracePage {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// clearLogButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button clearLogButton;
+
+ /// <summary>
+ /// placeHolder1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder placeHolder1;
+ }
+}
diff --git a/src/OAuth/OAuthResourceServer/Web.config b/src/OAuth/OAuthResourceServer/Web.config
new file mode 100644
index 0000000..1ab8dfa
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/Web.config
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false" />
+ <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+ <section name="openid" type="DotNetOpenAuth.Configuration.OpenIdElement, DotNetOpenAuth.OpenId" requirePermission="false" allowLocation="true" />
+ <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" />
+ <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ </sectionGroup>
+ </configSections>
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <uri>
+ <idn enabled="All" />
+ <iriParsing enabled="true" />
+ </uri>
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <dotNetOpenAuth>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true" />
+ <!-- Relaxing SSL requirements is useful for simple samples, but NOT a good idea in production. -->
+ <messaging relaxSslRequirements="true">
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <!-- Uncomment to enable communication with localhost (should generally not activate in production!) -->
+ <!--<add name="localhost" />-->
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ </dotNetOpenAuth>
+ <appSettings />
+ <connectionStrings>
+ <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient" />
+ </connectionStrings>
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true" targetFramework="4.0">
+ <assemblies>
+ <remove assembly="DotNetOpenAuth.Contracts" />
+ <add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
+ </assemblies>
+ </compilation>
+ <authentication mode="Forms">
+ <forms name="oauthSP" />
+ </authentication>
+ <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
+ </system.web>
+ <!--
+ The system.webServer section is required for running ASP.NET AJAX under Internet
+ Information Services 7.0. It is not necessary for previous version of IIS.
+ -->
+ <log4net>
+ <appender name="TracePageAppender" type="OAuthResourceServer.Code.TracePageAppender, OAuthResourceServer">
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline" />
+ </layout>
+ </appender>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO" />
+ <!--<appender-ref ref="RollingFileAppender" />-->
+ <appender-ref ref="TracePageAppender" />
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="ALL" />
+ </logger>
+ </log4net>
+ <system.serviceModel>
+ <behaviors>
+ <serviceBehaviors>
+ <behavior name="DataApiBehavior">
+ <serviceMetadata httpGetEnabled="true" />
+ <serviceDebug includeExceptionDetailInFaults="true" />
+ <serviceAuthorization serviceAuthorizationManagerType="OAuthResourceServer.Code.OAuthAuthorizationManager, OAuthResourceServer" principalPermissionMode="Custom" />
+ </behavior>
+ </serviceBehaviors>
+ <endpointBehaviors>
+ <behavior name="DataApiWebBehavior">
+ <webHttp />
+ </behavior>
+ </endpointBehaviors>
+ </behaviors>
+ <services>
+ <service behaviorConfiguration="DataApiBehavior" name="OAuthResourceServer.DataApi">
+ <endpoint address="" binding="wsHttpBinding" contract="OAuthResourceServer.Code.IDataApi">
+ <identity>
+ <dns value="localhost" />
+ </identity>
+ </endpoint>
+ <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
+ <endpoint address="web" binding="webHttpBinding" contract="OAuthResourceServer.Code.IDataApi" behaviorConfiguration="DataApiWebBehavior" />
+ </service>
+ </services>
+ </system.serviceModel>
+ <runtime>
+ <!-- This prevents the Windows Event Log from frequently logging that HMAC1 is being used (when the other party needs it). -->
+ <legacyHMACWarning enabled="0" />
+ </runtime>
+</configuration> \ No newline at end of file
diff --git a/src/OAuth/OAuthResourceServer/favicon.ico b/src/OAuth/OAuthResourceServer/favicon.ico
new file mode 100644
index 0000000..e227dbe
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/favicon.ico
Binary files differ
diff --git a/src/OAuth/OAuthResourceServer/packages.config b/src/OAuth/OAuthResourceServer/packages.config
new file mode 100644
index 0000000..0e5b33a
--- /dev/null
+++ b/src/OAuth/OAuthResourceServer/packages.config
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="CodeContracts.Unofficial" version="1.0.0.2" />
+ <package id="DotNetOpenAuth.Core" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth.Common" version="4.0.0.12084" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.Core" version="0.23.0-draft2" />
+ <package id="DotNetOpenAuth.OAuth2.ResourceServer" version="0.23.0-draft" />
+ <package id="DotNetOpenAuth.OAuth2.ResourceServer" version="0.23.0-draft2" />
+ <package id="log4net" version="2.0.0" />
+</packages> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/Constants.cs b/src/OAuth/OAuthServiceProvider/Code/Constants.cs
new file mode 100644
index 0000000..3e629f0
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/Constants.cs
@@ -0,0 +1,32 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ /// <summary>
+ /// Service Provider definitions.
+ /// </summary>
+ public static class Constants {
+ public static Uri WebRootUrl { get; set; }
+
+ public static ServiceProviderDescription SelfDescription {
+ get {
+ ServiceProviderDescription description = new ServiceProviderDescription {
+ AccessTokenEndpoint = new MessageReceivingEndpoint(new Uri(WebRootUrl, "/OAuth.ashx"), HttpDeliveryMethods.PostRequest),
+ RequestTokenEndpoint = new MessageReceivingEndpoint(new Uri(WebRootUrl, "/OAuth.ashx"), HttpDeliveryMethods.PostRequest),
+ UserAuthorizationEndpoint = new MessageReceivingEndpoint(new Uri(WebRootUrl, "/OAuth.ashx"), HttpDeliveryMethods.PostRequest),
+ TamperProtectionElements = new ITamperProtectionChannelBindingElement[] {
+ new HmacSha1SigningBindingElement(),
+ },
+ };
+
+ return description;
+ }
+ }
+
+ public static ServiceProvider CreateServiceProvider() {
+ return new ServiceProvider(SelfDescription, Global.TokenManager, Global.NonceStore);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/CustomOAuthTypeProvider.cs b/src/OAuth/OAuthServiceProvider/Code/CustomOAuthTypeProvider.cs
new file mode 100644
index 0000000..67da17c
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/CustomOAuthTypeProvider.cs
@@ -0,0 +1,34 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ /// <summary>
+ /// A custom class that will cause the OAuth library to use our custom message types
+ /// where we have them.
+ /// </summary>
+ public class CustomOAuthMessageFactory : OAuthServiceProviderMessageFactory {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="CustomOAuthMessageFactory"/> class.
+ /// </summary>
+ /// <param name="tokenManager">The token manager instance to use.</param>
+ public CustomOAuthMessageFactory(IServiceProviderTokenManager tokenManager)
+ : base(tokenManager) {
+ }
+
+ public override IDirectedProtocolMessage GetNewRequestMessage(MessageReceivingEndpoint recipient, IDictionary<string, string> fields) {
+ var message = base.GetNewRequestMessage(recipient, fields);
+
+ // inject our own type here to replace the standard one
+ if (message is UnauthorizedTokenRequest) {
+ message = new RequestScopedTokenMessage(recipient, message.Version);
+ }
+
+ return message;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml b/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml
new file mode 100644
index 0000000..5522ec8
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?><Database Name="Database" EntityNamespace="OAuthServiceProvider.Code" Class="DataClassesDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
+ <Connection Mode="WebSettings" ConnectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True" SettingsObjectName="System.Configuration.ConfigurationManager.ConnectionStrings" SettingsPropertyName="DatabaseConnectionString" Provider="System.Data.SqlClient" />
+ <Table Name="dbo.[User]" Member="Users">
+ <Type Name="User">
+ <Column Name="UserId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="OpenIDClaimedIdentifier" Type="System.String" DbType="NVarChar(150) NOT NULL" CanBeNull="false" />
+ <Column Name="OpenIDFriendlyIdentifier" Type="System.String" DbType="NVarChar(150)" CanBeNull="true" />
+ <Column Name="FullName" Type="System.String" DbType="NVarChar(150)" CanBeNull="false" />
+ <Column Name="Age" Type="System.Int32" DbType="int" CanBeNull="true" />
+ <Association Name="User_FavoriteSite" Member="FavoriteSites" ThisKey="UserId" OtherKey="UserId" Type="FavoriteSite" />
+ <Association Name="User_OAuthToken" Member="OAuthTokens" ThisKey="UserId" OtherKey="UserId" Type="OAuthToken" />
+ </Type>
+ </Table>
+ <Table Name="dbo.FavoriteSite" Member="FavoriteSites">
+ <Type Name="FavoriteSite">
+ <Column Name="FavoriteSiteId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="UserId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+ <Column Name="SiteUrl" Type="System.String" DbType="NVarChar(255) NOT NULL" CanBeNull="false" />
+ <Association Name="User_FavoriteSite" Member="User" ThisKey="UserId" OtherKey="UserId" Type="User" IsForeignKey="true" DeleteRule="CASCADE" DeleteOnNull="true" />
+ </Type>
+ </Table>
+ <Table Name="dbo.OAuthConsumer" Member="OAuthConsumers">
+ <Type Name="OAuthConsumer">
+ <Column Name="ConsumerId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="ConsumerKey" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="ConsumerSecret" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="Callback" Type="System.String" CanBeNull="true" />
+ <Column Name="VerificationCodeFormat" Type="DotNetOpenAuth.OAuth.VerificationCodeFormat" CanBeNull="false" />
+ <Column Name="VerificationCodeLength" Type="System.Int32" CanBeNull="false" />
+ <Association Name="OAuthConsumer_OAuthToken" Member="OAuthTokens" ThisKey="ConsumerId" OtherKey="ConsumerId" Type="OAuthToken" />
+ </Type>
+ </Table>
+ <Table Name="dbo.OAuthToken" Member="OAuthTokens">
+ <Type Name="OAuthToken">
+ <Column Name="TokenId" Type="System.Int32" DbType="Int NOT NULL IDENTITY" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+ <Column Name="Token" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="TokenSecret" Type="System.String" DbType="NVarChar(50) NOT NULL" CanBeNull="false" />
+ <Column Name="State" Type="OAuthServiceProvider.Code.TokenAuthorizationState" DbType="INT NOT NULL" CanBeNull="false" />
+ <Column Name="IssueDate" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" />
+ <Column Name="ConsumerId" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
+ <Column Name="UserId" Type="System.Int32" DbType="Int" CanBeNull="true" />
+ <Column Name="Scope" Type="System.String" DbType="nvarchar(MAX)" CanBeNull="false" />
+ <Column Name="RequestTokenVerifier" Type="System.String" CanBeNull="true" />
+ <Column Name="RequestTokenCallback" Type="System.String" CanBeNull="true" />
+ <Column Name="ConsumerVersion" Type="System.String" CanBeNull="true" />
+ <Association Name="OAuthConsumer_OAuthToken" Member="OAuthConsumer" ThisKey="ConsumerId" OtherKey="ConsumerId" Type="OAuthConsumer" IsForeignKey="true" DeleteRule="CASCADE" DeleteOnNull="true" />
+ <Association Name="User_OAuthToken" Member="User" ThisKey="UserId" OtherKey="UserId" Type="User" IsForeignKey="true" DeleteRule="CASCADE" />
+ </Type>
+ </Table>
+ <Table Name="" Member="Nonces">
+ <Type Name="Nonce">
+ <Column Member="Context" Type="System.String" IsPrimaryKey="true" CanBeNull="false" />
+ <Column Member="Code" Type="System.String" IsPrimaryKey="true" CanBeNull="false" />
+ <Column Member="Timestamp" Type="System.DateTime" IsPrimaryKey="true" CanBeNull="false" />
+ </Type>
+ </Table>
+</Database> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml.layout b/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml.layout
new file mode 100644
index 0000000..9b80443
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DataClasses.dbml.layout
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ordesignerObjectsDiagram dslVersion="1.0.0.0" absoluteBounds="0, 0, 11, 8.5" name="DataClasses">
+ <DataContextMoniker Name="/DataClassesDataContext" />
+ <nestedChildShapes>
+ <classShape Id="696d2c69-040e-411d-9257-bb664b743834" absoluteBounds="0.5, 0.5, 2.125, 1.7708968098958331">
+ <DataClassMoniker Name="/DataClassesDataContext/User" />
+ <nestedChildShapes>
+ <elementListCompartment Id="cd90aeff-476c-44a9-897f-a986e4a8305b" absoluteBounds="0.515, 0.96, 2.0949999999999998, 1.2108968098958333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="8a79b099-7f87-4766-907a-db2c3e1b5716" absoluteBounds="3.5, 0.625, 2, 1.3862939453125005">
+ <DataClassMoniker Name="/DataClassesDataContext/FavoriteSite" />
+ <nestedChildShapes>
+ <elementListCompartment Id="eba736b9-f9ec-484b-8083-c77155a49e4e" absoluteBounds="3.515, 1.085, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" absoluteBounds="0.625, 3.25, 2, 1.9631982421874996">
+ <DataClassMoniker Name="/DataClassesDataContext/OAuthConsumer" />
+ <nestedChildShapes>
+ <elementListCompartment Id="464308c4-d112-4448-b0c9-d9b82fb0ca4e" absoluteBounds="0.64, 3.71, 1.9700000000000002, 1.4031982421875" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <classShape Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" absoluteBounds="3.5, 3.125, 2, 2.9247054036458326">
+ <DataClassMoniker Name="/DataClassesDataContext/OAuthToken" />
+ <nestedChildShapes>
+ <elementListCompartment Id="403126d0-3d2a-4af4-b0b8-c489a830bbd4" absoluteBounds="3.515, 3.585, 1.9700000000000002, 2.364705403645833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ <associationConnector edgePoints="[(2.625 : 1.31814697265625); (3.5 : 1.31814697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+ <AssociationMoniker Name="/DataClassesDataContext/User/User_FavoriteSite" />
+ <nodes>
+ <classShapeMoniker Id="696d2c69-040e-411d-9257-bb664b743834" />
+ <classShapeMoniker Id="8a79b099-7f87-4766-907a-db2c3e1b5716" />
+ </nodes>
+ </associationConnector>
+ <associationConnector edgePoints="[(2.625 : 4.23159912109375); (3.5 : 4.23159912109375)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+ <AssociationMoniker Name="/DataClassesDataContext/OAuthConsumer/OAuthConsumer_OAuthToken" />
+ <nodes>
+ <classShapeMoniker Id="f909becb-85b1-4fe6-bb16-3feb3e4fe3ee" />
+ <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" />
+ </nodes>
+ </associationConnector>
+ <associationConnector edgePoints="[(0.53125 : 2.27089680989583); (0.53125 : 5.66270182291667); (3.5 : 5.66270182291667)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+ <AssociationMoniker Name="/DataClassesDataContext/User/User_OAuthToken" />
+ <nodes>
+ <classShapeMoniker Id="696d2c69-040e-411d-9257-bb664b743834" />
+ <classShapeMoniker Id="895ebbc8-8352-4c04-9e53-b8e6c8302d36" />
+ </nodes>
+ </associationConnector>
+ <classShape Id="a63562a7-acf2-4ed9-9686-52a1ad85633e" absoluteBounds="1.375, 6.375, 2, 1.3862939453124996">
+ <DataClassMoniker Name="/DataClassesDataContext/Nonce" />
+ <nestedChildShapes>
+ <elementListCompartment Id="9e4514ef-bc7b-4179-88e6-05363bf6ee5e" absoluteBounds="1.39, 6.835, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+ </nestedChildShapes>
+ </classShape>
+ </nestedChildShapes>
+</ordesignerObjectsDiagram> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/DataClasses.designer.cs b/src/OAuth/OAuthServiceProvider/Code/DataClasses.designer.cs
new file mode 100644
index 0000000..b7d291c
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DataClasses.designer.cs
@@ -0,0 +1,1190 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.1
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Code
+{
+ using System.Data.Linq;
+ using System.Data.Linq.Mapping;
+ using System.Data;
+ using System.Collections.Generic;
+ using System.Reflection;
+ using System.Linq;
+ using System.Linq.Expressions;
+ using System.ComponentModel;
+ using System;
+
+
+ [global::System.Data.Linq.Mapping.DatabaseAttribute(Name="Database")]
+ public partial class DataClassesDataContext : System.Data.Linq.DataContext
+ {
+
+ private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
+
+ #region Extensibility Method Definitions
+ partial void OnCreated();
+ partial void InsertUser(User instance);
+ partial void UpdateUser(User instance);
+ partial void DeleteUser(User instance);
+ partial void InsertFavoriteSite(FavoriteSite instance);
+ partial void UpdateFavoriteSite(FavoriteSite instance);
+ partial void DeleteFavoriteSite(FavoriteSite instance);
+ partial void InsertOAuthConsumer(OAuthConsumer instance);
+ partial void UpdateOAuthConsumer(OAuthConsumer instance);
+ partial void DeleteOAuthConsumer(OAuthConsumer instance);
+ partial void InsertOAuthToken(OAuthToken instance);
+ partial void UpdateOAuthToken(OAuthToken instance);
+ partial void DeleteOAuthToken(OAuthToken instance);
+ partial void InsertNonce(Nonce instance);
+ partial void UpdateNonce(Nonce instance);
+ partial void DeleteNonce(Nonce instance);
+ #endregion
+
+ public DataClassesDataContext() :
+ base(global::System.Configuration.ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(string connection) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(System.Data.IDbConnection connection) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public DataClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
+ base(connection, mappingSource)
+ {
+ OnCreated();
+ }
+
+ public System.Data.Linq.Table<User> Users
+ {
+ get
+ {
+ return this.GetTable<User>();
+ }
+ }
+
+ public System.Data.Linq.Table<FavoriteSite> FavoriteSites
+ {
+ get
+ {
+ return this.GetTable<FavoriteSite>();
+ }
+ }
+
+ public System.Data.Linq.Table<OAuthConsumer> OAuthConsumers
+ {
+ get
+ {
+ return this.GetTable<OAuthConsumer>();
+ }
+ }
+
+ public System.Data.Linq.Table<OAuthToken> OAuthTokens
+ {
+ get
+ {
+ return this.GetTable<OAuthToken>();
+ }
+ }
+
+ public System.Data.Linq.Table<Nonce> Nonces
+ {
+ get
+ {
+ return this.GetTable<Nonce>();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.[User]")]
+ public partial class User : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _UserId;
+
+ private string _OpenIDClaimedIdentifier;
+
+ private string _OpenIDFriendlyIdentifier;
+
+ private string _FullName;
+
+ private System.Nullable<int> _Age;
+
+ private EntitySet<FavoriteSite> _FavoriteSites;
+
+ private EntitySet<OAuthToken> _OAuthTokens;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnUserIdChanging(int value);
+ partial void OnUserIdChanged();
+ partial void OnOpenIDClaimedIdentifierChanging(string value);
+ partial void OnOpenIDClaimedIdentifierChanged();
+ partial void OnOpenIDFriendlyIdentifierChanging(string value);
+ partial void OnOpenIDFriendlyIdentifierChanged();
+ partial void OnFullNameChanging(string value);
+ partial void OnFullNameChanged();
+ partial void OnAgeChanging(System.Nullable<int> value);
+ partial void OnAgeChanged();
+ #endregion
+
+ public User()
+ {
+ this._FavoriteSites = new EntitySet<FavoriteSite>(new Action<FavoriteSite>(this.attach_FavoriteSites), new Action<FavoriteSite>(this.detach_FavoriteSites));
+ this._OAuthTokens = new EntitySet<OAuthToken>(new Action<OAuthToken>(this.attach_OAuthTokens), new Action<OAuthToken>(this.detach_OAuthTokens));
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int UserId
+ {
+ get
+ {
+ return this._UserId;
+ }
+ set
+ {
+ if ((this._UserId != value))
+ {
+ this.OnUserIdChanging(value);
+ this.SendPropertyChanging();
+ this._UserId = value;
+ this.SendPropertyChanged("UserId");
+ this.OnUserIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OpenIDClaimedIdentifier", DbType="NVarChar(150) NOT NULL", CanBeNull=false)]
+ public string OpenIDClaimedIdentifier
+ {
+ get
+ {
+ return this._OpenIDClaimedIdentifier;
+ }
+ set
+ {
+ if ((this._OpenIDClaimedIdentifier != value))
+ {
+ this.OnOpenIDClaimedIdentifierChanging(value);
+ this.SendPropertyChanging();
+ this._OpenIDClaimedIdentifier = value;
+ this.SendPropertyChanged("OpenIDClaimedIdentifier");
+ this.OnOpenIDClaimedIdentifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_OpenIDFriendlyIdentifier", DbType="NVarChar(150)")]
+ public string OpenIDFriendlyIdentifier
+ {
+ get
+ {
+ return this._OpenIDFriendlyIdentifier;
+ }
+ set
+ {
+ if ((this._OpenIDFriendlyIdentifier != value))
+ {
+ this.OnOpenIDFriendlyIdentifierChanging(value);
+ this.SendPropertyChanging();
+ this._OpenIDFriendlyIdentifier = value;
+ this.SendPropertyChanged("OpenIDFriendlyIdentifier");
+ this.OnOpenIDFriendlyIdentifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FullName", DbType="NVarChar(150)", CanBeNull=false)]
+ public string FullName
+ {
+ get
+ {
+ return this._FullName;
+ }
+ set
+ {
+ if ((this._FullName != value))
+ {
+ this.OnFullNameChanging(value);
+ this.SendPropertyChanging();
+ this._FullName = value;
+ this.SendPropertyChanged("FullName");
+ this.OnFullNameChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Age", DbType="int")]
+ public System.Nullable<int> Age
+ {
+ get
+ {
+ return this._Age;
+ }
+ set
+ {
+ if ((this._Age != value))
+ {
+ this.OnAgeChanging(value);
+ this.SendPropertyChanging();
+ this._Age = value;
+ this.SendPropertyChanged("Age");
+ this.OnAgeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_FavoriteSite", Storage="_FavoriteSites", ThisKey="UserId", OtherKey="UserId")]
+ public EntitySet<FavoriteSite> FavoriteSites
+ {
+ get
+ {
+ return this._FavoriteSites;
+ }
+ set
+ {
+ this._FavoriteSites.Assign(value);
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_OAuthToken", Storage="_OAuthTokens", ThisKey="UserId", OtherKey="UserId")]
+ public EntitySet<OAuthToken> OAuthTokens
+ {
+ get
+ {
+ return this._OAuthTokens;
+ }
+ set
+ {
+ this._OAuthTokens.Assign(value);
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_FavoriteSites(FavoriteSite entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = this;
+ }
+
+ private void detach_FavoriteSites(FavoriteSite entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = null;
+ }
+
+ private void attach_OAuthTokens(OAuthToken entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = this;
+ }
+
+ private void detach_OAuthTokens(OAuthToken entity)
+ {
+ this.SendPropertyChanging();
+ entity.User = null;
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.FavoriteSite")]
+ public partial class FavoriteSite : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _FavoriteSiteId;
+
+ private int _UserId;
+
+ private string _SiteUrl;
+
+ private EntityRef<User> _User;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnFavoriteSiteIdChanging(int value);
+ partial void OnFavoriteSiteIdChanged();
+ partial void OnUserIdChanging(int value);
+ partial void OnUserIdChanged();
+ partial void OnSiteUrlChanging(string value);
+ partial void OnSiteUrlChanged();
+ #endregion
+
+ public FavoriteSite()
+ {
+ this._User = default(EntityRef<User>);
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FavoriteSiteId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int FavoriteSiteId
+ {
+ get
+ {
+ return this._FavoriteSiteId;
+ }
+ set
+ {
+ if ((this._FavoriteSiteId != value))
+ {
+ this.OnFavoriteSiteIdChanging(value);
+ this.SendPropertyChanging();
+ this._FavoriteSiteId = value;
+ this.SendPropertyChanged("FavoriteSiteId");
+ this.OnFavoriteSiteIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="Int NOT NULL")]
+ public int UserId
+ {
+ get
+ {
+ return this._UserId;
+ }
+ set
+ {
+ if ((this._UserId != value))
+ {
+ if (this._User.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnUserIdChanging(value);
+ this.SendPropertyChanging();
+ this._UserId = value;
+ this.SendPropertyChanged("UserId");
+ this.OnUserIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SiteUrl", DbType="NVarChar(255) NOT NULL", CanBeNull=false)]
+ public string SiteUrl
+ {
+ get
+ {
+ return this._SiteUrl;
+ }
+ set
+ {
+ if ((this._SiteUrl != value))
+ {
+ this.OnSiteUrlChanging(value);
+ this.SendPropertyChanging();
+ this._SiteUrl = value;
+ this.SendPropertyChanged("SiteUrl");
+ this.OnSiteUrlChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_FavoriteSite", Storage="_User", ThisKey="UserId", OtherKey="UserId", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
+ public User User
+ {
+ get
+ {
+ return this._User.Entity;
+ }
+ set
+ {
+ User previousValue = this._User.Entity;
+ if (((previousValue != value)
+ || (this._User.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._User.Entity = null;
+ previousValue.FavoriteSites.Remove(this);
+ }
+ this._User.Entity = value;
+ if ((value != null))
+ {
+ value.FavoriteSites.Add(this);
+ this._UserId = value.UserId;
+ }
+ else
+ {
+ this._UserId = default(int);
+ }
+ this.SendPropertyChanged("User");
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.OAuthConsumer")]
+ public partial class OAuthConsumer : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _ConsumerId;
+
+ private string _ConsumerKey;
+
+ private string _ConsumerSecret;
+
+ private string _Callback;
+
+ private DotNetOpenAuth.OAuth.VerificationCodeFormat _VerificationCodeFormat;
+
+ private int _VerificationCodeLength;
+
+ private EntitySet<OAuthToken> _OAuthTokens;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnConsumerIdChanging(int value);
+ partial void OnConsumerIdChanged();
+ partial void OnConsumerKeyChanging(string value);
+ partial void OnConsumerKeyChanged();
+ partial void OnConsumerSecretChanging(string value);
+ partial void OnConsumerSecretChanged();
+ partial void OnCallbackChanging(string value);
+ partial void OnCallbackChanged();
+ partial void OnVerificationCodeFormatChanging(DotNetOpenAuth.OAuth.VerificationCodeFormat value);
+ partial void OnVerificationCodeFormatChanged();
+ partial void OnVerificationCodeLengthChanging(int value);
+ partial void OnVerificationCodeLengthChanged();
+ #endregion
+
+ public OAuthConsumer()
+ {
+ this._OAuthTokens = new EntitySet<OAuthToken>(new Action<OAuthToken>(this.attach_OAuthTokens), new Action<OAuthToken>(this.detach_OAuthTokens));
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int ConsumerId
+ {
+ get
+ {
+ return this._ConsumerId;
+ }
+ set
+ {
+ if ((this._ConsumerId != value))
+ {
+ this.OnConsumerIdChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerId = value;
+ this.SendPropertyChanged("ConsumerId");
+ this.OnConsumerIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerKey", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string ConsumerKey
+ {
+ get
+ {
+ return this._ConsumerKey;
+ }
+ set
+ {
+ if ((this._ConsumerKey != value))
+ {
+ this.OnConsumerKeyChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerKey = value;
+ this.SendPropertyChanged("ConsumerKey");
+ this.OnConsumerKeyChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerSecret", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string ConsumerSecret
+ {
+ get
+ {
+ return this._ConsumerSecret;
+ }
+ set
+ {
+ if ((this._ConsumerSecret != value))
+ {
+ this.OnConsumerSecretChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerSecret = value;
+ this.SendPropertyChanged("ConsumerSecret");
+ this.OnConsumerSecretChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Callback")]
+ public string Callback
+ {
+ get
+ {
+ return this._Callback;
+ }
+ set
+ {
+ if ((this._Callback != value))
+ {
+ this.OnCallbackChanging(value);
+ this.SendPropertyChanging();
+ this._Callback = value;
+ this.SendPropertyChanged("Callback");
+ this.OnCallbackChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_VerificationCodeFormat")]
+ public DotNetOpenAuth.OAuth.VerificationCodeFormat VerificationCodeFormat
+ {
+ get
+ {
+ return this._VerificationCodeFormat;
+ }
+ set
+ {
+ if ((this._VerificationCodeFormat != value))
+ {
+ this.OnVerificationCodeFormatChanging(value);
+ this.SendPropertyChanging();
+ this._VerificationCodeFormat = value;
+ this.SendPropertyChanged("VerificationCodeFormat");
+ this.OnVerificationCodeFormatChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_VerificationCodeLength")]
+ public int VerificationCodeLength
+ {
+ get
+ {
+ return this._VerificationCodeLength;
+ }
+ set
+ {
+ if ((this._VerificationCodeLength != value))
+ {
+ this.OnVerificationCodeLengthChanging(value);
+ this.SendPropertyChanging();
+ this._VerificationCodeLength = value;
+ this.SendPropertyChanged("VerificationCodeLength");
+ this.OnVerificationCodeLengthChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="OAuthConsumer_OAuthToken", Storage="_OAuthTokens", ThisKey="ConsumerId", OtherKey="ConsumerId")]
+ public EntitySet<OAuthToken> OAuthTokens
+ {
+ get
+ {
+ return this._OAuthTokens;
+ }
+ set
+ {
+ this._OAuthTokens.Assign(value);
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+
+ private void attach_OAuthTokens(OAuthToken entity)
+ {
+ this.SendPropertyChanging();
+ entity.OAuthConsumer = this;
+ }
+
+ private void detach_OAuthTokens(OAuthToken entity)
+ {
+ this.SendPropertyChanging();
+ entity.OAuthConsumer = null;
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.OAuthToken")]
+ public partial class OAuthToken : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private int _TokenId;
+
+ private string _Token;
+
+ private string _TokenSecret;
+
+ private OAuthServiceProvider.Code.TokenAuthorizationState _State;
+
+ private System.DateTime _IssueDate;
+
+ private int _ConsumerId;
+
+ private System.Nullable<int> _UserId;
+
+ private string _Scope;
+
+ private string _RequestTokenVerifier;
+
+ private string _RequestTokenCallback;
+
+ private string _ConsumerVersion;
+
+ private EntityRef<OAuthConsumer> _OAuthConsumer;
+
+ private EntityRef<User> _User;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnTokenIdChanging(int value);
+ partial void OnTokenIdChanged();
+ partial void OnTokenChanging(string value);
+ partial void OnTokenChanged();
+ partial void OnTokenSecretChanging(string value);
+ partial void OnTokenSecretChanged();
+ partial void OnStateChanging(OAuthServiceProvider.Code.TokenAuthorizationState value);
+ partial void OnStateChanged();
+ partial void OnIssueDateChanging(System.DateTime value);
+ partial void OnIssueDateChanged();
+ partial void OnConsumerIdChanging(int value);
+ partial void OnConsumerIdChanged();
+ partial void OnUserIdChanging(System.Nullable<int> value);
+ partial void OnUserIdChanged();
+ partial void OnScopeChanging(string value);
+ partial void OnScopeChanged();
+ partial void OnRequestTokenVerifierChanging(string value);
+ partial void OnRequestTokenVerifierChanged();
+ partial void OnRequestTokenCallbackChanging(string value);
+ partial void OnRequestTokenCallbackChanged();
+ partial void OnConsumerVersionChanging(string value);
+ partial void OnConsumerVersionChanged();
+ #endregion
+
+ public OAuthToken()
+ {
+ this._OAuthConsumer = default(EntityRef<OAuthConsumer>);
+ this._User = default(EntityRef<User>);
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TokenId", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
+ public int TokenId
+ {
+ get
+ {
+ return this._TokenId;
+ }
+ set
+ {
+ if ((this._TokenId != value))
+ {
+ this.OnTokenIdChanging(value);
+ this.SendPropertyChanging();
+ this._TokenId = value;
+ this.SendPropertyChanged("TokenId");
+ this.OnTokenIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Token", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string Token
+ {
+ get
+ {
+ return this._Token;
+ }
+ set
+ {
+ if ((this._Token != value))
+ {
+ this.OnTokenChanging(value);
+ this.SendPropertyChanging();
+ this._Token = value;
+ this.SendPropertyChanged("Token");
+ this.OnTokenChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_TokenSecret", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
+ public string TokenSecret
+ {
+ get
+ {
+ return this._TokenSecret;
+ }
+ set
+ {
+ if ((this._TokenSecret != value))
+ {
+ this.OnTokenSecretChanging(value);
+ this.SendPropertyChanging();
+ this._TokenSecret = value;
+ this.SendPropertyChanged("TokenSecret");
+ this.OnTokenSecretChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_State", DbType="INT NOT NULL", CanBeNull=false)]
+ public OAuthServiceProvider.Code.TokenAuthorizationState State
+ {
+ get
+ {
+ return this._State;
+ }
+ set
+ {
+ if ((this._State != value))
+ {
+ this.OnStateChanging(value);
+ this.SendPropertyChanging();
+ this._State = value;
+ this.SendPropertyChanged("State");
+ this.OnStateChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_IssueDate", DbType="DateTime NOT NULL")]
+ public System.DateTime IssueDate
+ {
+ get
+ {
+ return this._IssueDate;
+ }
+ set
+ {
+ if ((this._IssueDate != value))
+ {
+ this.OnIssueDateChanging(value);
+ this.SendPropertyChanging();
+ this._IssueDate = value;
+ this.SendPropertyChanged("IssueDate");
+ this.OnIssueDateChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerId", DbType="Int NOT NULL")]
+ public int ConsumerId
+ {
+ get
+ {
+ return this._ConsumerId;
+ }
+ set
+ {
+ if ((this._ConsumerId != value))
+ {
+ if (this._OAuthConsumer.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnConsumerIdChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerId = value;
+ this.SendPropertyChanged("ConsumerId");
+ this.OnConsumerIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="Int")]
+ public System.Nullable<int> UserId
+ {
+ get
+ {
+ return this._UserId;
+ }
+ set
+ {
+ if ((this._UserId != value))
+ {
+ if (this._User.HasLoadedOrAssignedValue)
+ {
+ throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+ }
+ this.OnUserIdChanging(value);
+ this.SendPropertyChanging();
+ this._UserId = value;
+ this.SendPropertyChanged("UserId");
+ this.OnUserIdChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Scope", DbType="nvarchar(MAX)", CanBeNull=false)]
+ public string Scope
+ {
+ get
+ {
+ return this._Scope;
+ }
+ set
+ {
+ if ((this._Scope != value))
+ {
+ this.OnScopeChanging(value);
+ this.SendPropertyChanging();
+ this._Scope = value;
+ this.SendPropertyChanged("Scope");
+ this.OnScopeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RequestTokenVerifier")]
+ public string RequestTokenVerifier
+ {
+ get
+ {
+ return this._RequestTokenVerifier;
+ }
+ set
+ {
+ if ((this._RequestTokenVerifier != value))
+ {
+ this.OnRequestTokenVerifierChanging(value);
+ this.SendPropertyChanging();
+ this._RequestTokenVerifier = value;
+ this.SendPropertyChanged("RequestTokenVerifier");
+ this.OnRequestTokenVerifierChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_RequestTokenCallback")]
+ public string RequestTokenCallback
+ {
+ get
+ {
+ return this._RequestTokenCallback;
+ }
+ set
+ {
+ if ((this._RequestTokenCallback != value))
+ {
+ this.OnRequestTokenCallbackChanging(value);
+ this.SendPropertyChanging();
+ this._RequestTokenCallback = value;
+ this.SendPropertyChanged("RequestTokenCallback");
+ this.OnRequestTokenCallbackChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ConsumerVersion")]
+ public string ConsumerVersion
+ {
+ get
+ {
+ return this._ConsumerVersion;
+ }
+ set
+ {
+ if ((this._ConsumerVersion != value))
+ {
+ this.OnConsumerVersionChanging(value);
+ this.SendPropertyChanging();
+ this._ConsumerVersion = value;
+ this.SendPropertyChanged("ConsumerVersion");
+ this.OnConsumerVersionChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="OAuthConsumer_OAuthToken", Storage="_OAuthConsumer", ThisKey="ConsumerId", OtherKey="ConsumerId", IsForeignKey=true, DeleteOnNull=true, DeleteRule="CASCADE")]
+ public OAuthConsumer OAuthConsumer
+ {
+ get
+ {
+ return this._OAuthConsumer.Entity;
+ }
+ set
+ {
+ OAuthConsumer previousValue = this._OAuthConsumer.Entity;
+ if (((previousValue != value)
+ || (this._OAuthConsumer.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._OAuthConsumer.Entity = null;
+ previousValue.OAuthTokens.Remove(this);
+ }
+ this._OAuthConsumer.Entity = value;
+ if ((value != null))
+ {
+ value.OAuthTokens.Add(this);
+ this._ConsumerId = value.ConsumerId;
+ }
+ else
+ {
+ this._ConsumerId = default(int);
+ }
+ this.SendPropertyChanged("OAuthConsumer");
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.AssociationAttribute(Name="User_OAuthToken", Storage="_User", ThisKey="UserId", OtherKey="UserId", IsForeignKey=true, DeleteRule="CASCADE")]
+ public User User
+ {
+ get
+ {
+ return this._User.Entity;
+ }
+ set
+ {
+ User previousValue = this._User.Entity;
+ if (((previousValue != value)
+ || (this._User.HasLoadedOrAssignedValue == false)))
+ {
+ this.SendPropertyChanging();
+ if ((previousValue != null))
+ {
+ this._User.Entity = null;
+ previousValue.OAuthTokens.Remove(this);
+ }
+ this._User.Entity = value;
+ if ((value != null))
+ {
+ value.OAuthTokens.Add(this);
+ this._UserId = value.UserId;
+ }
+ else
+ {
+ this._UserId = default(Nullable<int>);
+ }
+ this.SendPropertyChanged("User");
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+ public partial class Nonce : INotifyPropertyChanging, INotifyPropertyChanged
+ {
+
+ private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(string.Empty);
+
+ private string _Context;
+
+ private string _Code;
+
+ private System.DateTime _Timestamp;
+
+ #region Extensibility Method Definitions
+ partial void OnLoaded();
+ partial void OnValidate(System.Data.Linq.ChangeAction action);
+ partial void OnCreated();
+ partial void OnContextChanging(string value);
+ partial void OnContextChanged();
+ partial void OnCodeChanging(string value);
+ partial void OnCodeChanged();
+ partial void OnTimestampChanging(System.DateTime value);
+ partial void OnTimestampChanged();
+ #endregion
+
+ public Nonce()
+ {
+ OnCreated();
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Context", CanBeNull=false, IsPrimaryKey=true)]
+ public string Context
+ {
+ get
+ {
+ return this._Context;
+ }
+ set
+ {
+ if ((this._Context != value))
+ {
+ this.OnContextChanging(value);
+ this.SendPropertyChanging();
+ this._Context = value;
+ this.SendPropertyChanged("Context");
+ this.OnContextChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Code", CanBeNull=false, IsPrimaryKey=true)]
+ public string Code
+ {
+ get
+ {
+ return this._Code;
+ }
+ set
+ {
+ if ((this._Code != value))
+ {
+ this.OnCodeChanging(value);
+ this.SendPropertyChanging();
+ this._Code = value;
+ this.SendPropertyChanged("Code");
+ this.OnCodeChanged();
+ }
+ }
+ }
+
+ [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Timestamp", IsPrimaryKey=true)]
+ public System.DateTime Timestamp
+ {
+ get
+ {
+ return this._Timestamp;
+ }
+ set
+ {
+ if ((this._Timestamp != value))
+ {
+ this.OnTimestampChanging(value);
+ this.SendPropertyChanging();
+ this._Timestamp = value;
+ this.SendPropertyChanged("Timestamp");
+ this.OnTimestampChanged();
+ }
+ }
+ }
+
+ public event PropertyChangingEventHandler PropertyChanging;
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
+ protected virtual void SendPropertyChanging()
+ {
+ if ((this.PropertyChanging != null))
+ {
+ this.PropertyChanging(this, emptyChangingEventArgs);
+ }
+ }
+
+ protected virtual void SendPropertyChanged(String propertyName)
+ {
+ if ((this.PropertyChanged != null))
+ {
+ this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+ }
+ }
+ }
+}
+#pragma warning restore 1591
diff --git a/src/OAuth/OAuthServiceProvider/Code/DatabaseNonceStore.cs b/src/OAuth/OAuthServiceProvider/Code/DatabaseNonceStore.cs
new file mode 100644
index 0000000..1f8f56e
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DatabaseNonceStore.cs
@@ -0,0 +1,55 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.Messaging.Bindings;
+
+ /// <summary>
+ /// A database-persisted nonce store.
+ /// </summary>
+ public class DatabaseNonceStore : INonceStore {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="DatabaseNonceStore"/> class.
+ /// </summary>
+ public DatabaseNonceStore() {
+ }
+
+ #region INonceStore Members
+
+ /// <summary>
+ /// Stores a given nonce and timestamp.
+ /// </summary>
+ /// <param name="context">The context, or namespace, within which the
+ /// <paramref name="nonce"/> must be unique.
+ /// The context SHOULD be treated as case-sensitive.
+ /// The value will never be <c>null</c> but may be the empty string.</param>
+ /// <param name="nonce">A series of random characters.</param>
+ /// <param name="timestampUtc">The UTC timestamp that together with the nonce string make it unique
+ /// within the given <paramref name="context"/>.
+ /// The timestamp may also be used by the data store to clear out old nonces.</param>
+ /// <returns>
+ /// True if the context+nonce+timestamp (combination) was not previously in the database.
+ /// False if the nonce was stored previously with the same timestamp and context.
+ /// </returns>
+ /// <remarks>
+ /// The nonce must be stored for no less than the maximum time window a message may
+ /// be processed within before being discarded as an expired message.
+ /// This maximum message age can be looked up via the
+ /// <see cref="DotNetOpenAuth.Configuration.MessagingElement.MaximumMessageLifetime"/>
+ /// property, accessible via the <see cref="DotNetOpenAuth.Configuration.DotNetOpenAuthSection.Configuration"/>
+ /// property.
+ /// </remarks>
+ public bool StoreNonce(string context, string nonce, DateTime timestampUtc) {
+ Global.DataContext.Nonces.InsertOnSubmit(new Nonce { Context = context, Code = nonce, Timestamp = timestampUtc });
+ try {
+ Global.DataContext.SubmitChanges();
+ return true;
+ } catch (System.Data.Linq.DuplicateKeyException) {
+ return false;
+ }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/DatabaseTokenManager.cs b/src/OAuth/OAuthServiceProvider/Code/DatabaseTokenManager.cs
new file mode 100644
index 0000000..49da45d
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/DatabaseTokenManager.cs
@@ -0,0 +1,163 @@
+//-----------------------------------------------------------------------
+// <copyright file="DatabaseTokenManager.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ public class DatabaseTokenManager : IServiceProviderTokenManager {
+ #region IServiceProviderTokenManager
+
+ public IConsumerDescription GetConsumer(string consumerKey) {
+ var consumerRow = Global.DataContext.OAuthConsumers.SingleOrDefault(
+ consumerCandidate => consumerCandidate.ConsumerKey == consumerKey);
+ if (consumerRow == null) {
+ throw new KeyNotFoundException();
+ }
+
+ return consumerRow;
+ }
+
+ public IServiceProviderRequestToken GetRequestToken(string token) {
+ try {
+ return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State != TokenAuthorizationState.AccessToken);
+ } catch (InvalidOperationException ex) {
+ throw new KeyNotFoundException("Unrecognized token", ex);
+ }
+ }
+
+ public IServiceProviderAccessToken GetAccessToken(string token) {
+ try {
+ return Global.DataContext.OAuthTokens.First(t => t.Token == token && t.State == TokenAuthorizationState.AccessToken);
+ } catch (InvalidOperationException ex) {
+ throw new KeyNotFoundException("Unrecognized token", ex);
+ }
+ }
+
+ public void UpdateToken(IServiceProviderRequestToken token) {
+ // Nothing to do here, since we're using Linq To SQL, and
+ // We call LinqToSql's SubmitChanges method via our Global.Application_EndRequest method.
+ // This is a good pattern because we only save changes if the request didn't end up somehow failing.
+ // But if you DO want to save changes at this point, you could do it like so:
+ ////Global.DataContext.SubmitChanges();
+ }
+
+ #endregion
+
+ #region ITokenManager Members
+
+ public string GetTokenSecret(string token) {
+ var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(
+ tokenCandidate => tokenCandidate.Token == token);
+ if (tokenRow == null) {
+ throw new ArgumentException();
+ }
+
+ return tokenRow.TokenSecret;
+ }
+
+ public void StoreNewRequestToken(UnauthorizedTokenRequest request, ITokenSecretContainingMessage response) {
+ RequestScopedTokenMessage scopedRequest = (RequestScopedTokenMessage)request;
+ var consumer = Global.DataContext.OAuthConsumers.Single(consumerRow => consumerRow.ConsumerKey == request.ConsumerKey);
+ string scope = scopedRequest.Scope;
+ OAuthToken newToken = new OAuthToken {
+ OAuthConsumer = consumer,
+ Token = response.Token,
+ TokenSecret = response.TokenSecret,
+ IssueDate = DateTime.UtcNow,
+ Scope = scope,
+ };
+
+ Global.DataContext.OAuthTokens.InsertOnSubmit(newToken);
+ Global.DataContext.SubmitChanges();
+ }
+
+ /// <summary>
+ /// Checks whether a given request token has already been authorized
+ /// by some user for use by the Consumer that requested it.
+ /// </summary>
+ /// <param name="requestToken">The Consumer's request token.</param>
+ /// <returns>
+ /// True if the request token has already been fully authorized by the user
+ /// who owns the relevant protected resources. False if the token has not yet
+ /// been authorized, has expired or does not exist.
+ /// </returns>
+ public bool IsRequestTokenAuthorized(string requestToken) {
+ var tokenFound = Global.DataContext.OAuthTokens.SingleOrDefault(
+ token => token.Token == requestToken &&
+ token.State == TokenAuthorizationState.AuthorizedRequestToken);
+ return tokenFound != null;
+ }
+
+ public void ExpireRequestTokenAndStoreNewAccessToken(string consumerKey, string requestToken, string accessToken, string accessTokenSecret) {
+ var data = Global.DataContext;
+ var consumerRow = data.OAuthConsumers.Single(consumer => consumer.ConsumerKey == consumerKey);
+ var tokenRow = data.OAuthTokens.Single(token => token.Token == requestToken && token.OAuthConsumer == consumerRow);
+ Debug.Assert(tokenRow.State == TokenAuthorizationState.AuthorizedRequestToken, "The token should be authorized already!");
+
+ // Update the existing row to be an access token.
+ tokenRow.IssueDate = DateTime.UtcNow;
+ tokenRow.State = TokenAuthorizationState.AccessToken;
+ tokenRow.Token = accessToken;
+ tokenRow.TokenSecret = accessTokenSecret;
+ }
+
+ /// <summary>
+ /// Classifies a token as a request token or an access token.
+ /// </summary>
+ /// <param name="token">The token to classify.</param>
+ /// <returns>Request or Access token, or invalid if the token is not recognized.</returns>
+ public TokenType GetTokenType(string token) {
+ var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(tokenCandidate => tokenCandidate.Token == token);
+ if (tokenRow == null) {
+ return TokenType.InvalidToken;
+ } else if (tokenRow.State == TokenAuthorizationState.AccessToken) {
+ return TokenType.AccessToken;
+ } else {
+ return TokenType.RequestToken;
+ }
+ }
+
+ #endregion
+
+ public void AuthorizeRequestToken(string requestToken, User user) {
+ if (requestToken == null) {
+ throw new ArgumentNullException("requestToken");
+ }
+ if (user == null) {
+ throw new ArgumentNullException("user");
+ }
+
+ var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(
+ tokenCandidate => tokenCandidate.Token == requestToken &&
+ tokenCandidate.State == TokenAuthorizationState.UnauthorizedRequestToken);
+ if (tokenRow == null) {
+ throw new ArgumentException();
+ }
+
+ tokenRow.State = TokenAuthorizationState.AuthorizedRequestToken;
+ tokenRow.User = user;
+ }
+
+ public OAuthConsumer GetConsumerForToken(string token) {
+ if (string.IsNullOrEmpty(token)) {
+ throw new ArgumentNullException("requestToken");
+ }
+
+ var tokenRow = Global.DataContext.OAuthTokens.SingleOrDefault(
+ tokenCandidate => tokenCandidate.Token == token);
+ if (tokenRow == null) {
+ throw new ArgumentException();
+ }
+
+ return tokenRow.OAuthConsumer;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/Global.cs b/src/OAuth/OAuthServiceProvider/Code/Global.cs
new file mode 100644
index 0000000..60fed9f
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/Global.cs
@@ -0,0 +1,135 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Linq;
+ using System.ServiceModel;
+ using System.Text;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ /// <summary>
+ /// The web application global events and properties.
+ /// </summary>
+ public class Global : HttpApplication {
+ /// <summary>
+ /// An application memory cache of recent log messages.
+ /// </summary>
+ public static StringBuilder LogMessages = new StringBuilder();
+
+ /// <summary>
+ /// The logger for this sample to use.
+ /// </summary>
+ public static log4net.ILog Logger = log4net.LogManager.GetLogger("DotNetOpenAuth.OAuthServiceProvider");
+
+ /// <summary>
+ /// Gets the transaction-protected database connection for the current request.
+ /// </summary>
+ public static DataClassesDataContext DataContext {
+ get {
+ DataClassesDataContext dataContext = dataContextSimple;
+ if (dataContext == null) {
+ dataContext = new DataClassesDataContext();
+ dataContext.Connection.Open();
+ dataContext.Transaction = dataContext.Connection.BeginTransaction();
+ dataContextSimple = dataContext;
+ }
+
+ return dataContext;
+ }
+ }
+
+ public static DatabaseTokenManager TokenManager { get; set; }
+
+ public static DatabaseNonceStore NonceStore { get; set; }
+
+ public static User LoggedInUser {
+ get { return Global.DataContext.Users.SingleOrDefault(user => user.OpenIDClaimedIdentifier == HttpContext.Current.User.Identity.Name); }
+ }
+
+ public static UserAuthorizationRequest PendingOAuthAuthorization {
+ get { return HttpContext.Current.Session["authrequest"] as UserAuthorizationRequest; }
+ set { HttpContext.Current.Session["authrequest"] = value; }
+ }
+
+ private static DataClassesDataContext dataContextSimple {
+ get {
+ if (HttpContext.Current != null) {
+ return HttpContext.Current.Items["DataContext"] as DataClassesDataContext;
+ } else if (OperationContext.Current != null) {
+ object data;
+ if (OperationContext.Current.IncomingMessageProperties.TryGetValue("DataContext", out data)) {
+ return data as DataClassesDataContext;
+ } else {
+ return null;
+ }
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+
+ set {
+ if (HttpContext.Current != null) {
+ HttpContext.Current.Items["DataContext"] = value;
+ } else if (OperationContext.Current != null) {
+ OperationContext.Current.IncomingMessageProperties["DataContext"] = value;
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ public static void AuthorizePendingRequestToken() {
+ ITokenContainingMessage tokenMessage = PendingOAuthAuthorization;
+ TokenManager.AuthorizeRequestToken(tokenMessage.Token, LoggedInUser);
+ PendingOAuthAuthorization = null;
+ }
+
+ private static void CommitAndCloseDatabaseIfNecessary() {
+ var dataContext = dataContextSimple;
+ if (dataContext != null) {
+ dataContext.SubmitChanges();
+ dataContext.Transaction.Commit();
+ dataContext.Connection.Close();
+ }
+ }
+
+ private void Application_Start(object sender, EventArgs e) {
+ log4net.Config.XmlConfigurator.Configure();
+ Logger.Info("Sample starting...");
+ string appPath = HttpContext.Current.Request.ApplicationPath;
+ if (!appPath.EndsWith("/")) {
+ appPath += "/";
+ }
+
+ // This will break in IIS Integrated Pipeline mode, since applications
+ // start before the first incoming request context is available.
+ // TODO: fix this.
+ Constants.WebRootUrl = new Uri(HttpContext.Current.Request.Url, appPath);
+ Global.TokenManager = new DatabaseTokenManager();
+ Global.NonceStore = new DatabaseNonceStore();
+ }
+
+ private void Application_End(object sender, EventArgs e) {
+ Logger.Info("Sample shutting down...");
+
+ // this would be automatic, but in partial trust scenarios it is not.
+ log4net.LogManager.Shutdown();
+ }
+
+ private void Application_Error(object sender, EventArgs e) {
+ Logger.Error("An unhandled exception occurred in ASP.NET processing: " + Server.GetLastError(), Server.GetLastError());
+
+ // In the event of an unhandled exception, reverse any changes that were made to the database to avoid any partial database updates.
+ var dataContext = dataContextSimple;
+ if (dataContext != null) {
+ dataContext.Transaction.Rollback();
+ dataContext.Connection.Close();
+ dataContext.Dispose();
+ dataContextSimple = null;
+ }
+ }
+
+ private void Application_EndRequest(object sender, EventArgs e) {
+ CommitAndCloseDatabaseIfNecessary();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/IDataApi.cs b/src/OAuth/OAuthServiceProvider/Code/IDataApi.cs
new file mode 100644
index 0000000..45853cd
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/IDataApi.cs
@@ -0,0 +1,20 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Runtime.Serialization;
+ using System.ServiceModel;
+ using System.Text;
+
+ [ServiceContract]
+ public interface IDataApi {
+ [OperationContract]
+ int? GetAge();
+
+ [OperationContract]
+ string GetName();
+
+ [OperationContract]
+ string[] GetFavoriteSites();
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs b/src/OAuth/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
new file mode 100644
index 0000000..917a252
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/OAuthAuthorizationManager.cs
@@ -0,0 +1,65 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IdentityModel.Policy;
+ using System.Linq;
+ using System.Security.Principal;
+ using System.ServiceModel;
+ using System.ServiceModel.Channels;
+ using System.ServiceModel.Security;
+ using DotNetOpenAuth;
+ using DotNetOpenAuth.OAuth;
+
+ /// <summary>
+ /// A WCF extension to authenticate incoming messages using OAuth.
+ /// </summary>
+ public class OAuthAuthorizationManager : ServiceAuthorizationManager {
+ public OAuthAuthorizationManager() {
+ }
+
+ protected override bool CheckAccessCore(OperationContext operationContext) {
+ if (!base.CheckAccessCore(operationContext)) {
+ return false;
+ }
+
+ HttpRequestMessageProperty httpDetails = operationContext.RequestContext.RequestMessage.Properties[HttpRequestMessageProperty.Name] as HttpRequestMessageProperty;
+ Uri requestUri = operationContext.RequestContext.RequestMessage.Properties.Via;
+ ServiceProvider sp = Constants.CreateServiceProvider();
+ try {
+ var auth = sp.ReadProtectedResourceAuthorization(httpDetails, requestUri);
+ if (auth != null) {
+ var accessToken = Global.DataContext.OAuthTokens.Single(token => token.Token == auth.AccessToken);
+
+ var principal = sp.CreatePrincipal(auth);
+ var policy = new OAuthPrincipalAuthorizationPolicy(principal);
+ var policies = new List<IAuthorizationPolicy> {
+ policy,
+ };
+
+ var securityContext = new ServiceSecurityContext(policies.AsReadOnly());
+ if (operationContext.IncomingMessageProperties.Security != null) {
+ operationContext.IncomingMessageProperties.Security.ServiceSecurityContext = securityContext;
+ } else {
+ operationContext.IncomingMessageProperties.Security = new SecurityMessageProperty {
+ ServiceSecurityContext = securityContext,
+ };
+ }
+
+ securityContext.AuthorizationContext.Properties["Identities"] = new List<IIdentity> {
+ principal.Identity,
+ };
+
+ // Only allow this method call if the access token scope permits it.
+ string[] scopes = accessToken.Scope.Split('|');
+ if (scopes.Contains(operationContext.IncomingMessageHeaders.Action)) {
+ return true;
+ }
+ }
+ } catch (ProtocolException ex) {
+ Global.Logger.Error("Error processing OAuth messages.", ex);
+ }
+
+ return false;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/OAuthConsumer.cs b/src/OAuth/OAuthServiceProvider/Code/OAuthConsumer.cs
new file mode 100644
index 0000000..341afd4
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/OAuthConsumer.cs
@@ -0,0 +1,43 @@
+//-----------------------------------------------------------------------
+// <copyright file="OAuthConsumer.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public partial class OAuthConsumer : IConsumerDescription {
+ #region IConsumerDescription Members
+
+ string IConsumerDescription.Key {
+ get { return this.ConsumerKey; }
+ }
+
+ string IConsumerDescription.Secret {
+ get { return this.ConsumerSecret; }
+ }
+
+ System.Security.Cryptography.X509Certificates.X509Certificate2 IConsumerDescription.Certificate {
+ get { return null; }
+ }
+
+ Uri IConsumerDescription.Callback {
+ get { return string.IsNullOrEmpty(this.Callback) ? null : new Uri(this.Callback); }
+ }
+
+ DotNetOpenAuth.OAuth.VerificationCodeFormat IConsumerDescription.VerificationCodeFormat {
+ get { return this.VerificationCodeFormat; }
+ }
+
+ int IConsumerDescription.VerificationCodeLength {
+ get { return this.VerificationCodeLength; }
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/OAuthPrincipalAuthorizationPolicy.cs b/src/OAuth/OAuthServiceProvider/Code/OAuthPrincipalAuthorizationPolicy.cs
new file mode 100644
index 0000000..a25f4c5
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/OAuthPrincipalAuthorizationPolicy.cs
@@ -0,0 +1,47 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IdentityModel.Claims;
+ using System.IdentityModel.Policy;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public class OAuthPrincipalAuthorizationPolicy : IAuthorizationPolicy {
+ private readonly Guid uniqueId = Guid.NewGuid();
+ private readonly OAuthPrincipal principal;
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="OAuthPrincipalAuthorizationPolicy"/> class.
+ /// </summary>
+ /// <param name="principal">The principal.</param>
+ public OAuthPrincipalAuthorizationPolicy(OAuthPrincipal principal) {
+ this.principal = principal;
+ }
+
+ #region IAuthorizationComponent Members
+
+ /// <summary>
+ /// Gets a unique ID for this instance.
+ /// </summary>
+ public string Id {
+ get { return this.uniqueId.ToString(); }
+ }
+
+ #endregion
+
+ #region IAuthorizationPolicy Members
+
+ public ClaimSet Issuer {
+ get { return ClaimSet.System; }
+ }
+
+ public bool Evaluate(EvaluationContext evaluationContext, ref object state) {
+ evaluationContext.AddClaimSet(this, new DefaultClaimSet(Claim.CreateNameClaim(this.principal.Identity.Name)));
+ evaluationContext.Properties["Principal"] = this.principal;
+ return true;
+ }
+
+ #endregion
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/OAuthToken.cs b/src/OAuth/OAuthServiceProvider/Code/OAuthToken.cs
new file mode 100644
index 0000000..709b139
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/OAuthToken.cs
@@ -0,0 +1,95 @@
+//-----------------------------------------------------------------------
+// <copyright file="OAuthToken.cs" company="Outercurve Foundation">
+// Copyright (c) Outercurve Foundation. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using DotNetOpenAuth.OAuth.ChannelElements;
+
+ public partial class OAuthToken : IServiceProviderRequestToken, IServiceProviderAccessToken {
+ #region IServiceProviderRequestToken Members
+
+ string IServiceProviderRequestToken.Token {
+ get { return this.Token; }
+ }
+
+ string IServiceProviderRequestToken.ConsumerKey {
+ get { return this.OAuthConsumer.ConsumerKey; }
+ }
+
+ DateTime IServiceProviderRequestToken.CreatedOn {
+ get { return this.IssueDate; }
+ }
+
+ Uri IServiceProviderRequestToken.Callback {
+ get { return string.IsNullOrEmpty(this.RequestTokenCallback) ? null : new Uri(this.RequestTokenCallback); }
+ set { this.RequestTokenCallback = value.AbsoluteUri; }
+ }
+
+ string IServiceProviderRequestToken.VerificationCode {
+ get { return this.RequestTokenVerifier; }
+ set { this.RequestTokenVerifier = value; }
+ }
+
+ Version IServiceProviderRequestToken.ConsumerVersion {
+ get { return new Version(this.ConsumerVersion); }
+ set { this.ConsumerVersion = value.ToString(); }
+ }
+
+ #endregion
+
+ #region IServiceProviderAccessToken Members
+
+ string IServiceProviderAccessToken.Token {
+ get { return this.Token; }
+ }
+
+ DateTime? IServiceProviderAccessToken.ExpirationDate {
+ get { return null; }
+ }
+
+ string IServiceProviderAccessToken.Username {
+ get { return this.User.OpenIDClaimedIdentifier; }
+ }
+
+ string[] IServiceProviderAccessToken.Roles {
+ get { return this.Scope.Split('|'); }
+ }
+
+ #endregion
+
+ /// <summary>
+ /// Called by LinqToSql when the <see cref="IssueDate"/> property is about to change.
+ /// </summary>
+ /// <param name="value">The value.</param>
+ partial void OnIssueDateChanging(DateTime value) {
+ if (value.Kind == DateTimeKind.Unspecified) {
+ throw new ArgumentException("The DateTime.Kind cannot be Unspecified to ensure accurate timestamp checks.");
+ }
+ }
+
+ /// <summary>
+ /// Called by LinqToSql when <see cref="IssueDate"/> has changed.
+ /// </summary>
+ partial void OnIssueDateChanged() {
+ if (this.IssueDate.Kind == DateTimeKind.Local) {
+ this._IssueDate = this.IssueDate.ToUniversalTime();
+ }
+ }
+
+ /// <summary>
+ /// Called by LinqToSql when a token instance is deserialized.
+ /// </summary>
+ partial void OnLoaded() {
+ if (this.IssueDate.Kind == DateTimeKind.Unspecified) {
+ // this detail gets lost in db storage, but must be reaffirmed so that expiratoin checks succeed.
+ this._IssueDate = DateTime.SpecifyKind(this.IssueDate, DateTimeKind.Utc);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/RequestScopedTokenMessage.cs b/src/OAuth/OAuthServiceProvider/Code/RequestScopedTokenMessage.cs
new file mode 100644
index 0000000..984d683
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/RequestScopedTokenMessage.cs
@@ -0,0 +1,25 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using DotNetOpenAuth.Messaging;
+ using DotNetOpenAuth.OAuth.Messages;
+
+ /// <summary>
+ /// A custom web app version of the message sent to request an unauthorized token.
+ /// </summary>
+ public class RequestScopedTokenMessage : UnauthorizedTokenRequest {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="RequestScopedTokenMessage"/> class.
+ /// </summary>
+ /// <param name="endpoint">The endpoint that will receive the message.</param>
+ /// <param name="version">The OAuth version.</param>
+ public RequestScopedTokenMessage(MessageReceivingEndpoint endpoint, Version version)
+ : base(endpoint, version) {
+ }
+
+ /// <summary>
+ /// Gets or sets the scope of the access being requested.
+ /// </summary>
+ [MessagePart("scope", IsRequired = true)]
+ public string Scope { get; set; }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/TokenAuthorizationState.cs b/src/OAuth/OAuthServiceProvider/Code/TokenAuthorizationState.cs
new file mode 100644
index 0000000..a9cfa4e
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/TokenAuthorizationState.cs
@@ -0,0 +1,26 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+
+ /// <summary>
+ /// Various states an OAuth token can be in.
+ /// </summary>
+ public enum TokenAuthorizationState : int {
+ /// <summary>
+ /// An unauthorized request token.
+ /// </summary>
+ UnauthorizedRequestToken = 0,
+
+ /// <summary>
+ /// An authorized request token.
+ /// </summary>
+ AuthorizedRequestToken = 1,
+
+ /// <summary>
+ /// An authorized access token.
+ /// </summary>
+ AccessToken = 2,
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/TracePageAppender.cs b/src/OAuth/OAuthServiceProvider/Code/TracePageAppender.cs
new file mode 100644
index 0000000..8f97c89
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/TracePageAppender.cs
@@ -0,0 +1,13 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Web;
+
+ public class TracePageAppender : log4net.Appender.AppenderSkeleton {
+ protected override void Append(log4net.Core.LoggingEvent loggingEvent) {
+ StringWriter sw = new StringWriter(Global.LogMessages);
+ Layout.Format(sw, loggingEvent);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Code/Utilities.cs b/src/OAuth/OAuthServiceProvider/Code/Utilities.cs
new file mode 100644
index 0000000..a225650
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Code/Utilities.cs
@@ -0,0 +1,28 @@
+namespace OAuthServiceProvider.Code {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Security.Principal;
+ using System.Web;
+
+ /// <summary>
+ /// Extension methods and other helpful utility methods.
+ /// </summary>
+ public static class Utilities {
+ /// <summary>
+ /// Gets the database entity representing the user identified by a given <see cref="IIdentity"/> instance.
+ /// </summary>
+ /// <param name="identity">The identity of the user.</param>
+ /// <returns>
+ /// The database object for that user; or <c>null</c> if the user could not
+ /// be found or if <paramref name="identity"/> is <c>null</c> or represents an anonymous identity.
+ /// </returns>
+ public static User GetUser(this IIdentity identity) {
+ if (identity == null || !identity.IsAuthenticated) {
+ return null;
+ }
+
+ return Global.DataContext.Users.SingleOrDefault(user => user.OpenIDClaimedIdentifier == identity.Name);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/DataApi.cs b/src/OAuth/OAuthServiceProvider/DataApi.cs
new file mode 100644
index 0000000..9d531e6
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/DataApi.cs
@@ -0,0 +1,34 @@
+namespace OAuthServiceProvider {
+ using System.Linq;
+ using System.ServiceModel;
+ using OAuthServiceProvider.Code;
+
+ /// <summary>
+ /// The WCF service API.
+ /// </summary>
+ /// <remarks>
+ /// Note how there is no code here that is bound to OAuth or any other
+ /// credential/authorization scheme. That's all part of the channel/binding elsewhere.
+ /// And the reference to OperationContext.Current.ServiceSecurityContext.PrimaryIdentity
+ /// is the user being impersonated by the WCF client.
+ /// In the OAuth case, it is the user who authorized the OAuth access token that was used
+ /// to gain access to the service.
+ /// </remarks>
+ public class DataApi : IDataApi {
+ private User User {
+ get { return OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.GetUser(); }
+ }
+
+ public int? GetAge() {
+ return User.Age;
+ }
+
+ public string GetName() {
+ return User.FullName;
+ }
+
+ public string[] GetFavoriteSites() {
+ return User.FavoriteSites.Select(site => site.SiteUrl).ToArray();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/DataApi.svc b/src/OAuth/OAuthServiceProvider/DataApi.svc
new file mode 100644
index 0000000..50e952c
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/DataApi.svc
@@ -0,0 +1 @@
+<%@ ServiceHost Language="C#" Debug="true" Service="OAuthServiceProvider.DataApi" CodeBehind="DataApi.cs" %>
diff --git a/src/OAuth/OAuthServiceProvider/Default.aspx b/src/OAuth/OAuthServiceProvider/Default.aspx
new file mode 100644
index 0000000..3e5d820
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Default.aspx
@@ -0,0 +1,13 @@
+<%@ Page Title="DotNetOpenAuth Service Provider Sample" Language="C#" MasterPageFile="~/MasterPage.master" CodeBehind="~/Default.aspx.cs" Inherits="OAuthServiceProvider._Default" AutoEventWireup="True" %>
+
+<%@ Import Namespace="System.IO" %>
+<%@ Import Namespace="System.Data.SqlClient" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:Button ID="createDatabaseButton" runat="server" Text="(Re)create Database" OnClick="createDatabaseButton_Click" />
+ <asp:Label runat="server" ID="databaseStatus" EnableViewState="false" Text="Database recreated!"
+ Visible="false" />
+ <p>Note that to be useful, you really need to either modify the database to add an
+ account with data that will be accessed by this sample, or modify this very page
+ to inject that data into the database. </p>
+</asp:Content>
diff --git a/src/OAuth/OAuthServiceProvider/Default.aspx.cs b/src/OAuth/OAuthServiceProvider/Default.aspx.cs
new file mode 100644
index 0000000..653046a
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Default.aspx.cs
@@ -0,0 +1,49 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Configuration;
+ using System.IO;
+ using System.Linq;
+ using System.Web;
+ using OAuthServiceProvider.Code;
+
+ public partial class _Default : System.Web.UI.Page {
+ protected void createDatabaseButton_Click(object sender, EventArgs e) {
+ string databasePath = Path.Combine(Server.MapPath(Request.ApplicationPath), "App_Data");
+ if (!Directory.Exists(databasePath)) {
+ Directory.CreateDirectory(databasePath);
+ }
+ string connectionString = ConfigurationManager.ConnectionStrings["DatabaseConnectionString"].ConnectionString.Replace("|DataDirectory|", databasePath);
+ var dc = new DataClassesDataContext(connectionString);
+ if (dc.DatabaseExists()) {
+ dc.DeleteDatabase();
+ }
+ try {
+ dc.CreateDatabase();
+
+ // Fill with sample data.
+ dc.OAuthConsumers.InsertOnSubmit(new OAuthConsumer {
+ ConsumerKey = "sampleconsumer",
+ ConsumerSecret = "samplesecret",
+ });
+ dc.Users.InsertOnSubmit(new User {
+ OpenIDFriendlyIdentifier = "=arnott",
+ OpenIDClaimedIdentifier = "=!9B72.7DD1.50A9.5CCD",
+ Age = 27,
+ FullName = "Andrew Arnott",
+ FavoriteSites = new System.Data.Linq.EntitySet<FavoriteSite> {
+ new FavoriteSite { SiteUrl = "http://www.microsoft.com" },
+ new FavoriteSite { SiteUrl = "http://www.google.com" },
+ },
+ });
+
+ dc.SubmitChanges();
+ this.databaseStatus.Visible = true;
+ } catch (System.Data.SqlClient.SqlException ex) {
+ foreach (System.Data.SqlClient.SqlError error in ex.Errors) {
+ Response.Write(error.Message);
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Default.aspx.designer.cs b/src/OAuth/OAuthServiceProvider/Default.aspx.designer.cs
new file mode 100644
index 0000000..afa79c0
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Default.aspx.designer.cs
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider {
+
+
+ public partial class _Default {
+
+ /// <summary>
+ /// createDatabaseButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button createDatabaseButton;
+
+ /// <summary>
+ /// databaseStatus control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label databaseStatus;
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/Global.asax b/src/OAuth/OAuthServiceProvider/Global.asax
new file mode 100644
index 0000000..3007bd3
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Global.asax
@@ -0,0 +1 @@
+<%@ Application Inherits="OAuthServiceProvider.Code.Global" CodeBehind="Code\Global.cs" %> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Login.aspx b/src/OAuth/OAuthServiceProvider/Login.aspx
new file mode 100644
index 0000000..4498ee0
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Login.aspx
@@ -0,0 +1,7 @@
+<%@ Page Title="Login" Language="C#" MasterPageFile="~/MasterPage.master" %>
+
+<%@ Register Assembly="DotNetOpenAuth.OpenId.RelyingParty.UI" Namespace="DotNetOpenAuth.OpenId.RelyingParty" TagPrefix="rp" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <rp:OpenIdLogin runat="server" TabIndex='1' />
+</asp:Content>
diff --git a/src/OAuth/OAuthServiceProvider/MasterPage.master b/src/OAuth/OAuthServiceProvider/MasterPage.master
new file mode 100644
index 0000000..136dfc9
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/MasterPage.master
@@ -0,0 +1,23 @@
+<%@ Master Language="C#" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<script runat="server">
+
+</script>
+
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title>DotNetOpenAuth Service Provider sample</title>
+ <asp:ContentPlaceHolder ID="head" runat="server"/>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <h1>DotNetOpenAuth Service Provider sample</h1>
+ <div>
+ <asp:ContentPlaceHolder ID="Body" runat="server">
+ </asp:ContentPlaceHolder>
+ </div>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx
new file mode 100644
index 0000000..b3e2c6a
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx
@@ -0,0 +1,58 @@
+<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthServiceProvider.Authorize" Codebehind="Authorize.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <asp:MultiView runat="server" ActiveViewIndex="0" ID="multiView">
+ <asp:View runat="server">
+ <div style="background-color: Yellow">
+ <b>Warning</b>: Never give your login credentials to another web site or application.
+ </div>
+ <asp:HiddenField runat="server" ID="OAuthAuthorizationSecToken" EnableViewState="false" />
+ <p>The client web site or application <asp:Label ID="consumerLabel" Font-Bold="true"
+ runat="server" Text="[consumer]" /> wants access to your <asp:Label ID="desiredAccessLabel"
+ Font-Bold="true" runat="server" Text="[protected resource]" />. </p>
+ <p>Do you want to allow this? </p>
+ <div style="display: none" id="responseButtonsDiv">
+ <asp:Button ID="allowAccessButton" runat="server" Text="Yes" OnClick="allowAccessButton_Click" />
+ <asp:Button ID="denyAccessButton" runat="server" Text="No" OnClick="denyAccessButton_Click" />
+ </div>
+ <div id="javascriptDisabled">
+ <b>Javascript appears to be disabled in your browser. </b>This page requires Javascript
+ to be enabled to better protect your security.
+ </div>
+ <p>If you grant access now, you can revoke it at any time by returning to this page.
+ </p>
+ <asp:Panel runat="server" BackColor="Red" ForeColor="White" Font-Bold="true" Visible="false" ID="OAuth10ConsumerWarning">
+ This website is registered with service_PROVIDER_DOMAIN_NAME to make authorization requests, but has not been configured to send requests securely. If you grant access but you did not initiate this request at consumer_DOMAIN_NAME, it may be possible for other users of consumer_DOMAIN_NAME to access your data. We recommend you deny access unless you are certain that you initiated this request directly with consumer_DOMAIN_NAME.
+ </asp:Panel>
+ <script language="javascript" type="text/javascript">
+ //<![CDATA[
+ // we use HTML to hide the action buttons and Javascript to show them
+ // to protect against click-jacking in an iframe whose javascript is disabled.
+ document.getElementById('responseButtonsDiv').style.display = 'block';
+ document.getElementById('javascriptDisabled').style.display = 'none';
+
+ // Frame busting code (to protect us from being hosted in an iframe).
+ // This protects us from click-jacking.
+ if (document.location !== window.top.location) {
+ window.top.location = document.location;
+ }
+ //]]>
+ </script>
+ </asp:View>
+ <asp:View runat="server">
+ <p>Authorization has been granted.</p>
+ <asp:MultiView runat="server" ID="verifierMultiView" ActiveViewIndex="0">
+ <asp:View runat="server">
+ <p>You must enter this verification code at the Consumer: <asp:Label runat="server"
+ ID="verificationCodeLabel" /> </p>
+ </asp:View>
+ <asp:View ID="View1" runat="server">
+ <p>You may now close this window and return to the Consumer. </p>
+ </asp:View>
+ </asp:MultiView>
+ </asp:View>
+ <asp:View runat="server">
+ <p>Authorization has been denied. You're free to do whatever now. </p>
+ </asp:View>
+ </asp:MultiView>
+</asp:Content>
diff --git a/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.cs b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.cs
new file mode 100644
index 0000000..faa2147
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.cs
@@ -0,0 +1,80 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Security.Cryptography;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using DotNetOpenAuth;
+ using DotNetOpenAuth.OAuth;
+ using DotNetOpenAuth.OAuth.Messages;
+ using OAuthServiceProvider.Code;
+
+ /// <summary>
+ /// Conducts the user through a Consumer authorization process.
+ /// </summary>
+ public partial class Authorize : System.Web.UI.Page {
+ private static readonly RandomNumberGenerator CryptoRandomDataGenerator = new RNGCryptoServiceProvider();
+
+ private string AuthorizationSecret {
+ get { return Session["OAuthAuthorizationSecret"] as string; }
+ set { Session["OAuthAuthorizationSecret"] = value; }
+ }
+
+ protected void Page_Load(object sender, EventArgs e) {
+ if (!IsPostBack) {
+ if (Global.PendingOAuthAuthorization == null) {
+ Response.Redirect("~/Members/AuthorizedConsumers.aspx");
+ } else {
+ ITokenContainingMessage pendingToken = Global.PendingOAuthAuthorization;
+ var token = Global.DataContext.OAuthTokens.Single(t => t.Token == pendingToken.Token);
+ this.desiredAccessLabel.Text = token.Scope;
+ this.consumerLabel.Text = Global.TokenManager.GetConsumerForToken(token.Token).ConsumerKey;
+
+ // Generate an unpredictable secret that goes to the user agent and must come back
+ // with authorization to guarantee the user interacted with this page rather than
+ // being scripted by an evil Consumer.
+ byte[] randomData = new byte[8];
+ CryptoRandomDataGenerator.GetBytes(randomData);
+ this.AuthorizationSecret = Convert.ToBase64String(randomData);
+ this.OAuthAuthorizationSecToken.Value = this.AuthorizationSecret;
+
+ this.OAuth10ConsumerWarning.Visible = Global.PendingOAuthAuthorization.IsUnsafeRequest;
+ }
+ }
+ }
+
+ protected void allowAccessButton_Click(object sender, EventArgs e) {
+ if (this.AuthorizationSecret != this.OAuthAuthorizationSecToken.Value) {
+ throw new ArgumentException(); // probably someone trying to hack in.
+ }
+ this.AuthorizationSecret = null; // clear one time use secret
+ var pending = Global.PendingOAuthAuthorization;
+ Global.AuthorizePendingRequestToken();
+ this.multiView.ActiveViewIndex = 1;
+
+ ServiceProvider sp = new ServiceProvider(Constants.SelfDescription, Global.TokenManager);
+ var response = sp.PrepareAuthorizationResponse(pending);
+ if (response != null) {
+ sp.Channel.Send(response);
+ } else {
+ if (pending.IsUnsafeRequest) {
+ this.verifierMultiView.ActiveViewIndex = 1;
+ } else {
+ string verifier = ServiceProvider.CreateVerificationCode(VerificationCodeFormat.AlphaNumericNoLookAlikes, 10);
+ this.verificationCodeLabel.Text = verifier;
+ ITokenContainingMessage requestTokenMessage = pending;
+ var requestToken = Global.TokenManager.GetRequestToken(requestTokenMessage.Token);
+ requestToken.VerificationCode = verifier;
+ Global.TokenManager.UpdateToken(requestToken);
+ }
+ }
+ }
+
+ protected void denyAccessButton_Click(object sender, EventArgs e) {
+ // erase the request token.
+ this.multiView.ActiveViewIndex = 2;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.designer.cs b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.designer.cs
new file mode 100644
index 0000000..8aaf94d
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Authorize.aspx.designer.cs
@@ -0,0 +1,105 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider {
+
+
+ public partial class Authorize {
+
+ /// <summary>
+ /// multiView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView multiView;
+
+ /// <summary>
+ /// OAuthAuthorizationSecToken control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.HiddenField OAuthAuthorizationSecToken;
+
+ /// <summary>
+ /// consumerLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label consumerLabel;
+
+ /// <summary>
+ /// desiredAccessLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label desiredAccessLabel;
+
+ /// <summary>
+ /// allowAccessButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button allowAccessButton;
+
+ /// <summary>
+ /// denyAccessButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button denyAccessButton;
+
+ /// <summary>
+ /// OAuth10ConsumerWarning control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Panel OAuth10ConsumerWarning;
+
+ /// <summary>
+ /// verifierMultiView control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.MultiView verifierMultiView;
+
+ /// <summary>
+ /// verificationCodeLabel control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Label verificationCodeLabel;
+
+ /// <summary>
+ /// View1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.View View1;
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx
new file mode 100644
index 0000000..3506eb9
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx
@@ -0,0 +1,6 @@
+<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" Inherits="OAuthServiceProvider.AuthorizedConsumers" Codebehind="AuthorizedConsumers.aspx.cs" %>
+
+<asp:Content ID="Content2" ContentPlaceHolderID="Body" runat="Server">
+ <h2>The following consumers have access to your data</h2>
+ <p>TODO</p>
+</asp:Content>
diff --git a/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.cs b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.cs
new file mode 100644
index 0000000..fe647a8
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.cs
@@ -0,0 +1,17 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+
+ /// <summary>
+ /// Lists the consumers that have active request or access tokens
+ /// and provides a mechanism for the user to revoke permissions.
+ /// </summary>
+ public partial class AuthorizedConsumers : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.designer.cs b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.designer.cs
new file mode 100644
index 0000000..419c114
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/AuthorizedConsumers.aspx.designer.cs
@@ -0,0 +1,15 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider {
+
+
+ public partial class AuthorizedConsumers {
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/Members/Logoff.aspx b/src/OAuth/OAuthServiceProvider/Members/Logoff.aspx
new file mode 100644
index 0000000..afa9dd9
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Logoff.aspx
@@ -0,0 +1,8 @@
+<%@ Page Title="Log off" Language="C#" MasterPageFile="~/MasterPage.master" %>
+
+<script runat="server">
+ private void Page_Load(object sender, EventArgs e) {
+ FormsAuthentication.SignOut();
+ Response.Redirect("~/");
+ }
+</script>
diff --git a/src/OAuth/OAuthServiceProvider/Members/Web.config b/src/OAuth/OAuthServiceProvider/Members/Web.config
new file mode 100644
index 0000000..50fab27
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Members/Web.config
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<configuration>
+ <system.web>
+ <authorization>
+ <deny users="?"/>
+ </authorization>
+ </system.web>
+</configuration>
diff --git a/src/OAuth/OAuthServiceProvider/OAuth.ashx b/src/OAuth/OAuthServiceProvider/OAuth.ashx
new file mode 100644
index 0000000..8a74926
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/OAuth.ashx
@@ -0,0 +1,42 @@
+<%@ WebHandler Language="C#" Class="OAuth" %>
+
+using System;
+using System.Linq;
+using System.Web;
+using System.Web.SessionState;
+using DotNetOpenAuth.OAuth;
+using DotNetOpenAuth.OAuth.ChannelElements;
+using DotNetOpenAuth.OAuth.Messages;
+using DotNetOpenAuth.Messaging;
+using OAuthServiceProvider.Code;
+
+public class OAuth : IHttpHandler, IRequiresSessionState {
+ ServiceProvider sp;
+
+ public OAuth() {
+ sp = new ServiceProvider(Constants.SelfDescription, Global.TokenManager, new CustomOAuthMessageFactory(Global.TokenManager));
+ }
+
+ public void ProcessRequest(HttpContext context) {
+ IProtocolMessage request = sp.ReadRequest();
+ RequestScopedTokenMessage requestToken;
+ UserAuthorizationRequest requestAuth;
+ AuthorizedTokenRequest requestAccessToken;
+ if ((requestToken = request as RequestScopedTokenMessage) != null) {
+ var response = sp.PrepareUnauthorizedTokenMessage(requestToken);
+ sp.Channel.Send(response);
+ } else if ((requestAuth = request as UserAuthorizationRequest) != null) {
+ Global.PendingOAuthAuthorization = requestAuth;
+ HttpContext.Current.Response.Redirect("~/Members/Authorize.aspx");
+ } else if ((requestAccessToken = request as AuthorizedTokenRequest) != null) {
+ var response = sp.PrepareAccessTokenMessage(requestAccessToken);
+ sp.Channel.Send(response);
+ } else {
+ throw new InvalidOperationException();
+ }
+ }
+
+ public bool IsReusable {
+ get { return true; }
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/OAuthServiceProvider.csproj b/src/OAuth/OAuthServiceProvider/OAuthServiceProvider.csproj
new file mode 100644
index 0000000..f8c1eb5
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/OAuthServiceProvider.csproj
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))\EnlistmentInfo.props" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.props))' != '' " />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{CAA2408C-6918-4902-A512-58BCD62216C3}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>OAuthServiceProvider</RootNamespace>
+ <AssemblyName>OAuthServiceProvider</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <UseIISExpress>false</UseIISExpress>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net">
+ <HintPath>..\..\lib\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Data.Linq" />
+ <Reference Include="System.IdentityModel" />
+ <Reference Include="System.ServiceModel" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="System.Web.Mobile" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="DataApi.svc" />
+ <Content Include="Default.aspx" />
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="Login.aspx" />
+ <Content Include="Members\Authorize.aspx" />
+ <Content Include="Members\AuthorizedConsumers.aspx" />
+ <Content Include="Members\Logoff.aspx" />
+ <Content Include="TracePage.aspx" />
+ <Content Include="Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Code\DatabaseNonceStore.cs" />
+ <Compile Include="Default.aspx.designer.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="DataApi.cs">
+ <DependentUpon>DataApi.svc</DependentUpon>
+ </Compile>
+ <Compile Include="Members\Authorize.aspx.designer.cs">
+ <DependentUpon>Authorize.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Members\AuthorizedConsumers.aspx.designer.cs">
+ <DependentUpon>AuthorizedConsumers.aspx</DependentUpon>
+ </Compile>
+ <Compile Include="Code\Constants.cs" />
+ <Compile Include="Code\CustomOAuthTypeProvider.cs" />
+ <Compile Include="Code\DatabaseTokenManager.cs" />
+ <Compile Include="Code\Global.cs" />
+ <Compile Include="Code\IDataApi.cs" />
+ <Compile Include="Code\OAuthAuthorizationManager.cs" />
+ <Compile Include="Code\OAuthConsumer.cs" />
+ <Compile Include="Code\OAuthPrincipalAuthorizationPolicy.cs" />
+ <Compile Include="Code\OAuthToken.cs" />
+ <Compile Include="Code\RequestScopedTokenMessage.cs" />
+ <Compile Include="Code\TokenAuthorizationState.cs" />
+ <Compile Include="Code\TracePageAppender.cs" />
+ <Compile Include="Code\Utilities.cs" />
+ <Compile Include="Code\DataClasses.designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>DataClasses.dbml</DependentUpon>
+ </Compile>
+ <Compile Include="Default.aspx.cs">
+ <DependentUpon>Default.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Members\Authorize.aspx.cs">
+ <DependentUpon>Authorize.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="Members\AuthorizedConsumers.aspx.cs">
+ <DependentUpon>AuthorizedConsumers.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ <SubType>ASPXCodeBehind</SubType>
+ </Compile>
+ <Compile Include="TracePage.aspx.designer.cs">
+ <DependentUpon>TracePage.aspx</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="OAuth.ashx" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="MasterPage.master" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\DataClasses.dbml">
+ <Generator>MSLinqToSQLGenerator</Generator>
+ <LastGenOutput>DataClasses.designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </None>
+ <Content Include="Members\Web.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Code\DataClasses.dbml.layout">
+ <DependentUpon>DataClasses.dbml</DependentUpon>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.Core\DotNetOpenAuth.Core.csproj">
+ <Project>{60426312-6AE5-4835-8667-37EDEA670222}</Project>
+ <Name>DotNetOpenAuth.Core</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OAuth.Common\DotNetOpenAuth.OAuth.Common.csproj">
+ <Project>{115217C5-22CD-415C-A292-0DD0238CDD89}</Project>
+ <Name>DotNetOpenAuth.OAuth.Common</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OAuth.ServiceProvider\DotNetOpenAuth.OAuth.ServiceProvider.csproj">
+ <Project>{FED1923A-6D70-49B5-A37A-FB744FEC1C86}</Project>
+ <Name>DotNetOpenAuth.OAuth.ServiceProvider</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OAuth\DotNetOpenAuth.OAuth.csproj">
+ <Project>{A288FCC8-6FCF-46DA-A45E-5F9281556361}</Project>
+ <Name>DotNetOpenAuth.OAuth</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OpenId.RelyingParty.UI\DotNetOpenAuth.OpenId.RelyingParty.UI.csproj">
+ <Project>{1ED8D424-F8AB-4050-ACEB-F27F4F909484}</Project>
+ <Name>DotNetOpenAuth.OpenId.RelyingParty.UI</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OpenId.RelyingParty\DotNetOpenAuth.OpenId.RelyingParty.csproj">
+ <Project>{F458AB60-BA1C-43D9-8CEF-EC01B50BE87B}</Project>
+ <Name>DotNetOpenAuth.OpenId.RelyingParty</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\..\src\DotNetOpenAuth.OpenId\DotNetOpenAuth.OpenId.csproj">
+ <Project>{3896A32A-E876-4C23-B9B8-78E17D134CD3}</Project>
+ <Name>DotNetOpenAuth.OpenId</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>False</UseIIS>
+ <AutoAssignPort>False</AutoAssignPort>
+ <DevelopmentServerPort>65169</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>
+ </IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " />
+</Project> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/Properties/AssemblyInfo.cs b/src/OAuth/OAuthServiceProvider/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..09d299c
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("OAuthServiceProvider")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("OAuthServiceProvider")]
+[assembly: AssemblyCopyright("Copyright © 2010")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("B6206451-6557-4568-8D25-84AF93EC8B7B")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/OAuth/OAuthServiceProvider/Settings.StyleCop b/src/OAuth/OAuthServiceProvider/Settings.StyleCop
new file mode 100644
index 0000000..7f55ce6
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Settings.StyleCop
@@ -0,0 +1 @@
+<StyleCopSettings Version="4.3" /> \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/TracePage.aspx b/src/OAuth/OAuthServiceProvider/TracePage.aspx
new file mode 100644
index 0000000..e83adc3
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/TracePage.aspx
@@ -0,0 +1,18 @@
+<%@ Page Language="C#" AutoEventWireup="true" Inherits="OAuthServiceProvider.TracePage" Codebehind="TracePage.aspx.cs" %>
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head runat="server">
+ <title></title>
+</head>
+<body>
+ <form id="form1" runat="server">
+ <p align="right">
+ <asp:Button runat="server" Text="Clear log" ID="clearLogButton" OnClick="clearLogButton_Click" />
+ </p>
+ <pre>
+ <asp:PlaceHolder runat="server" ID="placeHolder1" />
+ </pre>
+ </form>
+</body>
+</html>
diff --git a/src/OAuth/OAuthServiceProvider/TracePage.aspx.cs b/src/OAuth/OAuthServiceProvider/TracePage.aspx.cs
new file mode 100644
index 0000000..fcfade5
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/TracePage.aspx.cs
@@ -0,0 +1,24 @@
+namespace OAuthServiceProvider {
+ using System;
+ using System.Collections.Generic;
+ using System.Web;
+ using System.Web.UI;
+ using System.Web.UI.WebControls;
+ using OAuthServiceProvider.Code;
+
+ /// <summary>
+ /// A page to display recent log messages.
+ /// </summary>
+ public partial class TracePage : System.Web.UI.Page {
+ protected void Page_Load(object sender, EventArgs e) {
+ this.placeHolder1.Controls.Add(new Label { Text = HttpUtility.HtmlEncode(Global.LogMessages.ToString()) });
+ }
+
+ protected void clearLogButton_Click(object sender, EventArgs e) {
+ Global.LogMessages.Length = 0;
+
+ // clear the page immediately, and allow for F5 without a Postback warning.
+ Response.Redirect(Request.Url.AbsoluteUri);
+ }
+ }
+} \ No newline at end of file
diff --git a/src/OAuth/OAuthServiceProvider/TracePage.aspx.designer.cs b/src/OAuth/OAuthServiceProvider/TracePage.aspx.designer.cs
new file mode 100644
index 0000000..3cd04be
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/TracePage.aspx.designer.cs
@@ -0,0 +1,42 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace OAuthServiceProvider {
+
+
+ public partial class TracePage {
+
+ /// <summary>
+ /// form1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.HtmlControls.HtmlForm form1;
+
+ /// <summary>
+ /// clearLogButton control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.Button clearLogButton;
+
+ /// <summary>
+ /// placeHolder1 control.
+ /// </summary>
+ /// <remarks>
+ /// Auto-generated field.
+ /// To modify move field declaration from designer file to code-behind file.
+ /// </remarks>
+ protected global::System.Web.UI.WebControls.PlaceHolder placeHolder1;
+ }
+}
diff --git a/src/OAuth/OAuthServiceProvider/Web.config b/src/OAuth/OAuthServiceProvider/Web.config
new file mode 100644
index 0000000..60a4d86
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/Web.config
@@ -0,0 +1,180 @@
+<?xml version="1.0"?>
+<configuration>
+ <configSections>
+ <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
+ <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler" requirePermission="false"/>
+ <sectionGroup name="dotNetOpenAuth" type="DotNetOpenAuth.Configuration.DotNetOpenAuthSection, DotNetOpenAuth.Core">
+ <section name="oauth" type="DotNetOpenAuth.Configuration.OAuthElement, DotNetOpenAuth.OAuth" requirePermission="false" allowLocation="true" />
+ <section name="messaging" type="DotNetOpenAuth.Configuration.MessagingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ <section name="reporting" type="DotNetOpenAuth.Configuration.ReportingElement, DotNetOpenAuth.Core" requirePermission="false" allowLocation="true" />
+ </sectionGroup>
+ <sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
+ <section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ <section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
+ </sectionGroup>
+ </sectionGroup>
+ </sectionGroup>
+ </configSections>
+
+ <!-- The uri section is necessary to turn on .NET 3.5 support for IDN (international domain names),
+ which is necessary for OpenID urls with unicode characters in the domain/host name.
+ It is also required to put the Uri class into RFC 3986 escaping mode, which OpenID and OAuth require. -->
+ <uri>
+ <idn enabled="All"/>
+ <iriParsing enabled="true"/>
+ </uri>
+
+ <system.net>
+ <defaultProxy enabled="true" />
+ <settings>
+ <!-- This setting causes .NET to check certificate revocation lists (CRL)
+ before trusting HTTPS certificates. But this setting tends to not
+ be allowed in shared hosting environments. -->
+ <!--<servicePointManager checkCertificateRevocationList="true"/>-->
+ </settings>
+ </system.net>
+
+ <!-- this is an optional configuration section where aspects of dotnetopenauth can be customized -->
+ <dotNetOpenAuth>
+ <!-- Allow DotNetOpenAuth to publish usage statistics to library authors to improve the library. -->
+ <reporting enabled="true" />
+ <messaging>
+ <untrustedWebRequest>
+ <whitelistHosts>
+ <add name="localhost"/>
+ </whitelistHosts>
+ </untrustedWebRequest>
+ </messaging>
+ </dotNetOpenAuth>
+
+ <appSettings/>
+ <connectionStrings>
+ <add name="DatabaseConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True"
+ providerName="System.Data.SqlClient" />
+ </connectionStrings>
+
+ <system.web>
+ <!--
+ Set compilation debug="true" to insert debugging
+ symbols into the compiled page. Because this
+ affects performance, set this value to true only
+ during development.
+ -->
+ <compilation debug="true">
+ <assemblies>
+ <add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
+ <remove assembly="DotNetOpenAuth.Contracts"/>
+ </assemblies>
+ </compilation>
+ <authentication mode="Forms">
+ <forms name="oauthSP" />
+ </authentication>
+ <pages>
+ <controls>
+ <add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </controls>
+ </pages>
+ <httpHandlers>
+ <remove verb="*" path="*.asmx"/>
+ <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
+ </httpHandlers>
+ <httpModules>
+ <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </httpModules>
+ </system.web>
+ <system.codedom>
+ <compilers>
+ <compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <providerOption name="CompilerVersion" value="v3.5"/>
+ <providerOption name="WarnAsError" value="false"/>
+ </compiler>
+ <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+ <providerOption name="CompilerVersion" value="v3.5"/>
+ <providerOption name="OptionInfer" value="true"/>
+ <providerOption name="WarnAsError" value="false"/>
+ </compiler>
+ </compilers>
+ </system.codedom>
+ <!--
+ The system.webServer section is required for running ASP.NET AJAX under Internet
+ Information Services 7.0. It is not necessary for previous version of IIS.
+ -->
+ <system.webServer>
+ <validation validateIntegratedModeConfiguration="false"/>
+ <modules>
+ <remove name="ScriptModule"/>
+ <add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </modules>
+ <handlers>
+ <remove name="WebServiceHandlerFactory-Integrated"/>
+ <remove name="ScriptHandlerFactory"/>
+ <remove name="ScriptHandlerFactoryAppServices"/>
+ <remove name="ScriptResource"/>
+ <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ <add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+ </handlers>
+ </system.webServer>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+ <log4net>
+ <appender name="TracePageAppender" type="OAuthServiceProvider.Code.TracePageAppender, OAuthServiceProvider">
+ <layout type="log4net.Layout.PatternLayout">
+ <conversionPattern value="%date (GMT%date{%z}) [%thread] %-5level %logger - %message%newline"/>
+ </layout>
+ </appender>
+ <!-- Setup the root category, add the appenders and set the default level -->
+ <root>
+ <level value="INFO"/>
+ <!--<appender-ref ref="RollingFileAppender" />-->
+ <appender-ref ref="TracePageAppender"/>
+ </root>
+ <!-- Specify the level for some specific categories -->
+ <logger name="DotNetOpenAuth">
+ <level value="ALL"/>
+ </logger>
+ </log4net>
+ <system.serviceModel>
+ <behaviors>
+ <serviceBehaviors>
+ <behavior name="DataApiBehavior">
+ <serviceMetadata httpGetEnabled="true"/>
+ <serviceDebug includeExceptionDetailInFaults="true"/>
+ <serviceAuthorization serviceAuthorizationManagerType="OAuthServiceProvider.Code.OAuthAuthorizationManager, OAuthServiceProvider" principalPermissionMode="Custom"/>
+ </behavior>
+ </serviceBehaviors>
+ </behaviors>
+ <services>
+ <service behaviorConfiguration="DataApiBehavior" name="OAuthServiceProvider.DataApi">
+ <endpoint address="" binding="wsHttpBinding" contract="OAuthServiceProvider.Code.IDataApi">
+ <identity>
+ <dns value="localhost"/>
+ </identity>
+ </endpoint>
+ <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
+ </service>
+ </services>
+ </system.serviceModel>
+</configuration>
diff --git a/src/OAuth/OAuthServiceProvider/favicon.ico b/src/OAuth/OAuthServiceProvider/favicon.ico
new file mode 100644
index 0000000..e227dbe
--- /dev/null
+++ b/src/OAuth/OAuthServiceProvider/favicon.ico
Binary files differ