diff --git a/.azure/pipelines/ci.yml b/.azure/pipelines/ci.yml index cc205852e640d411466058acf12a1e393f116fc8..f0a760d1f172edd663dc6af64590ff1a63a54de7 100644 --- a/.azure/pipelines/ci.yml +++ b/.azure/pipelines/ci.yml @@ -303,15 +303,10 @@ jobs: displayName: Install SQL Server 2016 Express LocalDB - powershell: "& ./src/Servers/IIS/tools/UpdateIISExpressCertificate.ps1; & ./src/Servers/IIS/tools/update_schema.ps1" displayName: Setup IISExpress test certificates and schema - - powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Setup signalrclienttests.exe" - displayName: Start AppVerifier afterBuild: - powershell: "& ./build.ps1 -CI -NoBuild -Test /p:RunFlakyTests=true" displayName: Run Flaky Tests continueOnError: true - - powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Shutdown signalrclienttests.exe" - displayName: Stop AppVerifier - condition: always() artifacts: - name: Windows_Test_Logs path: artifacts/logs/ diff --git a/.azure/pipelines/signalr-daily-tests.yml b/.azure/pipelines/signalr-daily-tests.yml index 3269b2657a70b24b8045e975a8acb592227c2130..2e74597f738ae1ce0075a96cbf2edf4ad33def89 100644 --- a/.azure/pipelines/signalr-daily-tests.yml +++ b/.azure/pipelines/signalr-daily-tests.yml @@ -14,11 +14,4 @@ jobs: agentOs: Windows jobName: SignalRDailyTests jobDisplayName: "SignalR Daily Tests" - beforeBuild: - - powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Setup signalrclienttests.exe" - displayName: Start AppVerifier - afterBuild: - - powershell: "& ./.azure/pipelines/tools/SetupTestEnvironment.ps1 Shutdown signalrclienttests.exe" - displayName: Stop AppVerifier - condition: always() diff --git a/build/repo.props b/build/repo.props index f453c3c5c81223c867c8d7c8e3a6e92499c172c5..1452299ad8d383046c49fa2825c12aadd9e6dd5b 100644 --- a/build/repo.props +++ b/build/repo.props @@ -54,8 +54,6 @@ $(RepositoryRoot)src\Tools\dotnet-watch\test\TestProjects\**\*.csproj; $(RepositoryRoot)src\Razor\Razor.Design\test\testassets\**\*.*proj; $(RepositoryRoot)src\submodules\**\*.*proj; - $(RepositoryRoot)src\SignalR\clients\cpp\samples\**\*.*proj; - $(RepositoryRoot)src\SignalR\clients\cpp\test\signalrclient-testhost\**\*.*proj; $(RepositoryRoot)src\Installers\**\*.*proj; $(RepositoryRoot)src\SignalR\clients\ts\**\node_modules\**\*.*proj; $(RepositoryRoot)src\Components\Blazor\Templates\src\content\**\*.*proj; diff --git a/src/SignalR/.gitmodules b/src/SignalR/.gitmodules deleted file mode 100644 index 9808c70a50f29cf29980b762983e5dfc1399843b..0000000000000000000000000000000000000000 --- a/src/SignalR/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "clients/cpp/test/gtest/googletest"] - path = clients/cpp/test/gtest/googletest - url = https://github.com/google/googletest diff --git a/src/SignalR/clients/cpp/.gitignore b/src/SignalR/clients/cpp/.gitignore deleted file mode 100644 index 92f623a179d40dcc3a10e3e701bba76ca4839808..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -packages/ -Debug/ -Release/ \ No newline at end of file diff --git a/src/SignalR/clients/cpp/Build/Common.Build.Settings b/src/SignalR/clients/cpp/Build/Common.Build.Settings deleted file mode 100644 index 1e8d9932b014cd876b93dc8365f7fa8b818562e6..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/Build/Common.Build.Settings +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildThisFileDirectory)Version.props" /> - <PropertyGroup> - <SolutionDir Condition="$(SolutionDir) == '' Or '$(SolutionDir)' == '*Undefined*'">$(MSBuildThisFileDirectory)..\</SolutionDir> - <Configuration Condition="'$(Configuration)'==''">Debug</Configuration> - <Platform Condition="'$(Platform)'==''">Win32</Platform> - <PlatformToolset Condition=" '$(PlatformToolset)' == '' And '$(VisualStudioVersion)' == '12.0'">v120</PlatformToolset> - <PlatformToolset Condition=" '$(PlatformToolset)' == '' And '$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset> - <PlatformToolset Condition=" '$(PlatformToolset)' == ''">v140</PlatformToolset> - <SubSystem Condition="'$(SubSystem)' != 'UWP'">Desktop</SubSystem> - <OutDir Condition="'$(OutDir)' == ''">$(SolutionDir)bin\$(SubSystem)\$(Platform)\$(Configuration)\</OutDir> - <SignalrClientTargetName>signalrclient</SignalrClientTargetName> - <DefaultLanguage>en-US</DefaultLanguage> - </PropertyGroup> -</Project> diff --git a/src/SignalR/clients/cpp/Build/Common.tasks b/src/SignalR/clients/cpp/Build/Common.tasks deleted file mode 100644 index 8c3db65aa9e1b9b243db7006462029bcbb80df81..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/Build/Common.tasks +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - - <UsingTask TaskName="ExecAsync" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll"> - <ParameterGroup> - <Executable ParameterType="System.String" Required="true" /> - <Arguments ParameterType="System.String" Required="false" /> - </ParameterGroup> - <Task> - <Using Namespace="System.IO" /> - <Using Namespace="System.Diagnostics" /> - <Code Type="Fragment" Language="cs"> - <![CDATA[ - Log.LogMessage("Executable {0}...", Executable); - var name = System.IO.Path.GetFileNameWithoutExtension(Executable); - Log.LogMessage("Starting {0}...", name); - var processStartInfo = new ProcessStartInfo(Executable, Arguments) { UseShellExecute = true }; - Process.Start(processStartInfo); - Log.LogMessage("Finished starting process {0}.", name); - ]]> - </Code> - </Task> - </UsingTask> - - <UsingTask TaskName="Sleep" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll"> - <ParameterGroup> - <TimeoutMs ParameterType="System.Int32" Required="true" /> - </ParameterGroup> - <Task> - <Code Type="Fragment" Language="cs"> - <![CDATA[System.Threading.Thread.Sleep(TimeoutMs);]]> - </Code> - </Task> - </UsingTask> - - <UsingTask TaskName="ZipDir" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll"> - <ParameterGroup> - <InputDir ParameterType="System.String" Required="true" /> - <OutputFileName ParameterType="System.String" Required="true" /> - <IncludeBaseDir ParameterType="System.Boolean" Required="false" /> - </ParameterGroup> - <Task> - <Reference Include="System.IO.Compression.FileSystem" /> - <Using Namespace="System.IO.Compression" /> - <Code Type="Fragment" Language="cs"> - <![CDATA[ ZipFile.CreateFromDirectory(InputDir, OutputFileName, CompressionLevel.Optimal, IncludeBaseDir); ]]> - </Code> - </Task> - </UsingTask> - - <UsingTask TaskName="RegexReplaceInFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll"> - <ParameterGroup> - <InputFilename ParameterType="System.String" Required="true" /> - <OutputFilename ParameterType="System.String" Required="true" /> - <Pattern ParameterType="System.String" Required="true" /> - <Replacement ParameterType="System.String" Required="true" /> - </ParameterGroup> - <Task> - <Using Namespace="System.IO" /> - <Using Namespace="System.Linq" /> - <Using Namespace="System.Text.RegularExpressions" /> - <Code Type="Fragment" Language="cs"> - <![CDATA[ - string contents; - using (var input = new StreamReader(InputFilename)) - { - contents = input.ReadToEnd(); - } - - contents = new Regex(Pattern, RegexOptions.Compiled | RegexOptions.Multiline) - .Replace(contents, Replacement); - - using (var output = new StreamWriter(OutputFilename)) - { - output.Write(contents); - } - ]]> - </Code> - </Task> - </UsingTask> - -</Project> diff --git a/src/SignalR/clients/cpp/Build/Config.Definitions.Props b/src/SignalR/clients/cpp/Build/Config.Definitions.Props deleted file mode 100644 index 07e90f692c5ad4416efea87f0d1941baf6b55bb4..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/Build/Config.Definitions.Props +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> -</Project> diff --git a/src/SignalR/clients/cpp/Build/SignalRClient.Build.Settings b/src/SignalR/clients/cpp/Build/SignalRClient.Build.Settings deleted file mode 100644 index 33e61e1fa2b902f9d2f6654bf6d8f9b7767a4ed4..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/Build/SignalRClient.Build.Settings +++ /dev/null @@ -1,91 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildThisFileDirectory)\Common.Build.Settings" /> - <PropertyGroup> - <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe> - <RestorePackages>true</RestorePackages> - <CharacterSet>Unicode</CharacterSet> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)' == 'Debug'"> - <UseDebugLibraries>true</UseDebugLibraries> - <WholeProgramOptimization>false</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)' == 'Release'"> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - </PropertyGroup> - <PropertyGroup Condition="'$(SubSystem)' == 'UWP'"> - <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> - <AppContainerApplication>true</AppContainerApplication> - <ApplicationType>Windows Store</ApplicationType> - <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> - <WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion> - <ApplicationTypeRevision>10.0</ApplicationTypeRevision> - <GenerateProjectSpecificOutputFolder>False</GenerateProjectSpecificOutputFolder> - </PropertyGroup> - <ItemDefinitionGroup> - <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <WarningLevel>Level4</WarningLevel> - <TreatWarningAsError Condition="'$(TreatWarningsAsErrors)' != ''">true</TreatWarningAsError> - <SDLCheck>true</SDLCheck> - <StringPooling>true</StringPooling> - <CompileAsWinRT Condition="'$(SubSystem)' == 'UWP'">true</CompileAsWinRT> - </ClCompile> - <Link> - <SubSystem Condition="'$(SubSystem)' != 'UWP'">Windows</SubSystem> - <SubSystem Condition="'$(SubSystem)' == 'UWP'">Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <ProgramDatabaseFile>$(OutDir)$(TargetName).pdb</ProgramDatabaseFile> - <StripPrivateSymbols>$(OutDir)$(TargetName).pub.pdb</StripPrivateSymbols> - <OptimizeReferences>true</OptimizeReferences> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <Profile>true</Profile> - </Link> - </ItemDefinitionGroup> - - <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'"> - <ClCompile> - <Optimization>Disabled</Optimization> - </ClCompile> - </ItemDefinitionGroup> - - <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> - <ClCompile> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - </ClCompile> - </ItemDefinitionGroup> - - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PreprocessorDefinitions>WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemDefinitionGroup> - - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PreprocessorDefinitions>_WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - </ItemDefinitionGroup> - - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PreprocessorDefinitions>_WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> -</Project> diff --git a/src/SignalR/clients/cpp/Build/Version.props b/src/SignalR/clients/cpp/Build/Version.props deleted file mode 100644 index 07905402d89531f97e07bf78d58404380b5b31d7..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/Build/Version.props +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup> - <!-- When changing version remember to update version in $src\signalrclient\constants.h --> - <SignalRClientCppVersionMajor>1</SignalRClientCppVersionMajor> - <SignalRClientCppVersionMinor>0</SignalRClientCppVersionMinor> - <SignalRClientCppVersionPatch>0</SignalRClientCppVersionPatch> - <SignalRClientCppVersionSuffix>-alpha0</SignalRClientCppVersionSuffix> - <!-- $(build_number) generated by Team City --> - <SignalRClientCppVersionSuffix Condition="'$(build_number)' != '' And '$(build_branch)' != 'release'">$(SignalRClientCppVersionSuffix)-$(build_number)</SignalRClientCppVersionSuffix> - <SignalRClientCppVersionString>$(SignalRClientCppVersionMajor).$(SignalRClientCppVersionMinor).$(SignalRClientCppVersionPatch)$(SignalRClientCppVersionSuffix)</SignalRClientCppVersionString> - </PropertyGroup> -</Project> diff --git a/src/SignalR/clients/cpp/Build/build.msbuild b/src/SignalR/clients/cpp/Build/build.msbuild deleted file mode 100644 index 0d28100087d17263d6efa205ddff86c73d75e24a..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/Build/build.msbuild +++ /dev/null @@ -1,148 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" DefaultTargets="Test" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildThisFileDirectory)\Common.tasks" /> - <Import Project="$(MSBuildThisFileDirectory)\Common.Build.Settings" /> - - <ItemGroup> - <Projects Include="$(SolutionDir)src\signalrclientdll\Build\VS\signalrclientdll.vcxproj" /> - </ItemGroup> - - <ItemGroup> - <TestProjects Include="$(SolutionDir)src\signalrclient\Build\VS\signalrclient.vcxproj" /> - <TestProjects Include="$(SolutionDir)test\signalrclienttests\Build\VS\signalrclienttests.vcxproj" /> - <TestProjects Include="$(SolutionDir)test\signalrclient-e2e-tests\Build\VS\signalrclient-e2e-tests.vcxproj" /> - </ItemGroup> - - <ItemGroup> - <!-- TestHost is an ASP.NET app, will replace with a ASP.NET Core app --> - <!-- <ManagedProjects Include="$(SolutionDir)test\signalrclient-testhost\signalrclient-testhost.csproj" /> --> - <!-- - <ManagedProjects Include="$(SolutionDir)\samples\SignalRServer\SignalRServer.csproj" /> - --> - </ItemGroup> - - <ItemGroup> - <!-- - <SampleProjects Include="$(SolutionDir)\samples\PersistentConnectionSample\PersistentConnectionSample.vcxproj" /> - <SampleProjects Include="$(SolutionDir)\samples\HubConnectionSample\HubConnectionSample.vcxproj" /> - --> - </ItemGroup> - - <Import Project="$(SolutionDir)\.nuget\nuget.targets" /> - - <Target Name="Build"> - <MSBuild Targets="RestorePackages" Projects="@(Projects)" /> - <MSBuild Targets="RestorePackages" Projects="@(SampleProjects)" /> - <MSBuild Targets="RestorePackages" Projects="@(ManagedProjects)" /> - - <MSBuild Targets="$(BuildTargets)" - Projects="@(Projects)" - Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)" /> - - <MSBuild Targets="$(BuildTargets)" - Projects="@(TestProjects)" - Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'"/> - - <MSBuild Targets="$(BuildTargets)" - Projects="@(SampleProjects)" - Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'"/> - - <MSBuild Targets="$(BuildTargets)" - Projects="@(ManagedProjects)" - Properties="Configuration=$(Configuration)" Condition="'$(SubSystem)' == 'Desktop'"/> - </Target> - - <Target Name="Clean"> - <MSBuild Targets="Clean" - Projects="@(Projects)" /> - <MSBuild Targets="Clean" - Projects="@(TestProjects)" /> - <MSBuild Targets="Clean" - Projects="@(SampleProjects)" /> - <MSBuild Targets="Clean" - Projects="@(ManagedProjects)" /> - </Target> - - <Target Name="Rebuild"> - <MSBuild Targets="Clean;Build" - Projects="$(MSBuildProjectFile)" - Properties="BuildTargets=Rebuild;Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)"/> - </Target> - - <Target Name="Test" DependsOnTargets="Build" Condition="'$(SubSystem)' == 'Desktop'"> - <Exec Command="$(OutDir)\signalrclienttests.exe --gtest_output=xml:$(OutDir)test_results.xml" /> - <ExecAsync Executable="$(SolutionDir)test\signalrclient-testhost\bin\$(Configuration)\signalrclient-testhost.exe" Arguments="60000" /> - <!-- give the host some time to open the port otherwise the first tests may fail on slow machines--> - <Sleep TimeoutMs="3000" /> - <Exec Command="$(OutDir)\signalrclient-e2e-tests.exe --gtest_output=xml:$(OutDir)e2e_test_results.xml" /> - <Exec Command="taskkill /IM signalrclient-testhost.exe /F" ContinueOnError="true" /> - </Target> - - <Import Project="Config.Definitions.Props" /> - - <Target Name="CreatePackage"> - <PropertyGroup> - <PlatformToolset Condition="'$(PlatformToolset)' == ''">v140</PlatformToolset> - <SubSystem Condition="'$(SubSystem)' != 'UWP'">Desktop</SubSystem> - <PackageSource>$(SolutionDir)bin\Package\$(SubSystem)\$(PlatformToolset)\</PackageSource> - <PackageSourceNative>$(PackageSource)build\native\</PackageSourceNative> - <NuGetArtifactsPath>$(MSBuildThisFileDirectory)..\NuGet\</NuGetArtifactsPath> - <NuSpecTemplatePath>$(NuGetArtifactsPath)signalrclientcpp.nuspec.template</NuSpecTemplatePath> - <PackageOutputDir>$(SolutionDir)artifacts\build</PackageOutputDir> - <PrivateSymbols>$(SolutionDir)bin\Symbols\$(SubSystem)\$(PlatformToolset)\</PrivateSymbols> - </PropertyGroup> - - <Error Text="UWP not supported with v120 toolset" Condition="'$(SubSystem)' == 'UWP' And '$(PlatformToolset)' != 'v140'" /> - - <ItemGroup> - <Include Include="$(SolutionDir)include\**\*.*" /> - </ItemGroup> - <Copy SourceFiles="@(Include)" DestinationFolder="$(PackageSourceNative)include\%(RecursiveDir)" /> - <MakeDir Directories="$(PackageSource)" /> - - <RegexReplaceInFile InputFileName="$(NuSpecTemplatePath)" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#Toolset#" Replacement="$(PlatformToolset)" /> - <RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#casablanca-subsystem#" Replacement="windesktop" Condition="'$(SubSystem)' == 'Desktop'" /> - <RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#SubSystem#" Replacement="WinDesktop" Condition="'$(SubSystem)' == 'Desktop'" /> - <RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#casablanca-subsystem#" Replacement="winapp" Condition="'$(SubSystem)' == 'UWP'" /> - <RegexReplaceInFile InputFileName="$(PackageSource)signalrclientcpp.nuspec" OutputFileName="$(PackageSource)signalrclientcpp.nuspec" Pattern="#SubSystem#" Replacement="UWP" Condition="'$(SubSystem)' == 'UWP'" /> - - <RegexReplaceInFile InputFileName="$(NuGetArtifactsPath)\Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template" - OutputFileName="$(PackageSourceNative)Microsoft.AspNet.SignalR.Client.Cpp.$(PlatformToolset).WinDesktop.targets" Pattern="#Toolset#" Replacement="$(PlatformToolset)" Condition="'$(SubSystem)' == 'Desktop'" /> - <RegexReplaceInFile InputFileName="$(NuGetArtifactsPath)\Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template" - OutputFileName="$(PackageSourceNative)Microsoft.AspNet.SignalR.Client.Cpp.$(PlatformToolset).UWP.targets" Pattern="#Toolset#" Replacement="$(PlatformToolset)" Condition="'$(SubSystem)' == 'UWP'" /> - - <MSBuild Targets="RestorePackages" Projects="@(Projects)" /> - - <MSBuild Targets="BuildForNuget" - Projects="$(MSBuildThisFile)" Properties="PackageSourceNative=$(PackageSourceNative);PrivateSymbols=$(PrivateSymbols);Configuration=%(ProjectConfiguration.Configuration);Platform=%(ProjectConfiguration.Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem);SignalrClientTargetName=$(SignalrClientTargetName)" /> - - <MakeDir Directories="$(PackageOutputDir)" /> - <Exec Command="$(NuGetCommand) pack $(PackageSource)signalrclientcpp.nuspec -BasePath $(PackageSource) -OutputDirectory $(PackageOutputDir) -Version $(SignalRClientCppVersionString)" LogStandardErrorAsError="true" /> - - <ZipDir InputDir="$(PrivateSymbols)" OutputFileName="$(PackageOutputDir)\Symbols_$(PlatformToolset)_$(SubSystem).zip" IncludeBaseDir="false"/> - </Target> - - <Target Name="BuildForNuget"> - <MSBuild Targets="$(BuildTargets)" - Projects="@(Projects)" - Properties="Configuration=$(Configuration);Platform=$(Platform);PlatformToolset=$(PlatformToolset);SubSystem=$(SubSystem)" /> - - <Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).lib" DestinationFolder="$(PackageSourceNative)lib\$(Platform)\$(PlatformToolset)\$(Configuration)" /> - - <Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).dll" DestinationFolder="$(PackageSourceNative)dll\$(Platform)\$(PlatformToolset)\$(Configuration)" /> - <Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).pub.pdb" DestinationFiles="$(PackageSourceNative)dll\$(Platform)\$(PlatformToolset)\$(Configuration)\$(SignalrClientTargetName).pdb" /> - <Copy SourceFiles="$(OutDir)dll\$(SignalrClientTargetName).pdb" DestinationFiles="$(PrivateSymbols)$(Platform)\$(PlatformToolset)\$(Configuration)\$(SignalrClientTargetName).pdb" /> - </Target> - - <Target Name="NuGetPush"> - <PropertyGroup> - <NuGetExePath Condition="'$(NuGetExePath)' == ''">$(PUSH_NUGET_EXE)</NuGetExePath> - <NuGetExePath Condition="'$(NuGetExePath)' == ''">$(MSBuildThisFileDirectory)..\.nuget\NuGet.exe</NuGetExePath> - </PropertyGroup> - <ItemGroup> - <Package Include="$(SolutionDir)artifacts\build\*.nupkg" /> - <Package Include="$(SolutionDir)artifacts\build\*.symbols.nupkg" /> - </ItemGroup> - <Exec Command="$(NuGetExePath) push -nosymbols %(Package.Identity) -Source $(NUGET_PUBLISH_FEED) -ApiKey $(APIKEY)" /> - </Target> -</Project> diff --git a/src/SignalR/clients/cpp/CMakeLists.txt b/src/SignalR/clients/cpp/CMakeLists.txt deleted file mode 100644 index 0d78e1cf8ae90378a3c71d49bd0a56f68445a519..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -cmake_minimum_required (VERSION 2.8.11) -project (signalrclient) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -L -lcpprest") - -set(CPPREST_INCLUDE_DIR "" CACHE FILEPATH "Path to casablanca include dir") - -include_directories ( -include -"${CPPREST_INCLUDE_DIR}") - -find_library(CPPREST_SO NAMES "cpprest" PATHS ${CPPREST_LIB_DIR} REQUIRED) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) - -add_subdirectory(src/signalrclient) -add_subdirectory(test) diff --git a/src/SignalR/clients/cpp/CONTRIBUTING.md b/src/SignalR/clients/cpp/CONTRIBUTING.md deleted file mode 100644 index 64ff041d5caf65de66e8e966129f689e5919fb64..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/CONTRIBUTING.md +++ /dev/null @@ -1,4 +0,0 @@ -Contributing -====== - -Information on contributing to this repo is in the [Contributing Guide](https://github.com/aspnet/Home/blob/dev/CONTRIBUTING.md) in the Home repo. diff --git a/src/SignalR/clients/cpp/NuGet.config b/src/SignalR/clients/cpp/NuGet.config deleted file mode 100644 index 0cbd4452e047ef13a78391ac130cefcaca60d64b..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/NuGet.config +++ /dev/null @@ -1,7 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<configuration> - <packageSources> - <clear /> - <add key="nuget" value="https://api.nuget.org/v3/index.json" /> - </packageSources> -</configuration> diff --git a/src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template b/src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template deleted file mode 100644 index 7086ee6059368d24310d168befe3c69b0cf05b10..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.UWP.targets.template +++ /dev/null @@ -1,69 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="signalrclient_uwp_inittarget"> - - <PropertyGroup Condition="'$(PlatformToolset)' != 'v140' Or '$(ApplicationType)' != 'Windows Store'"> - <DisableUwp>True</DisableUwp> - </PropertyGroup> - - <ItemDefinitionGroup Condition="'$(DisableUwp)' == ''"> - <ClCompile> - <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <ResourceCompile> - <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ResourceCompile> - </ItemDefinitionGroup> - - <ItemDefinitionGroup Label="x64 and #Toolset# and Release" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1"> - <Link> - <AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Label="x64 and #Toolset# and Debug" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1"> - <Link> - <AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Label="Win32 and #Toolset# and Release" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1"> - <Link> - <AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Label="Win32 and #Toolset# and Debug" Condition="'$(DisableUwp)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1"> - <Link> - <AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - - <Target Name="signalrclient_uwp_AfterBuild" AfterTargets="AfterBuild" Condition="'$(DisableUwp)' == ''"> - <PropertyGroup> - <UseHardlinksIfPossible Condition="'$(UseHardlinksIfPossible)' == ''">true</UseHardlinksIfPossible> - </PropertyGroup> - - <Copy DestinationFolder="$(TargetDir)" SourceFiles="@(CopyToOutput)" SkipUnchangedFiles="true" UseHardlinksIfPossible="$(UseHardlinksIfPossible)"> - <Output TaskParameter="DestinationFiles" PropertyName="DestinationFiles" /> - <Output TaskParameter="DestinationFiles" ItemName="DestinationFiles" /> - <Output TaskParameter="CopiedFiles" PropertyName="CopiedFiles" /> - <Output TaskParameter="CopiedFiles" ItemName="CopiedFiles" /> - </Copy> - </Target> - - <Target Name="signalrclient_uwp_inittarget" Condition="'$(DisableUwp)' == ''"> - <ItemGroup Label="x64 and #Toolset# and Debug" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1"> - <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll" /> - <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.pdb" /> - </ItemGroup> - <ItemGroup Label="x64 and #Toolset# and Release" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1"> - <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll" /> - <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.pdb" /> - </ItemGroup> - <ItemGroup Label="Win32 and #Toolset# and Debug" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1"> - <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll" /> - <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.pdb" /> - </ItemGroup> - <ItemGroup Label="Win32 and #Toolset# and Release" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1"> - <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll" /> - <ReferenceCopyLocalPaths Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.pdb" /> - </ItemGroup> - </Target> -</Project> diff --git a/src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template b/src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template deleted file mode 100644 index 659651b0c4c0b45a9a15be7240d071294f56829d..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/NuGet/Microsoft.AspNet.SignalR.Client.Cpp.WinDesktop.targets.template +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" InitialTargets="signalrclient_inittarget"> - - <PropertyGroup Condition="'$(ApplicationType)' != ''"> - <DisableDesktop>True</DisableDesktop> - </PropertyGroup> - - - <ItemDefinitionGroup Condition="'$(DisableDesktop)' == ''"> - <ClCompile> - <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <ResourceCompile> - <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ResourceCompile> - </ItemDefinitionGroup> - - <ItemDefinitionGroup Label="x64 and #Toolset# and Release" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1"> - <Link> - <AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Label="x64 and #Toolset# and Debug" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1"> - <Link> - <AdditionalDependencies>$(MSBuildThisFileDirectory)lib\x64\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Label="Win32 and #Toolset# and Release" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1"> - <Link> - <AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Release\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Label="Win32 and #Toolset# and Debug" Condition="'$(DisableDesktop)' == '' And '$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1"> - <Link> - <AdditionalDependencies>$(MSBuildThisFileDirectory)lib\Win32\#Toolset#\Debug\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - - <Target Name="signalrclient_AfterBuild" AfterTargets="AfterBuild" Condition="'$(DisableDesktop)' == ''"> - <PropertyGroup> - <UseHardlinksIfPossible Condition="'$(UseHardlinksIfPossible)' == ''">true</UseHardlinksIfPossible> - </PropertyGroup> - - <Copy DestinationFolder="$(TargetDir)" SourceFiles="@(CopyToOutput)" SkipUnchangedFiles="true" UseHardlinksIfPossible="$(UseHardlinksIfPossible)"> - <Output TaskParameter="DestinationFiles" PropertyName="DestinationFiles" /> - <Output TaskParameter="DestinationFiles" ItemName="DestinationFiles" /> - <Output TaskParameter="CopiedFiles" PropertyName="CopiedFiles" /> - <Output TaskParameter="CopiedFiles" ItemName="CopiedFiles" /> - </Copy> - </Target> - - <Target Name="signalrclient_inittarget" Condition="'$(DisableDesktop)' == ''"> - <ItemGroup Label="x64 and #Toolset# and Debug" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1"> - <CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll" /> - <CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.pdb" /> - <None Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Debug\signalrclient.dll"> - <DeploymentContent>true</DeploymentContent> - </None> - </ItemGroup> - <ItemGroup Label="x64 and #Toolset# and Release" Condition="'$(Platform)' == 'x64' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1"> - <CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll" /> - <CopyToOutput Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.pdb" /> - <None Include="$(MSBuildThisFileDirectory)dll\x64\#Toolset#\Release\signalrclient.dll"> - <DeploymentContent>true</DeploymentContent> - </None> - </ItemGroup> - <ItemGroup Label="Win32 and #Toolset# and Debug" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) > -1"> - <CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll" /> - <CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.pdb" /> - <None Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Debug\signalrclient.dll"> - <DeploymentContent>true</DeploymentContent> - </None> - </ItemGroup> - <ItemGroup Label="Win32 and #Toolset# and Release" Condition="'$(Platform)' == 'Win32' And '$(PlatformToolset)' == '#Toolset#' And $(Configuration.ToLower().IndexOf('debug')) == -1"> - <CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll" /> - <CopyToOutput Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.pdb" /> - <None Include="$(MSBuildThisFileDirectory)dll\Win32\#Toolset#\Release\signalrclient.dll"> - <DeploymentContent>true</DeploymentContent> - </None> - </ItemGroup> - </Target> -</Project> diff --git a/src/SignalR/clients/cpp/NuGet/signalrclientcpp.nuspec.template b/src/SignalR/clients/cpp/NuGet/signalrclientcpp.nuspec.template deleted file mode 100644 index 544a4f4f04f9f94094c19e91d4b04a2f5e541ba2..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/NuGet/signalrclientcpp.nuspec.template +++ /dev/null @@ -1,21 +0,0 @@ -<?xml version="1.0"?> -<package> - <metadata> - <id>Microsoft.AspNet.SignalR.Client.Cpp.#Toolset#.#SubSystem#</id> - <title>Microsoft ASP.NET SignalR C++ Client</title> - <version>0.0.0</version> - <authors>Microsoft</authors> - <owners>Microsoft</owners> - <licenseUrl>http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm</licenseUrl> - <copyright>© Microsoft Corporation. All rights reserved.</copyright> - <projectUrl>http://www.asp.net/signalr</projectUrl> - <requireLicenseAcceptance>true</requireLicenseAcceptance> - <description>C++ client for ASP.NET SignalR.</description> - <language>en-US</language> - <tags>Microsoft AspNet SignalR AspNetSignalR Client C++ native</tags> - <releaseNotes>https://github.com/aspnet/SignalR-Client-Cpp/releases</releaseNotes> - <dependencies> - <dependency id="cpprestsdk.#Toolset#.#casablanca-subsystem#.msvcstl.dyn.rt-dyn" version="2.9.1" /> - </dependencies> - </metadata> -</package> diff --git a/src/SignalR/clients/cpp/README.md b/src/SignalR/clients/cpp/README.md deleted file mode 100644 index a9f17e5626120e6359d7ba85b00a096fe590f78f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/README.md +++ /dev/null @@ -1,6 +0,0 @@ -ASP.NET Core SignalR C++ Client -======== - -This folder contains a C++ client for ASP.NET Core SignalR. - -**There are no plans to ship this client at this time.** \ No newline at end of file diff --git a/src/SignalR/clients/cpp/build.cmd b/src/SignalR/clients/cpp/build.cmd deleted file mode 100644 index 852b65ceb08086c2ece94690a23eddd82de4b98d..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/build.cmd +++ /dev/null @@ -1 +0,0 @@ -msbuild "%~dp0\Build\build.msbuild" /v:minimal /maxcpucount /nodeReuse:false %* diff --git a/src/SignalR/clients/cpp/include/signalrclient/_exports.h b/src/SignalR/clients/cpp/include/signalrclient/_exports.h deleted file mode 100644 index c9e9fadbfa258a2bdc82fd8f32afb0b1872fb1d3..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/_exports.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#ifdef NO_SIGNALRCLIENT_EXPORTS -#define SIGNALRCLIENT_API -#else -#ifdef SIGNALRCLIENT_EXPORTS -#define SIGNALRCLIENT_API __declspec(dllexport) -#else -#define SIGNALRCLIENT_API __declspec(dllimport) -#endif // SIGNALRCLIENT_EXPORTS -#endif // NO_SIGNALRCLIENT_EXPORTS \ No newline at end of file diff --git a/src/SignalR/clients/cpp/include/signalrclient/connection.h b/src/SignalR/clients/cpp/include/signalrclient/connection.h deleted file mode 100644 index b3af11d09f79efe37e8724279c79d682fef85e7a..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/connection.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "_exports.h" -#include <memory> -#include <functional> -#include "connection_state.h" -#include "trace_level.h" -#include "log_writer.h" -#include "signalr_client_config.h" - -namespace signalr -{ - class connection_impl; - - class connection - { - public: - typedef std::function<void __cdecl(const std::string&)> message_received_handler; - - SIGNALRCLIENT_API explicit connection(const std::string& url, trace_level trace_level = trace_level::all, std::shared_ptr<log_writer> log_writer = nullptr); - - SIGNALRCLIENT_API ~connection(); - - connection(const connection&) = delete; - - connection& operator=(const connection&) = delete; - - SIGNALRCLIENT_API void __cdecl start(std::function<void(std::exception_ptr)> callback) noexcept; - - SIGNALRCLIENT_API void __cdecl send(const std::string& data, std::function<void(std::exception_ptr)> callback) noexcept; - - SIGNALRCLIENT_API void __cdecl set_message_received(const message_received_handler& message_received_callback); - SIGNALRCLIENT_API void __cdecl set_disconnected(const std::function<void __cdecl()>& disconnected_callback); - - SIGNALRCLIENT_API void __cdecl set_client_config(const signalr_client_config& config); - - SIGNALRCLIENT_API void __cdecl stop(std::function<void(std::exception_ptr)> callback) noexcept; - - SIGNALRCLIENT_API connection_state __cdecl get_connection_state() const noexcept; - SIGNALRCLIENT_API std::string __cdecl get_connection_id() const; - - private: - // The recommended smart pointer to use when doing pImpl is the `std::unique_ptr`. However - // we are capturing the m_pImpl instance in the lambdas used by tasks which can outlive - // the connection instance. Using `std::shared_ptr` guarantees that we won't be using - // a deleted object if the task is run after the `connection` instance goes away. - std::shared_ptr<connection_impl> m_pImpl; - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/connection_state.h b/src/SignalR/clients/cpp/include/signalrclient/connection_state.h deleted file mode 100644 index ff01f5d399172b9ab8d6b67df44b544a2f1bc527..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/connection_state.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -namespace signalr -{ - enum class connection_state - { - connecting, - connected, - disconnecting, - disconnected - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/http_client.h b/src/SignalR/clients/cpp/include/signalrclient/http_client.h deleted file mode 100644 index 3b3b9b390afda794af78a1107487147a00071aeb..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/http_client.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <string> -#include <functional> -#include <map> -#include <chrono> - -namespace signalr -{ - enum class http_method - { - GET, - POST - }; - - class http_request - { - public: - http_method method; - std::map<std::string, std::string> headers; - std::string content; - std::chrono::seconds timeout; - }; - - class http_response - { - public: - http_response() {} - http_response(http_response&& rhs) noexcept : status_code(rhs.status_code), content(std::move(rhs.content)) {} - http_response(int code, const std::string& content) : status_code(code), content(content) {} - - http_response& operator=(http_response&& rhs) - { - status_code = rhs.status_code; - content = std::move(rhs.content); - - return *this; - } - - int status_code = 0; - std::string content; - }; - - class http_client - { - public: - virtual void send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback) = 0; - - virtual ~http_client() {} - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/hub_connection.h b/src/SignalR/clients/cpp/include/signalrclient/hub_connection.h deleted file mode 100644 index 68597e5420b83671b6709bc853c8897e708ba4f2..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/hub_connection.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "_exports.h" -#include <memory> -#include <functional> -#include "cpprest/json.h" -#include "connection_state.h" -#include "trace_level.h" -#include "log_writer.h" -#include "signalr_client_config.h" - -namespace signalr -{ - class hub_connection_impl; - - class hub_connection - { - public: - typedef std::function<void __cdecl (const web::json::value&)> method_invoked_handler; - - SIGNALRCLIENT_API explicit hub_connection(const std::string& url, trace_level trace_level = trace_level::all, - std::shared_ptr<log_writer> log_writer = nullptr); - - SIGNALRCLIENT_API ~hub_connection(); - - hub_connection(const hub_connection&) = delete; - - hub_connection& operator=(const hub_connection&) = delete; - - SIGNALRCLIENT_API void __cdecl start(std::function<void(std::exception_ptr)> callback) noexcept; - SIGNALRCLIENT_API void __cdecl stop(std::function<void(std::exception_ptr)> callback) noexcept; - - SIGNALRCLIENT_API connection_state __cdecl get_connection_state() const; - SIGNALRCLIENT_API std::string __cdecl get_connection_id() const; - - SIGNALRCLIENT_API void __cdecl set_disconnected(const std::function<void __cdecl()>& disconnected_callback); - - SIGNALRCLIENT_API void __cdecl set_client_config(const signalr_client_config& config); - - SIGNALRCLIENT_API void __cdecl on(const std::string& event_name, const method_invoked_handler& handler); - - SIGNALRCLIENT_API void invoke(const std::string& method_name, const web::json::value& arguments = web::json::value::array(), std::function<void(const web::json::value&, std::exception_ptr)> callback = [](const web::json::value&, std::exception_ptr) {}) noexcept; - - SIGNALRCLIENT_API void send(const std::string& method_name, const web::json::value& arguments = web::json::value::array(), std::function<void(std::exception_ptr)> callback = [](std::exception_ptr) {}) noexcept; - - private: - std::shared_ptr<hub_connection_impl> m_pImpl; - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/hub_exception.h b/src/SignalR/clients/cpp/include/signalrclient/hub_exception.h deleted file mode 100644 index 0c653acc2a498d7281c44fe0b9c4fab0ed1f7abd..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/hub_exception.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <stdexcept> -#include "signalr_exception.h" - -namespace signalr -{ - class hub_exception : public signalr_exception - { - public: - hub_exception(const std::string &what) - : signalr_exception(what) - {} - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/log_writer.h b/src/SignalR/clients/cpp/include/signalrclient/log_writer.h deleted file mode 100644 index 89dc3815c4f105e82f4f76ef764f6cfea751fbe3..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/log_writer.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -namespace signalr -{ - class log_writer - { - public: - // NOTE: the caller does not enforce thread safety of this call - virtual void __cdecl write(const std::string &entry) = 0; - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/signalr_client_config.h b/src/SignalR/clients/cpp/include/signalrclient/signalr_client_config.h deleted file mode 100644 index c8fe6d8122783557966902b60f5f1e121b0aa498..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/signalr_client_config.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "cpprest/http_client.h" -#include "cpprest/ws_client.h" -#include "_exports.h" - -namespace signalr -{ - class signalr_client_config - { - public: - SIGNALRCLIENT_API void __cdecl set_proxy(const web::web_proxy &proxy); - // Please note that setting credentials does not work in all cases. - // For example, Basic Authentication fails under Win32. - // As a workaround, you can set the required authorization headers directly - // using signalr_client_config::set_http_headers - SIGNALRCLIENT_API void __cdecl set_credentials(const web::credentials &credentials); - - SIGNALRCLIENT_API web::http::client::http_client_config __cdecl get_http_client_config() const; - SIGNALRCLIENT_API void __cdecl set_http_client_config(const web::http::client::http_client_config& http_client_config); - - SIGNALRCLIENT_API web::websockets::client::websocket_client_config __cdecl get_websocket_client_config() const noexcept; - SIGNALRCLIENT_API void __cdecl set_websocket_client_config(const web::websockets::client::websocket_client_config& websocket_client_config); - - SIGNALRCLIENT_API web::http::http_headers __cdecl get_http_headers() const noexcept; - SIGNALRCLIENT_API void __cdecl set_http_headers(const web::http::http_headers& http_headers); - - private: - web::http::client::http_client_config m_http_client_config; - web::websockets::client::websocket_client_config m_websocket_client_config; - web::http::http_headers m_http_headers; - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/signalr_exception.h b/src/SignalR/clients/cpp/include/signalrclient/signalr_exception.h deleted file mode 100644 index e475ff4ee98276aeccd84efd95797f0ff0f101e1..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/signalr_exception.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <stdexcept> - -namespace signalr -{ - class signalr_exception : public std::runtime_error - { - public: - explicit signalr_exception(const std::string &what) - : runtime_error(what) - {} - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/trace_level.h b/src/SignalR/clients/cpp/include/signalrclient/trace_level.h deleted file mode 100644 index 928d0a28bc6bffba59740dfe166bc5a4b01d0996..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/trace_level.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -namespace signalr -{ - enum class trace_level : int - { - none = 0, - messages = 1, - events = 2, - state_changes = 4, - errors = 8, - info = 16, - all = messages | events | state_changes | errors | info - }; - - inline trace_level operator|(trace_level lhs, trace_level rhs) noexcept - { - return static_cast<trace_level>(static_cast<int>(lhs) | static_cast<int>(rhs)); - } - - inline trace_level operator&(trace_level lhs, trace_level rhs) noexcept - { - return static_cast<trace_level>(static_cast<int>(lhs) & static_cast<int>(rhs)); - } -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/transfer_format.h b/src/SignalR/clients/cpp/include/signalrclient/transfer_format.h deleted file mode 100644 index 8355d25309f1878c6457c767bf8156d375183c7e..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/transfer_format.h +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -namespace signalr -{ - enum class transfer_format - { - text, - binary - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/transport_type.h b/src/SignalR/clients/cpp/include/signalrclient/transport_type.h deleted file mode 100644 index bc30ee464602812504f6fc2f732d08ce6100f998..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/transport_type.h +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -namespace signalr -{ - enum class transport_type - { - long_polling, - websockets - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/web_exception.h b/src/SignalR/clients/cpp/include/signalrclient/web_exception.h deleted file mode 100644 index f8d4c9a520ad1c6470d77c6124857f4ae8089f9d..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/web_exception.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <stdexcept> - -namespace signalr -{ - class web_exception : public std::runtime_error - { - public: - web_exception(const std::string &what, unsigned short status_code) - : runtime_error(what), m_status_code(status_code) - {} - - unsigned short status_code() const noexcept - { - return m_status_code; - } - - private: - unsigned short m_status_code; - }; -} diff --git a/src/SignalR/clients/cpp/include/signalrclient/websocket_client.h b/src/SignalR/clients/cpp/include/signalrclient/websocket_client.h deleted file mode 100644 index b45e73995f3b9fd9c861b79b313a7c62cbdf77c4..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/include/signalrclient/websocket_client.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "transfer_format.h" - -namespace signalr -{ - class websocket_client - { - public: - virtual ~websocket_client() {}; - - virtual void start(std::string url, transfer_format format, std::function<void(std::exception_ptr)> callback) = 0; - - virtual void stop(std::function<void(std::exception_ptr)> callback) = 0; - - virtual void send(std::string payload, std::function<void(std::exception_ptr)> callback) = 0; - - virtual void receive(std::function<void(std::string, std::exception_ptr)> callback) = 0; - }; -} diff --git a/src/SignalR/clients/cpp/samples.sln b/src/SignalR/clients/cpp/samples.sln deleted file mode 100644 index b152ac18a876b52382da7cba1547891db3b85ae1..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples.sln +++ /dev/null @@ -1,63 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 16.0.0.0 -MinimumVisualStudioVersion = 16.0.0.0 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PersistentConnectionSample", "samples\PersistentConnectionSample\PersistentConnectionSample.vcxproj", "{BD075706-11E9-403B-A2E3-A5E1397E53EF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HubConnectionSample", "samples\HubConnectionSample\HubConnectionSample.vcxproj", "{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SignalRServer", "samples\SignalRServer\SignalRServer.csproj", "{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{4AA7C02A-A2E9-4E22-A026-B43D623C272F}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Win32.ActiveCfg = Debug|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Debug|Win32.Build.0 = Debug|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Any CPU.ActiveCfg = Release|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Mixed Platforms.Build.0 = Release|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Win32.ActiveCfg = Release|Win32 - {BD075706-11E9-403B-A2E3-A5E1397E53EF}.Release|Win32.Build.0 = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.ActiveCfg = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.Build.0 = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Any CPU.ActiveCfg = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.Build.0 = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.ActiveCfg = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.Build.0 = Release|Win32 - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Debug|Win32.ActiveCfg = Debug|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Any CPU.Build.0 = Release|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}.Release|Win32.ActiveCfg = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.cpp b/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.cpp deleted file mode 100644 index dba7bcc9644f14ed97451e7ebb8943b801cb6e76..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.cpp +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" - -#include <iostream> -#include <sstream> -#include "hub_connection.h" -#include "log_writer.h" -#include <future> - -class logger : public signalr::log_writer -{ - // Inherited via log_writer - virtual void __cdecl write(const std::string & entry) override - { - //std::cout << utility::conversions::to_utf8string(entry) << std::endl; - } -}; - -void send_message(signalr::hub_connection& connection, const std::string& message) -{ - web::json::value args{}; - args[0] = web::json::value(utility::conversions::to_string_t(message)); - - // if you get an internal compiler error uncomment the lambda below or install VS Update 4 - connection.invoke("Send", args, [](const web::json::value& value, std::exception_ptr exception) - { - try - { - if (exception) - { - std::rethrow_exception(exception); - } - - ucout << U("Received: ") << value.serialize() << std::endl; - } - catch (const std::exception &e) - { - ucout << U("Error while sending data: ") << e.what() << std::endl; - } - }); -} - -void chat() -{ - signalr::hub_connection connection("http://localhost:5000/default", signalr::trace_level::all, std::make_shared<logger>()); - connection.on("Send", [](const web::json::value & m) - { - ucout << std::endl << m.at(0).as_string() << /*U(" wrote:") << m.at(1).as_string() <<*/ std::endl << U("Enter your message: "); - }); - - std::promise<void> task; - connection.start([&connection, &task](std::exception_ptr exception) - { - if (exception) - { - try - { - std::rethrow_exception(exception); - } - catch (const std::exception & ex) - { - ucout << U("exception when starting connection: ") << ex.what() << std::endl; - } - task.set_value(); - return; - } - - ucout << U("Enter your message:"); - for (;;) - { - std::string message; - std::getline(std::cin, message); - - if (message == ":q") - { - break; - } - - send_message(connection, message); - } - - connection.stop([&task](std::exception_ptr exception) - { - try - { - if (exception) - { - std::rethrow_exception(exception); - } - - ucout << U("connection stopped successfully") << std::endl; - } - catch (const std::exception & e) - { - ucout << U("exception when stopping connection: ") << e.what() << std::endl; - } - - task.set_value(); - }); - }); - - task.get_future().get(); -} - -int main() -{ - chat(); - - return 0; -} diff --git a/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj b/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj deleted file mode 100644 index ae70839bc8db496e7d069f0c94e5b770d5759166..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj +++ /dev/null @@ -1,118 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="..\..\Build\SignalRClient.Build.Settings" /> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>HubConnectionSample</RootNamespace> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> - <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe> - <RestorePackages>true</RestorePackages> - <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - <Import Project="..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\include\signalrclient;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <AdditionalLibraryDirectories> - </AdditionalLibraryDirectories> - <AdditionalDependencies>$(MSBuildThisFileDirectory)..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\lib\native\v140\windesktop\msvcstl\dyn\rt-dyn\x86\Debug\cpprest140d_2_9.lib;$(MSBuildThisFileDirectory)..\..\bin\Desktop\Win32\Debug\dll\signalrclient.lib;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader>Use</PrecompiledHeader> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - <AdditionalIncludeDirectories>..\..\include\signalrclient;$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="stdafx.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="HubConnectionSample.cpp" /> - <ClCompile Include="stdafx.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\..\src\signalrclient\Build\VS\signalrclient.vcxproj"> - <Project>{87ed3ad4-d820-48cd-8382-a12564213a12}</Project> - </ProjectReference> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> - <PropertyGroup> - <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> - </PropertyGroup> - <Error Condition="!Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.9.1\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" /> - </Target> - <Target Name="AfterBuild"> - <Exec Command="copy /y "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\dll\$(SignalrClientTargetName).dll" "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\$(SignalrClientTargetName).dll"" /> - <Exec Command="copy /y "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\dll\$(SignalrClientTargetName).pdb" "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\$(SignalrClientTargetName).pdb"" /> - </Target> -</Project> diff --git a/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj.filters b/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj.filters deleted file mode 100644 index 2d23e3b4616a8a41d1bf5d9a8ff8732a10605d5b..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/HubConnectionSample/HubConnectionSample.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="stdafx.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="stdafx.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="HubConnectionSample.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/HubConnectionSample/packages.config b/src/SignalR/clients/cpp/samples/HubConnectionSample/packages.config deleted file mode 100644 index 54b8976318d09e7565066d2966279d96a22ec171..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/HubConnectionSample/packages.config +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<packages> - <package id="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" version="2.9.1" targetFramework="native" /> -</packages> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.cpp b/src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.cpp deleted file mode 100644 index 4ddb0135bdeb0f9ea0d9e7b7d1a3747d4e0925c5..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.h b/src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.h deleted file mode 100644 index b9c15ddfa26eef340cb110bf8cac4a1a50774b2f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/HubConnectionSample/stdafx.h +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once diff --git a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.cpp b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.cpp deleted file mode 100644 index 323890a80d04741872038f0a7945392598bfcd08..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "signalrclient\connection.h" -#include <iostream> - -void send_message(signalr::connection &connection, const utility::string_t& message) -{ - connection.send(message) - .then([](pplx::task<void> send_task) // fire and forget but we need to observe exceptions - { - try - { - send_task.get(); - } - catch (const std::exception &e) - { - ucout << U("Error while sending data: ") << e.what(); - } - }); -} - -int main() -{ - signalr::connection connection{ U("http://localhost:34281/echo") }; - connection.set_message_received([](const utility::string_t& m) - { - ucout << U("Message received:") << m << std::endl << U("Enter message: "); - }); - - connection.start() - .then([&connection]() // fine to capture by reference - we are blocking so it is guaranteed to be valid - { - for (;;) - { - utility::string_t message; - std::getline(ucin, message); - - if (message == U(":q")) - { - break; - } - - send_message(connection, message); - } - - return connection.stop(); - }) - .then([](pplx::task<void> stop_task) - { - try - { - stop_task.get(); - ucout << U("connection stopped successfully") << std::endl; - } - catch (const std::exception &e) - { - ucout << U("exception when starting or closing connection: ") << e.what() << std::endl; - } - }).get(); - - return 0; -} diff --git a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj deleted file mode 100644 index 06064783a4a3f6ee39002a057bae27d81cc5c2e6..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj +++ /dev/null @@ -1,109 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - </ItemGroup> - <PropertyGroup Label="Globals"> - <ProjectGuid>{BD075706-11E9-403B-A2E3-A5E1397E53EF}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>PersistentConnectionSample</RootNamespace> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> - <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe> - <RestorePackages>true</RestorePackages> - <WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>Use</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <WarningLevel>Level3</WarningLevel> - <PrecompiledHeader>Use</PrecompiledHeader> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <SDLCheck>true</SDLCheck> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="stdafx.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="PersistentConnectionSample.cpp" /> - <ClCompile Include="stdafx.cpp"> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> - <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> - <Import Project="..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" /> - <Import Project="..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets" Condition="Exists('..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets')" /> - </ImportGroup> - <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> - <PropertyGroup> - <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> - </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" /> - <Error Condition="!Exists('..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.2.7.0\build\native\cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" /> - <Error Condition="!Exists('..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.1.0.0-beta1\build\native\Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop.targets'))" /> - </Target> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj.filters b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj.filters deleted file mode 100644 index f04ee37ebfd64f7c549e36eafc230ef1e7d8120f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/PersistentConnectionSample.vcxproj.filters +++ /dev/null @@ -1,33 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="stdafx.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="stdafx.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="PersistentConnectionSample.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <None Include="packages.config" /> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/packages.config b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/packages.config deleted file mode 100644 index b2d64c805a3525aa0e6bf335e0b7a543a001c858..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/packages.config +++ /dev/null @@ -1,5 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<packages> - <package id="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" version="2.7.0" targetFramework="native" /> - <package id="Microsoft.AspNet.SignalR.Client.Cpp.v140.WinDesktop" version="1.0.0-beta1" targetFramework="native" /> -</packages> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.cpp b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.cpp deleted file mode 100644 index bd7a85614cfe19b82fec4f1be1f0738d8a0079d0..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" diff --git a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.h b/src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.h deleted file mode 100644 index b9c15ddfa26eef340cb110bf8cac4a1a50774b2f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/PersistentConnectionSample/stdafx.h +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/ChatHub.cs b/src/SignalR/clients/cpp/samples/SignalRServer/ChatHub.cs deleted file mode 100644 index 00f626c4a10c2e309837226fb717b1b59be939ca..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/ChatHub.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using Microsoft.AspNet.SignalR; - -namespace SignalRServer -{ - public class ChatHub : Hub - { - public void Send(string name, string message) - { - // Call the broadcastMessage method to update clients. - Clients.All.broadcastMessage(name, message); - } - } -} \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/EchoConnection.cs b/src/SignalR/clients/cpp/samples/SignalRServer/EchoConnection.cs deleted file mode 100644 index 98d50fc767de55b3fc9c89c96ff01aa445f1f83a..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/EchoConnection.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Microsoft.AspNet.SignalR; - -namespace SignalRServer -{ - public class EchoConnection : PersistentConnection - { - protected override Task OnConnected(IRequest request, string connectionId) - { - return Connection.Send(connectionId, "Welcome!"); - } - - protected override Task OnReceived(IRequest request, string connectionId, string data) - { - return Connection.Broadcast(data); - } - } -} \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/Properties/AssemblyInfo.cs b/src/SignalR/clients/cpp/samples/SignalRServer/Properties/AssemblyInfo.cs deleted file mode 100644 index a6bd8e468b706089ccdeb10954194c397b485573..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -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("SignalRServer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SignalRServer")] -[assembly: AssemblyCopyright("Copyright © 2015")] -[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("64b40dbb-f6c1-45b4-8fc4-764526e9f16c")] - -// 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/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.intellisense.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.intellisense.js deleted file mode 100644 index f1d83254a61cd188d6e8a08ad2156cb36174f22a..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.intellisense.js +++ /dev/null @@ -1,2671 +0,0 @@ -/* NUGET: BEGIN LICENSE TEXT - * - * Microsoft grants you the right to use these script files for the sole - * purpose of either: (i) interacting through your browser with the Microsoft - * website or online service, subject to the applicable licensing or use - * terms; or (ii) using the files as included with a Microsoft product subject - * to that product's license terms. Microsoft reserves all other rights to the - * files not expressly granted by Microsoft, whether by implication, estoppel - * or otherwise. Insofar as a script file is dual licensed under GPL, - * Microsoft neither took the code under GPL nor distributes it thereunder but - * under the terms set out in this paragraph. All notices and licenses - * below are for informational purposes only. - * - * NUGET: END LICENSE TEXT */ -intellisense.annotate(jQuery, { - 'ajax': function() { - /// <signature> - /// <summary>Perform an asynchronous HTTP (Ajax) request.</summary> - /// <param name="url" type="String">A string containing the URL to which the request is sent.</param> - /// <param name="settings" type="PlainObject">A set of key/value pairs that configure the Ajax request. All settings are optional. A default can be set for any option with $.ajaxSetup(). See jQuery.ajax( settings ) below for a complete list of all settings.</param> - /// <returns type="jqXHR" /> - /// </signature> - /// <signature> - /// <summary>Perform an asynchronous HTTP (Ajax) request.</summary> - /// <param name="settings" type="PlainObject">A set of key/value pairs that configure the Ajax request. All settings are optional. A default can be set for any option with $.ajaxSetup().</param> - /// <returns type="jqXHR" /> - /// </signature> - }, - 'ajaxPrefilter': function() { - /// <signature> - /// <summary>Handle custom Ajax options or modify existing options before each request is sent and before they are processed by $.ajax().</summary> - /// <param name="dataTypes" type="String">An optional string containing one or more space-separated dataTypes</param> - /// <param name="handler(options, originalOptions, jqXHR)" type="Function">A handler to set default values for future Ajax requests.</param> - /// </signature> - }, - 'ajaxSetup': function() { - /// <signature> - /// <summary>Set default values for future Ajax requests.</summary> - /// <param name="options" type="PlainObject">A set of key/value pairs that configure the default Ajax request. All options are optional.</param> - /// </signature> - }, - 'ajaxTransport': function() { - /// <signature> - /// <summary>Creates an object that handles the actual transmission of Ajax data.</summary> - /// <param name="dataType" type="String">A string identifying the data type to use</param> - /// <param name="handler(options, originalOptions, jqXHR)" type="Function">A handler to return the new transport object to use with the data type provided in the first argument.</param> - /// </signature> - }, - 'boxModel': function() { - /// <summary>Deprecated in jQuery 1.3 (see jQuery.support). States if the current page, in the user's browser, is being rendered using the W3C CSS Box Model.</summary> - /// <returns type="Boolean" /> - }, - 'browser': function() { - /// <summary>Contains flags for the useragent, read from navigator.userAgent. We recommend against using this property; please try to use feature detection instead (see jQuery.support). jQuery.browser may be moved to a plugin in a future release of jQuery.</summary> - /// <returns type="PlainObject" /> - }, - 'browser.version': function() { - /// <summary>The version number of the rendering engine for the user's browser.</summary> - /// <returns type="String" /> - }, - 'Callbacks': function() { - /// <signature> - /// <summary>A multi-purpose callbacks list object that provides a powerful way to manage callback lists.</summary> - /// <param name="flags" type="String">An optional list of space-separated flags that change how the callback list behaves.</param> - /// <returns type="Callbacks" /> - /// </signature> - }, - 'contains': function() { - /// <signature> - /// <summary>Check to see if a DOM element is a descendant of another DOM element.</summary> - /// <param name="container" type="Element">The DOM element that may contain the other element.</param> - /// <param name="contained" type="Element">The DOM element that may be contained by (a descendant of) the other element.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'cssHooks': function() { - /// <summary>Hook directly into jQuery to override how particular CSS properties are retrieved or set, normalize CSS property naming, or create custom properties.</summary> - /// <returns type="Object" /> - }, - 'data': function() { - /// <signature> - /// <summary>Returns value at named data store for the element, as set by jQuery.data(element, name, value), or the full data store for the element.</summary> - /// <param name="element" type="Element">The DOM element to query for the data.</param> - /// <param name="key" type="String">Name of the data stored.</param> - /// <returns type="Object" /> - /// </signature> - /// <signature> - /// <summary>Returns value at named data store for the element, as set by jQuery.data(element, name, value), or the full data store for the element.</summary> - /// <param name="element" type="Element">The DOM element to query for the data.</param> - /// <returns type="Object" /> - /// </signature> - }, - 'Deferred': function() { - /// <signature> - /// <summary>A constructor function that returns a chainable utility object with methods to register multiple callbacks into callback queues, invoke callback queues, and relay the success or failure state of any synchronous or asynchronous function.</summary> - /// <param name="beforeStart" type="Function">A function that is called just before the constructor returns.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'dequeue': function() { - /// <signature> - /// <summary>Execute the next function on the queue for the matched element.</summary> - /// <param name="element" type="Element">A DOM element from which to remove and execute a queued function.</param> - /// <param name="queueName" type="String">A string containing the name of the queue. Defaults to fx, the standard effects queue.</param> - /// </signature> - }, - 'each': function() { - /// <signature> - /// <summary>A generic iterator function, which can be used to seamlessly iterate over both objects and arrays. Arrays and array-like objects with a length property (such as a function's arguments object) are iterated by numeric index, from 0 to length-1. Other objects are iterated via their named properties.</summary> - /// <param name="collection" type="Object">The object or array to iterate over.</param> - /// <param name="callback(indexInArray, valueOfElement)" type="Function">The function that will be executed on every object.</param> - /// <returns type="Object" /> - /// </signature> - }, - 'error': function() { - /// <signature> - /// <summary>Takes a string and throws an exception containing it.</summary> - /// <param name="message" type="String">The message to send out.</param> - /// </signature> - }, - 'extend': function() { - /// <signature> - /// <summary>Merge the contents of two or more objects together into the first object.</summary> - /// <param name="target" type="Object">An object that will receive the new properties if additional objects are passed in or that will extend the jQuery namespace if it is the sole argument.</param> - /// <param name="object1" type="Object">An object containing additional properties to merge in.</param> - /// <param name="objectN" type="Object">Additional objects containing properties to merge in.</param> - /// <returns type="Object" /> - /// </signature> - /// <signature> - /// <summary>Merge the contents of two or more objects together into the first object.</summary> - /// <param name="deep" type="Boolean">If true, the merge becomes recursive (aka. deep copy).</param> - /// <param name="target" type="Object">The object to extend. It will receive the new properties.</param> - /// <param name="object1" type="Object">An object containing additional properties to merge in.</param> - /// <param name="objectN" type="Object">Additional objects containing properties to merge in.</param> - /// <returns type="Object" /> - /// </signature> - }, - 'get': function() { - /// <signature> - /// <summary>Load data from the server using a HTTP GET request.</summary> - /// <param name="url" type="String">A string containing the URL to which the request is sent.</param> - /// <param name="data" type="String">A plain object or string that is sent to the server with the request.</param> - /// <param name="success(data, textStatus, jqXHR)" type="Function">A callback function that is executed if the request succeeds.</param> - /// <param name="dataType" type="String">The type of data expected from the server. Default: Intelligent Guess (xml, json, script, or html).</param> - /// <returns type="jqXHR" /> - /// </signature> - }, - 'getJSON': function() { - /// <signature> - /// <summary>Load JSON-encoded data from the server using a GET HTTP request.</summary> - /// <param name="url" type="String">A string containing the URL to which the request is sent.</param> - /// <param name="data" type="PlainObject">A plain object or string that is sent to the server with the request.</param> - /// <param name="success(data, textStatus, jqXHR)" type="Function">A callback function that is executed if the request succeeds.</param> - /// <returns type="jqXHR" /> - /// </signature> - }, - 'getScript': function() { - /// <signature> - /// <summary>Load a JavaScript file from the server using a GET HTTP request, then execute it.</summary> - /// <param name="url" type="String">A string containing the URL to which the request is sent.</param> - /// <param name="success(script, textStatus, jqXHR)" type="Function">A callback function that is executed if the request succeeds.</param> - /// <returns type="jqXHR" /> - /// </signature> - }, - 'globalEval': function() { - /// <signature> - /// <summary>Execute some JavaScript code globally.</summary> - /// <param name="code" type="String">The JavaScript code to execute.</param> - /// </signature> - }, - 'grep': function() { - /// <signature> - /// <summary>Finds the elements of an array which satisfy a filter function. The original array is not affected.</summary> - /// <param name="array" type="Array">The array to search through.</param> - /// <param name="function(elementOfArray, indexInArray)" type="Function">The function to process each item against. The first argument to the function is the item, and the second argument is the index. The function should return a Boolean value. this will be the global window object.</param> - /// <param name="invert" type="Boolean">If "invert" is false, or not provided, then the function returns an array consisting of all elements for which "callback" returns true. If "invert" is true, then the function returns an array consisting of all elements for which "callback" returns false.</param> - /// <returns type="Array" /> - /// </signature> - }, - 'hasData': function() { - /// <signature> - /// <summary>Determine whether an element has any jQuery data associated with it.</summary> - /// <param name="element" type="Element">A DOM element to be checked for data.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'holdReady': function() { - /// <signature> - /// <summary>Holds or releases the execution of jQuery's ready event.</summary> - /// <param name="hold" type="Boolean">Indicates whether the ready hold is being requested or released</param> - /// </signature> - }, - 'inArray': function() { - /// <signature> - /// <summary>Search for a specified value within an array and return its index (or -1 if not found).</summary> - /// <param name="value" type="Anything">The value to search for.</param> - /// <param name="array" type="Array">An array through which to search.</param> - /// <param name="fromIndex" type="Number">The index of the array at which to begin the search. The default is 0, which will search the whole array.</param> - /// <returns type="Number" /> - /// </signature> - }, - 'isArray': function() { - /// <signature> - /// <summary>Determine whether the argument is an array.</summary> - /// <param name="obj" type="Object">Object to test whether or not it is an array.</param> - /// <returns type="boolean" /> - /// </signature> - }, - 'isEmptyObject': function() { - /// <signature> - /// <summary>Check to see if an object is empty (contains no enumerable properties).</summary> - /// <param name="object" type="Object">The object that will be checked to see if it's empty.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'isFunction': function() { - /// <signature> - /// <summary>Determine if the argument passed is a Javascript function object.</summary> - /// <param name="obj" type="PlainObject">Object to test whether or not it is a function.</param> - /// <returns type="boolean" /> - /// </signature> - }, - 'isNumeric': function() { - /// <signature> - /// <summary>Determines whether its argument is a number.</summary> - /// <param name="value" type="PlainObject">The value to be tested.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'isPlainObject': function() { - /// <signature> - /// <summary>Check to see if an object is a plain object (created using "{}" or "new Object").</summary> - /// <param name="object" type="PlainObject">The object that will be checked to see if it's a plain object.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'isWindow': function() { - /// <signature> - /// <summary>Determine whether the argument is a window.</summary> - /// <param name="obj" type="PlainObject">Object to test whether or not it is a window.</param> - /// <returns type="boolean" /> - /// </signature> - }, - 'isXMLDoc': function() { - /// <signature> - /// <summary>Check to see if a DOM node is within an XML document (or is an XML document).</summary> - /// <param name="node" type="Element">The DOM node that will be checked to see if it's in an XML document.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'makeArray': function() { - /// <signature> - /// <summary>Convert an array-like object into a true JavaScript array.</summary> - /// <param name="obj" type="PlainObject">Any object to turn into a native Array.</param> - /// <returns type="Array" /> - /// </signature> - }, - 'map': function() { - /// <signature> - /// <summary>Translate all items in an array or object to new array of items.</summary> - /// <param name="array" type="Array">The Array to translate.</param> - /// <param name="callback(elementOfArray, indexInArray)" type="Function">The function to process each item against. The first argument to the function is the array item, the second argument is the index in array The function can return any value. Within the function, this refers to the global (window) object.</param> - /// <returns type="Array" /> - /// </signature> - /// <signature> - /// <summary>Translate all items in an array or object to new array of items.</summary> - /// <param name="arrayOrObject" type="Object">The Array or Object to translate.</param> - /// <param name="callback( value, indexOrKey )" type="Function">The function to process each item against. The first argument to the function is the value; the second argument is the index or key of the array or object property. The function can return any value to add to the array. A returned array will be flattened into the resulting array. Within the function, this refers to the global (window) object.</param> - /// <returns type="Array" /> - /// </signature> - }, - 'merge': function() { - /// <signature> - /// <summary>Merge the contents of two arrays together into the first array.</summary> - /// <param name="first" type="Array">The first array to merge, the elements of second added.</param> - /// <param name="second" type="Array">The second array to merge into the first, unaltered.</param> - /// <returns type="Array" /> - /// </signature> - }, - 'noConflict': function() { - /// <signature> - /// <summary>Relinquish jQuery's control of the $ variable.</summary> - /// <param name="removeAll" type="Boolean">A Boolean indicating whether to remove all jQuery variables from the global scope (including jQuery itself).</param> - /// <returns type="Object" /> - /// </signature> - }, - 'noop': function() { - /// <summary>An empty function.</summary> - }, - 'now': function() { - /// <summary>Return a number representing the current time.</summary> - /// <returns type="Number" /> - }, - 'param': function() { - /// <signature> - /// <summary>Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request.</summary> - /// <param name="obj" type="Object">An array or object to serialize.</param> - /// <returns type="String" /> - /// </signature> - /// <signature> - /// <summary>Create a serialized representation of an array or object, suitable for use in a URL query string or Ajax request.</summary> - /// <param name="obj" 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" /> - /// </signature> - }, - 'parseHTML': function() { - /// <signature> - /// <summary>Parses a string into an array of DOM nodes.</summary> - /// <param name="data" type="String">HTML string to be parsed</param> - /// <param name="context" type="Element">DOM element to serve as the context in which the HTML fragment will be created</param> - /// <param name="keepScripts" type="Boolean">A Boolean indicating whether to include scripts passed in the HTML string</param> - /// <returns type="Array" /> - /// </signature> - }, - 'parseJSON': function() { - /// <signature> - /// <summary>Takes a well-formed JSON string and returns the resulting JavaScript object.</summary> - /// <param name="json" type="String">The JSON string to parse.</param> - /// <returns type="Object" /> - /// </signature> - }, - 'parseXML': function() { - /// <signature> - /// <summary>Parses a string into an XML document.</summary> - /// <param name="data" type="String">a well-formed XML string to be parsed</param> - /// <returns type="XMLDocument" /> - /// </signature> - }, - 'post': function() { - /// <signature> - /// <summary>Load data from the server using a HTTP POST request.</summary> - /// <param name="url" type="String">A string containing the URL to which the request is sent.</param> - /// <param name="data" type="String">A plain object or string that is sent to the server with the request.</param> - /// <param name="success(data, textStatus, jqXHR)" type="Function">A callback function that is executed if the request succeeds.</param> - /// <param name="dataType" type="String">The type of data expected from the server. Default: Intelligent Guess (xml, json, script, text, html).</param> - /// <returns type="jqXHR" /> - /// </signature> - }, - 'proxy': function() { - /// <signature> - /// <summary>Takes a function and returns a new one that will always have a particular context.</summary> - /// <param name="function" type="Function">The function whose context will be changed.</param> - /// <param name="context" type="PlainObject">The object to which the context (this) of the function should be set.</param> - /// <returns type="Function" /> - /// </signature> - /// <signature> - /// <summary>Takes a function and returns a new one that will always have a particular context.</summary> - /// <param name="context" type="PlainObject">The object to which the context of the function should be set.</param> - /// <param name="name" type="String">The name of the function whose context will be changed (should be a property of the context object).</param> - /// <returns type="Function" /> - /// </signature> - /// <signature> - /// <summary>Takes a function and returns a new one that will always have a particular context.</summary> - /// <param name="function" type="Function">The function whose context will be changed.</param> - /// <param name="context" type="PlainObject">The object to which the context (this) of the function should be set.</param> - /// <param name="additionalArguments" type="Anything">Any number of arguments to be passed to the function referenced in the function argument.</param> - /// <returns type="Function" /> - /// </signature> - /// <signature> - /// <summary>Takes a function and returns a new one that will always have a particular context.</summary> - /// <param name="context" type="PlainObject">The object to which the context of the function should be set.</param> - /// <param name="name" type="String">The name of the function whose context will be changed (should be a property of the context object).</param> - /// <param name="additionalArguments" type="Anything">Any number of arguments to be passed to the function named in the name argument.</param> - /// <returns type="Function" /> - /// </signature> - }, - 'queue': function() { - /// <signature> - /// <summary>Manipulate the queue of functions to be executed on the matched element.</summary> - /// <param name="element" type="Element">A DOM element where the array of queued functions is attached.</param> - /// <param name="queueName" type="String">A string containing the name of the queue. Defaults to fx, the standard effects queue.</param> - /// <param name="newQueue" type="Array">An array of functions to replace the current queue contents.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Manipulate the queue of functions to be executed on the matched element.</summary> - /// <param name="element" type="Element">A DOM element on which to add a queued function.</param> - /// <param name="queueName" type="String">A string containing the name of the queue. Defaults to fx, the standard effects queue.</param> - /// <param name="callback()" type="Function">The new function to add to the queue.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'removeData': function() { - /// <signature> - /// <summary>Remove a previously-stored piece of data.</summary> - /// <param name="element" type="Element">A DOM element from which to remove data.</param> - /// <param name="name" type="String">A string naming the piece of data to remove.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'sub': function() { - /// <summary>Creates a new copy of jQuery whose properties and methods can be modified without affecting the original jQuery object.</summary> - /// <returns type="jQuery" /> - }, - 'support': function() { - /// <summary>A collection of properties that represent the presence of different browser features or bugs. Primarily intended for jQuery's internal use; specific properties may be removed when they are no longer needed internally to improve page startup performance.</summary> - /// <returns type="Object" /> - }, - 'trim': function() { - /// <signature> - /// <summary>Remove the whitespace from the beginning and end of a string.</summary> - /// <param name="str" type="String">The string to trim.</param> - /// <returns type="String" /> - /// </signature> - }, - 'type': function() { - /// <signature> - /// <summary>Determine the internal JavaScript [[Class]] of an object.</summary> - /// <param name="obj" type="PlainObject">Object to get the internal JavaScript [[Class]] of.</param> - /// <returns type="String" /> - /// </signature> - }, - 'unique': function() { - /// <signature> - /// <summary>Sorts an array of DOM elements, in place, with the duplicates removed. Note that this only works on arrays of DOM elements, not strings or numbers.</summary> - /// <param name="array" type="Array">The Array of DOM elements.</param> - /// <returns type="Array" /> - /// </signature> - }, - 'when': function() { - /// <signature> - /// <summary>Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events.</summary> - /// <param name="deferreds" type="Deferred">One or more Deferred objects, or plain JavaScript objects.</param> - /// <returns type="Promise" /> - /// </signature> - }, -}); - -var _1228819969 = jQuery.Callbacks; -jQuery.Callbacks = function(flags) { -var _object = _1228819969(flags); -intellisense.annotate(_object, { - 'add': function() { - /// <signature> - /// <summary>Add a callback or a collection of callbacks to a callback list.</summary> - /// <param name="callbacks" type="Array">A function, or array of functions, that are to be added to the callback list.</param> - /// <returns type="Callbacks" /> - /// </signature> - }, - 'disable': function() { - /// <summary>Disable a callback list from doing anything more.</summary> - /// <returns type="Callbacks" /> - }, - 'disabled': function() { - /// <summary>Determine if the callbacks list has been disabled.</summary> - /// <returns type="Boolean" /> - }, - 'empty': function() { - /// <summary>Remove all of the callbacks from a list.</summary> - /// <returns type="Callbacks" /> - }, - 'fire': function() { - /// <signature> - /// <summary>Call all of the callbacks with the given arguments</summary> - /// <param name="arguments" type="Anything">The argument or list of arguments to pass back to the callback list.</param> - /// <returns type="Callbacks" /> - /// </signature> - }, - 'fired': function() { - /// <summary>Determine if the callbacks have already been called at least once.</summary> - /// <returns type="Boolean" /> - }, - 'fireWith': function() { - /// <signature> - /// <summary>Call all callbacks in a list with the given context and arguments.</summary> - /// <param name="context" type="">A reference to the context in which the callbacks in the list should be fired.</param> - /// <param name="args" type="">An argument, or array of arguments, to pass to the callbacks in the list.</param> - /// <returns type="Callbacks" /> - /// </signature> - }, - 'has': function() { - /// <signature> - /// <summary>Determine whether a supplied callback is in a list</summary> - /// <param name="callback" type="Function">The callback to search for.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'lock': function() { - /// <summary>Lock a callback list in its current state.</summary> - /// <returns type="Callbacks" /> - }, - 'locked': function() { - /// <summary>Determine if the callbacks list has been locked.</summary> - /// <returns type="Boolean" /> - }, - 'remove': function() { - /// <signature> - /// <summary>Remove a callback or a collection of callbacks from a callback list.</summary> - /// <param name="callbacks" type="Array">A function, or array of functions, that are to be removed from the callback list.</param> - /// <returns type="Callbacks" /> - /// </signature> - }, -}); - -return _object; -}; -intellisense.redirectDefinition(jQuery.Callbacks, _1228819969); - -var _731531622 = jQuery.Deferred; -jQuery.Deferred = function(func) { -var _object = _731531622(func); -intellisense.annotate(_object, { - 'always': function() { - /// <signature> - /// <summary>Add handlers to be called when the Deferred object is either resolved or rejected.</summary> - /// <param name="alwaysCallbacks" type="Function">A function, or array of functions, that is called when the Deferred is resolved or rejected.</param> - /// <param name="alwaysCallbacks" type="Function">Optional additional functions, or arrays of functions, that are called when the Deferred is resolved or rejected.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'done': function() { - /// <signature> - /// <summary>Add handlers to be called when the Deferred object is resolved.</summary> - /// <param name="doneCallbacks" type="Function">A function, or array of functions, that are called when the Deferred is resolved.</param> - /// <param name="doneCallbacks" type="Function">Optional additional functions, or arrays of functions, that are called when the Deferred is resolved.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'fail': function() { - /// <signature> - /// <summary>Add handlers to be called when the Deferred object is rejected.</summary> - /// <param name="failCallbacks" type="Function">A function, or array of functions, that are called when the Deferred is rejected.</param> - /// <param name="failCallbacks" type="Function">Optional additional functions, or arrays of functions, that are called when the Deferred is rejected.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'isRejected': function() { - /// <summary>Determine whether a Deferred object has been rejected.</summary> - /// <returns type="Boolean" /> - }, - 'isResolved': function() { - /// <summary>Determine whether a Deferred object has been resolved.</summary> - /// <returns type="Boolean" /> - }, - 'notify': function() { - /// <signature> - /// <summary>Call the progressCallbacks on a Deferred object with the given args.</summary> - /// <param name="args" type="Object">Optional arguments that are passed to the progressCallbacks.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'notifyWith': function() { - /// <signature> - /// <summary>Call the progressCallbacks on a Deferred object with the given context and args.</summary> - /// <param name="context" type="Object">Context passed to the progressCallbacks as the this object.</param> - /// <param name="args" type="Object">Optional arguments that are passed to the progressCallbacks.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'pipe': function() { - /// <signature> - /// <summary>Utility method to filter and/or chain Deferreds.</summary> - /// <param name="doneFilter" type="Function">An optional function that is called when the Deferred is resolved.</param> - /// <param name="failFilter" type="Function">An optional function that is called when the Deferred is rejected.</param> - /// <returns type="Promise" /> - /// </signature> - /// <signature> - /// <summary>Utility method to filter and/or chain Deferreds.</summary> - /// <param name="doneFilter" type="Function">An optional function that is called when the Deferred is resolved.</param> - /// <param name="failFilter" type="Function">An optional function that is called when the Deferred is rejected.</param> - /// <param name="progressFilter" type="Function">An optional function that is called when progress notifications are sent to the Deferred.</param> - /// <returns type="Promise" /> - /// </signature> - }, - 'progress': function() { - /// <signature> - /// <summary>Add handlers to be called when the Deferred object generates progress notifications.</summary> - /// <param name="progressCallbacks" type="Function">A function, or array of functions, that is called when the Deferred generates progress notifications.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'promise': function() { - /// <signature> - /// <summary>Return a Deferred's Promise object.</summary> - /// <param name="target" type="Object">Object onto which the promise methods have to be attached</param> - /// <returns type="Promise" /> - /// </signature> - }, - 'reject': function() { - /// <signature> - /// <summary>Reject a Deferred object and call any failCallbacks with the given args.</summary> - /// <param name="args" type="Object">Optional arguments that are passed to the failCallbacks.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'rejectWith': function() { - /// <signature> - /// <summary>Reject a Deferred object and call any failCallbacks with the given context and args.</summary> - /// <param name="context" type="Object">Context passed to the failCallbacks as the this object.</param> - /// <param name="args" type="Array">An optional array of arguments that are passed to the failCallbacks.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'resolve': function() { - /// <signature> - /// <summary>Resolve a Deferred object and call any doneCallbacks with the given args.</summary> - /// <param name="args" type="Object">Optional arguments that are passed to the doneCallbacks.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'resolveWith': function() { - /// <signature> - /// <summary>Resolve a Deferred object and call any doneCallbacks with the given context and args.</summary> - /// <param name="context" type="Object">Context passed to the doneCallbacks as the this object.</param> - /// <param name="args" type="Array">An optional array of arguments that are passed to the doneCallbacks.</param> - /// <returns type="Deferred" /> - /// </signature> - }, - 'state': function() { - /// <summary>Determine the current state of a Deferred object.</summary> - /// <returns type="String" /> - }, - 'then': function() { - /// <signature> - /// <summary>Add handlers to be called when the Deferred object is resolved, rejected, or still in progress.</summary> - /// <param name="doneFilter" type="Function">A function that is called when the Deferred is resolved.</param> - /// <param name="failFilter" type="Function">An optional function that is called when the Deferred is rejected.</param> - /// <param name="progressFilter" type="Function">An optional function that is called when progress notifications are sent to the Deferred.</param> - /// <returns type="Promise" /> - /// </signature> - /// <signature> - /// <summary>Add handlers to be called when the Deferred object is resolved, rejected, or still in progress.</summary> - /// <param name="doneCallbacks" type="Function">A function, or array of functions, called when the Deferred is resolved.</param> - /// <param name="failCallbacks" type="Function">A function, or array of functions, called when the Deferred is rejected.</param> - /// <returns type="Promise" /> - /// </signature> - /// <signature> - /// <summary>Add handlers to be called when the Deferred object is resolved, rejected, or still in progress.</summary> - /// <param name="doneCallbacks" type="Function">A function, or array of functions, called when the Deferred is resolved.</param> - /// <param name="failCallbacks" type="Function">A function, or array of functions, called when the Deferred is rejected.</param> - /// <param name="progressCallbacks" type="Function">A function, or array of functions, called when the Deferred notifies progress.</param> - /// <returns type="Promise" /> - /// </signature> - }, -}); - -return _object; -}; -intellisense.redirectDefinition(jQuery.Callbacks, _731531622); - -intellisense.annotate(jQuery.Event.prototype, { - 'currentTarget': function() { - /// <summary>The current DOM element within the event bubbling phase.</summary> - /// <returns type="Element" /> - }, - 'data': function() { - /// <summary>An optional object of data passed to an event method when the current executing handler is bound.</summary> - /// <returns type="Object" /> - }, - 'delegateTarget': function() { - /// <summary>The element where the currently-called jQuery event handler was attached.</summary> - /// <returns type="Element" /> - }, - 'isDefaultPrevented': function() { - /// <summary>Returns whether event.preventDefault() was ever called on this event object.</summary> - /// <returns type="Boolean" /> - }, - 'isImmediatePropagationStopped': function() { - /// <summary>Returns whether event.stopImmediatePropagation() was ever called on this event object.</summary> - /// <returns type="Boolean" /> - }, - 'isPropagationStopped': function() { - /// <summary>Returns whether event.stopPropagation() was ever called on this event object.</summary> - /// <returns type="Boolean" /> - }, - 'metaKey': function() { - /// <summary>Indicates whether the META key was pressed when the event fired.</summary> - /// <returns type="Boolean" /> - }, - 'namespace': function() { - /// <summary>The namespace specified when the event was triggered.</summary> - /// <returns type="String" /> - }, - 'pageX': function() { - /// <summary>The mouse position relative to the left edge of the document.</summary> - /// <returns type="Number" /> - }, - 'pageY': function() { - /// <summary>The mouse position relative to the top edge of the document.</summary> - /// <returns type="Number" /> - }, - 'preventDefault': function() { - /// <summary>If this method is called, the default action of the event will not be triggered.</summary> - }, - 'relatedTarget': function() { - /// <summary>The other DOM element involved in the event, if any.</summary> - /// <returns type="Element" /> - }, - 'result': function() { - /// <summary>The last value returned by an event handler that was triggered by this event, unless the value was undefined.</summary> - /// <returns type="Object" /> - }, - 'stopImmediatePropagation': function() { - /// <summary>Keeps the rest of the handlers from being executed and prevents the event from bubbling up the DOM tree.</summary> - }, - 'stopPropagation': function() { - /// <summary>Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.</summary> - }, - 'target': function() { - /// <summary>The DOM element that initiated the event.</summary> - /// <returns type="Element" /> - }, - 'timeStamp': function() { - /// <summary>The difference in milliseconds between the time the browser created the event and January 1, 1970.</summary> - /// <returns type="Number" /> - }, - 'type': function() { - /// <summary>Describes the nature of the event.</summary> - /// <returns type="String" /> - }, - 'which': function() { - /// <summary>For key or mouse events, this property indicates the specific key or button that was pressed.</summary> - /// <returns type="Number" /> - }, -}); - -intellisense.annotate(jQuery.fn, { - 'add': function() { - /// <signature> - /// <summary>Add elements to the set of matched elements.</summary> - /// <param name="selector" type="String">A string representing a selector expression to find additional elements to add to the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Add elements to the set of matched elements.</summary> - /// <param name="elements" type="Array">One or more elements to add to the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Add elements to the set of matched elements.</summary> - /// <param name="html" type="String">An HTML fragment to add to the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Add elements to the set of matched elements.</summary> - /// <param name="jQuery object" type="jQuery object ">An existing jQuery object to add to the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Add elements to the set of matched elements.</summary> - /// <param name="selector" type="String">A string representing a selector expression to find additional elements to add to the set of matched elements.</param> - /// <param name="context" type="Element">The point in the document at which the selector should begin matching; similar to the context argument of the $(selector, context) method.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'addBack': function() { - /// <signature> - /// <summary>Add the previous set of elements on the stack to the current set, optionally filtered by a selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match the current set of elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'addClass': function() { - /// <signature> - /// <summary>Adds the specified class(es) to each of the set of matched elements.</summary> - /// <param name="className" type="String">One or more space-separated classes to be added to the class attribute of each matched element.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Adds the specified class(es) to each of the set of matched elements.</summary> - /// <param name="function(index, currentClass)" type="Function">A function returning one or more space-separated class names to be added to the existing class name(s). Receives the index position of the element in the set and the existing class name(s) as arguments. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'after': function() { - /// <signature> - /// <summary>Insert content, specified by the parameter, after each element in the set of matched elements.</summary> - /// <param name="content" type="jQuery">HTML string, DOM element, or jQuery object to insert after each element in the set of matched elements.</param> - /// <param name="content" type="jQuery">One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert after each element in the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Insert content, specified by the parameter, after each element in the set of matched elements.</summary> - /// <param name="function(index)" type="Function">A function that returns an HTML string, DOM element(s), or jQuery object to insert after each element in the set of matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'ajaxComplete': function() { - /// <signature> - /// <summary>Register a handler to be called when Ajax requests complete. This is an AjaxEvent.</summary> - /// <param name="handler(event, XMLHttpRequest, ajaxOptions)" type="Function">The function to be invoked.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'ajaxError': function() { - /// <signature> - /// <summary>Register a handler to be called when Ajax requests complete with an error. This is an Ajax Event.</summary> - /// <param name="handler(event, jqXHR, ajaxSettings, thrownError)" type="Function">The function to be invoked.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'ajaxSend': function() { - /// <signature> - /// <summary>Attach a function to be executed before an Ajax request is sent. This is an Ajax Event.</summary> - /// <param name="handler(event, jqXHR, ajaxOptions)" type="Function">The function to be invoked.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'ajaxStart': function() { - /// <signature> - /// <summary>Register a handler to be called when the first Ajax request begins. This is an Ajax Event.</summary> - /// <param name="handler()" type="Function">The function to be invoked.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'ajaxStop': function() { - /// <signature> - /// <summary>Register a handler to be called when all Ajax requests have completed. This is an Ajax Event.</summary> - /// <param name="handler()" type="Function">The function to be invoked.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'ajaxSuccess': function() { - /// <signature> - /// <summary>Attach a function to be executed whenever an Ajax request completes successfully. This is an Ajax Event.</summary> - /// <param name="handler(event, XMLHttpRequest, ajaxOptions)" type="Function">The function to be invoked.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'all': function() { - /// <summary>Selects all elements.</summary> - }, - 'andSelf': function() { - /// <summary>Add the previous set of elements on the stack to the current set.</summary> - /// <returns type="jQuery" /> - }, - 'animate': function() { - /// <signature> - /// <summary>Perform a custom animation of a set of CSS properties.</summary> - /// <param name="properties" type="PlainObject">An object of CSS properties and values that the animation will move toward.</param> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Perform a custom animation of a set of CSS properties.</summary> - /// <param name="properties" type="PlainObject">An object of CSS properties and values that the animation will move toward.</param> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'animated': function() { - /// <summary>Select all elements that are in the progress of an animation at the time the selector is run.</summary> - }, - 'append': function() { - /// <signature> - /// <summary>Insert content, specified by the parameter, to the end of each element in the set of matched elements.</summary> - /// <param name="content" type="jQuery">DOM element, HTML string, or jQuery object to insert at the end of each element in the set of matched elements.</param> - /// <param name="content" type="jQuery">One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the end of each element in the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Insert content, specified by the parameter, to the end of each element in the set of matched elements.</summary> - /// <param name="function(index, html)" type="Function">A function that returns an HTML string, DOM element(s), or jQuery object to insert at the end of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'appendTo': function() { - /// <signature> - /// <summary>Insert every element in the set of matched elements to the end of the target.</summary> - /// <param name="target" type="jQuery">A selector, element, HTML string, or jQuery object; the matched set of elements will be inserted at the end of the element(s) specified by this parameter.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'attr': function() { - /// <signature> - /// <summary>Set one or more attributes for the set of matched elements.</summary> - /// <param name="attributeName" type="String">The name of the attribute to set.</param> - /// <param name="value" type="Number">A value to set for the attribute.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set one or more attributes for the set of matched elements.</summary> - /// <param name="attributes" type="PlainObject">An object of attribute-value pairs to set.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set one or more attributes for the set of matched elements.</summary> - /// <param name="attributeName" type="String">The name of the attribute to set.</param> - /// <param name="function(index, attr)" type="Function">A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old attribute value as arguments.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'attributeContains': function() { - /// <signature> - /// <summary>Selects elements that have the specified attribute with a value containing the a given substring.</summary> - /// <param name="attribute" type="String">An attribute name.</param> - /// <param name="value" type="String">An attribute value. Can be either an unquoted single word or a quoted string.</param> - /// </signature> - }, - 'attributeContainsPrefix': function() { - /// <signature> - /// <summary>Selects elements that have the specified attribute with a value either equal to a given string or starting with that string followed by a hyphen (-).</summary> - /// <param name="attribute" type="String">An attribute name.</param> - /// <param name="value" type="String">An attribute value. Can be either an unquoted single word or a quoted string.</param> - /// </signature> - }, - 'attributeContainsWord': function() { - /// <signature> - /// <summary>Selects elements that have the specified attribute with a value containing a given word, delimited by spaces.</summary> - /// <param name="attribute" type="String">An attribute name.</param> - /// <param name="value" type="String">An attribute value. Can be either an unquoted single word or a quoted string.</param> - /// </signature> - }, - 'attributeEndsWith': function() { - /// <signature> - /// <summary>Selects elements that have the specified attribute with a value ending exactly with a given string. The comparison is case sensitive.</summary> - /// <param name="attribute" type="String">An attribute name.</param> - /// <param name="value" type="String">An attribute value. Can be either an unquoted single word or a quoted string.</param> - /// </signature> - }, - 'attributeEquals': function() { - /// <signature> - /// <summary>Selects elements that have the specified attribute with a value exactly equal to a certain value.</summary> - /// <param name="attribute" type="String">An attribute name.</param> - /// <param name="value" type="String">An attribute value. Can be either an unquoted single word or a quoted string.</param> - /// </signature> - }, - 'attributeHas': function() { - /// <signature> - /// <summary>Selects elements that have the specified attribute, with any value.</summary> - /// <param name="attribute" type="String">An attribute name.</param> - /// </signature> - }, - 'attributeMultiple': function() { - /// <signature> - /// <summary>Matches elements that match all of the specified attribute filters.</summary> - /// <param name="attributeFilter1" type="String">An attribute filter.</param> - /// <param name="attributeFilter2" type="String">Another attribute filter, reducing the selection even more</param> - /// <param name="attributeFilterN" type="String">As many more attribute filters as necessary</param> - /// </signature> - }, - 'attributeNotEqual': function() { - /// <signature> - /// <summary>Select elements that either don't have the specified attribute, or do have the specified attribute but not with a certain value.</summary> - /// <param name="attribute" type="String">An attribute name.</param> - /// <param name="value" type="String">An attribute value. Can be either an unquoted single word or a quoted string.</param> - /// </signature> - }, - 'attributeStartsWith': function() { - /// <signature> - /// <summary>Selects elements that have the specified attribute with a value beginning exactly with a given string.</summary> - /// <param name="attribute" type="String">An attribute name.</param> - /// <param name="value" type="String">An attribute value. Can be either an unquoted single word or a quoted string.</param> - /// </signature> - }, - 'before': function() { - /// <signature> - /// <summary>Insert content, specified by the parameter, before each element in the set of matched elements.</summary> - /// <param name="content" type="jQuery">HTML string, DOM element, or jQuery object to insert before each element in the set of matched elements.</param> - /// <param name="content" type="jQuery">One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert before each element in the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Insert content, specified by the parameter, before each element in the set of matched elements.</summary> - /// <param name="function" type="Function">A function that returns an HTML string, DOM element(s), or jQuery object to insert before each element in the set of matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'bind': function() { - /// <signature> - /// <summary>Attach a handler to an event for the elements.</summary> - /// <param name="eventType" type="String">A string containing one or more DOM event types, such as "click" or "submit," or custom event names.</param> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach a handler to an event for the elements.</summary> - /// <param name="eventType" type="String">A string containing one or more DOM event types, such as "click" or "submit," or custom event names.</param> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="preventBubble" type="Boolean">Setting the third argument to false will attach a function that prevents the default action from occurring and stops the event from bubbling. The default is true.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach a handler to an event for the elements.</summary> - /// <param name="events" type="Object">An object containing one or more DOM event types and functions to execute for them.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'blur': function() { - /// <signature> - /// <summary>Bind an event handler to the "blur" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "blur" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'button': function() { - /// <summary>Selects all button elements and elements of type button.</summary> - }, - 'change': function() { - /// <signature> - /// <summary>Bind an event handler to the "change" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "change" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'checkbox': function() { - /// <summary>Selects all elements of type checkbox.</summary> - }, - 'checked': function() { - /// <summary>Matches all elements that are checked.</summary> - }, - 'child': function() { - /// <signature> - /// <summary>Selects all direct child elements specified by "child" of elements specified by "parent".</summary> - /// <param name="parent" type="String">Any valid selector.</param> - /// <param name="child" type="String">A selector to filter the child elements.</param> - /// </signature> - }, - 'children': function() { - /// <signature> - /// <summary>Get the children of each element in the set of matched elements, optionally filtered by a selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'class': function() { - /// <signature> - /// <summary>Selects all elements with the given class.</summary> - /// <param name="class" type="String">A class to search for. An element can have multiple classes; only one of them must match.</param> - /// </signature> - }, - 'clearQueue': function() { - /// <signature> - /// <summary>Remove from the queue all items that have not yet been run.</summary> - /// <param name="queueName" type="String">A string containing the name of the queue. Defaults to fx, the standard effects queue.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'click': function() { - /// <signature> - /// <summary>Bind an event handler to the "click" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "click" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'clone': function() { - /// <signature> - /// <summary>Create a deep copy of the set of matched elements.</summary> - /// <param name="withDataAndEvents" type="Boolean">A Boolean indicating whether event handlers should be copied along with the elements. As of jQuery 1.4, element data will be copied as well.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Create a deep copy of the set of matched elements.</summary> - /// <param name="withDataAndEvents" type="Boolean">A Boolean indicating whether event handlers and data should be copied along with the elements. The default value is false. *In jQuery 1.5.0 the default value was incorrectly true; it was changed back to false in 1.5.1 and up.</param> - /// <param name="deepWithDataAndEvents" type="Boolean">A Boolean indicating whether event handlers and data for all children of the cloned element should be copied. By default its value matches the first argument's value (which defaults to false).</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'closest': function() { - /// <signature> - /// <summary>For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.</summary> - /// <param name="selector" 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" /> - /// </signature> - /// <signature> - /// <summary>For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.</summary> - /// <param name="jQuery object" type="jQuery">A jQuery object to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.</summary> - /// <param name="element" type="Element">An element to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'contains': function() { - /// <signature> - /// <summary>Select all elements that contain the specified text.</summary> - /// <param name="text" type="String">A string of text to look for. It's case sensitive.</param> - /// </signature> - }, - 'contents': function() { - /// <summary>Get the children of each element in the set of matched elements, including text and comment nodes.</summary> - /// <returns type="jQuery" /> - }, - 'context': function() { - /// <summary>The DOM node context originally passed to jQuery(); if none was passed then context will likely be the document.</summary> - /// <returns type="Element" /> - }, - 'css': function() { - /// <signature> - /// <summary>Set one or more CSS properties for the set of matched elements.</summary> - /// <param name="propertyName" type="String">A CSS property name.</param> - /// <param name="value" type="Number">A value to set for the property.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set one or more CSS properties for the set of matched elements.</summary> - /// <param name="propertyName" type="String">A CSS property name.</param> - /// <param name="function(index, value)" type="Function">A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set one or more CSS properties for the set of matched elements.</summary> - /// <param name="properties" type="PlainObject">An object of property-value pairs to set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'data': function() { - /// <signature> - /// <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; it can be any Javascript type including Array or Object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Store arbitrary data associated with the matched elements.</summary> - /// <param name="obj" type="Object">An object of key-value pairs of data to update.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'dblclick': function() { - /// <signature> - /// <summary>Bind an event handler to the "dblclick" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "dblclick" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'delay': function() { - /// <signature> - /// <summary>Set a timer to delay execution of subsequent items in the queue.</summary> - /// <param name="duration" type="Number">An integer indicating the number of milliseconds to delay execution of the next item in the queue.</param> - /// <param name="queueName" type="String">A string containing the name of the queue. Defaults to fx, the standard effects queue.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'delegate': function() { - /// <signature> - /// <summary>Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.</summary> - /// <param name="selector" type="String">A selector to filter the elements that trigger the event.</param> - /// <param name="eventType" type="String">A string containing one or more space-separated JavaScript event types, such as "click" or "keydown," or custom event names.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute at the time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.</summary> - /// <param name="selector" type="String">A selector to filter the elements that trigger the event.</param> - /// <param name="eventType" type="String">A string containing one or more space-separated JavaScript event types, such as "click" or "keydown," or custom event names.</param> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute at the time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach a handler to one or more events for all elements that match the selector, now or in the future, based on a specific set of root elements.</summary> - /// <param name="selector" type="String">A selector to filter the elements that trigger the event.</param> - /// <param name="events" type="PlainObject">A plain object of one or more event types and functions to execute for them.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'dequeue': function() { - /// <signature> - /// <summary>Execute the next function on the queue for the matched elements.</summary> - /// <param name="queueName" type="String">A string containing the name of the queue. Defaults to fx, the standard effects queue.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'descendant': function() { - /// <signature> - /// <summary>Selects all elements that are descendants of a given ancestor.</summary> - /// <param name="ancestor" type="String">Any valid selector.</param> - /// <param name="descendant" type="String">A selector to filter the descendant elements.</param> - /// </signature> - }, - 'detach': function() { - /// <signature> - /// <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" /> - /// </signature> - }, - 'die': function() { - /// <signature> - /// <summary>Remove event handlers previously attached using .live() from the elements.</summary> - /// <param name="eventType" type="String">A string containing a JavaScript event type, such as click or keydown.</param> - /// <param name="handler" type="String">The function that is no longer to be executed.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove event handlers previously attached using .live() from the elements.</summary> - /// <param name="events" type="PlainObject">A plain object of one or more event types, such as click or keydown and their corresponding functions that are no longer to be executed.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'disabled': function() { - /// <summary>Selects all elements that are disabled.</summary> - }, - 'each': function() { - /// <signature> - /// <summary>Iterate over a jQuery object, executing a function for each matched element.</summary> - /// <param name="function(index, Element)" type="Function">A function to execute for each matched element.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'element': function() { - /// <signature> - /// <summary>Selects all elements with the given tag name.</summary> - /// <param name="element" type="String">An element to search for. Refers to the tagName of DOM nodes.</param> - /// </signature> - }, - 'empty': function() { - /// <summary>Select all elements that have no children (including text nodes).</summary> - }, - 'enabled': function() { - /// <summary>Selects all elements that are enabled.</summary> - }, - 'end': function() { - /// <summary>End the most recent filtering operation in the current chain and return the set of matched elements to its previous state.</summary> - /// <returns type="jQuery" /> - }, - 'eq': function() { - /// <signature> - /// <summary>Select the element at index n within the matched set.</summary> - /// <param name="index" type="Number">Zero-based index of the element to match.</param> - /// </signature> - /// <signature> - /// <summary>Select the element at index n within the matched set.</summary> - /// <param name="-index" type="Number">Zero-based index of the element to match, counting backwards from the last element.</param> - /// </signature> - }, - 'error': function() { - /// <signature> - /// <summary>Bind an event handler to the "error" JavaScript event.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute when the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "error" JavaScript event.</summary> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'even': function() { - /// <summary>Selects even elements, zero-indexed. See also odd.</summary> - }, - 'fadeIn': function() { - /// <signature> - /// <summary>Display the matched elements by fading them to opaque.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display the matched elements by fading them to opaque.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display the matched elements by fading them to opaque.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'fadeOut': function() { - /// <signature> - /// <summary>Hide the matched elements by fading them to transparent.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Hide the matched elements by fading them to transparent.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Hide the matched elements by fading them to transparent.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'fadeTo': function() { - /// <signature> - /// <summary>Adjust the opacity of the matched elements.</summary> - /// <param name="duration" type="Number">A string or number determining how long the animation will run.</param> - /// <param name="opacity" type="Number">A number between 0 and 1 denoting the target opacity.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Adjust the opacity of the matched elements.</summary> - /// <param name="duration" type="Number">A string or number determining how long the animation will run.</param> - /// <param name="opacity" type="Number">A number between 0 and 1 denoting the target opacity.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'fadeToggle': function() { - /// <signature> - /// <summary>Display or hide the matched elements by animating their opacity.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display or hide the matched elements by animating their opacity.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'file': function() { - /// <summary>Selects all elements of type file.</summary> - }, - 'filter': function() { - /// <signature> - /// <summary>Reduce the set of matched elements to those that match the selector or pass the function's test.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match the current set of elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Reduce the set of matched elements to those that match the selector or pass the function's test.</summary> - /// <param name="function(index)" type="Function">A function used as a test for each element in the set. this is the current DOM element.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Reduce the set of matched elements to those that match the selector or pass the function's test.</summary> - /// <param name="element" type="Element">An element to match the current set of elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Reduce the set of matched elements to those that match the selector or pass the function's test.</summary> - /// <param name="jQuery object" type="Object">An existing jQuery object to match the current set of elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'find': function() { - /// <signature> - /// <summary>Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.</summary> - /// <param name="jQuery object" type="Object">A jQuery object to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.</summary> - /// <param name="element" type="Element">An element to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'finish': function() { - /// <signature> - /// <summary>Stop the currently-running animation, remove all queued animations, and complete all animations for the matched elements.</summary> - /// <param name="queue" type="String">The name of the queue in which to stop animations.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'first': function() { - /// <summary>Selects the first matched element.</summary> - }, - 'first-child': function() { - /// <summary>Selects all elements that are the first child of their parent.</summary> - }, - 'first-of-type': function() { - /// <summary>Selects all elements that are the first among siblings of the same element name.</summary> - }, - 'focus': function() { - /// <signature> - /// <summary>Bind an event handler to the "focus" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "focus" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'focusin': function() { - /// <signature> - /// <summary>Bind an event handler to the "focusin" event.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "focusin" event.</summary> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'focusout': function() { - /// <signature> - /// <summary>Bind an event handler to the "focusout" JavaScript event.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "focusout" JavaScript event.</summary> - /// <param name="eventData" type="Object">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'get': function() { - /// <signature> - /// <summary>Retrieve the DOM elements matched by the jQuery object.</summary> - /// <param name="index" type="Number">A zero-based integer indicating which element to retrieve.</param> - /// <returns type="Element, Array" /> - /// </signature> - }, - 'gt': function() { - /// <signature> - /// <summary>Select all elements at an index greater than index within the matched set.</summary> - /// <param name="index" type="Number">Zero-based index.</param> - /// </signature> - }, - 'has': function() { - /// <signature> - /// <summary>Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Reduce the set of matched elements to those that have a descendant that matches the selector or DOM element.</summary> - /// <param name="contained" type="Element">A DOM element to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'hasClass': function() { - /// <signature> - /// <summary>Determine whether any of the matched elements are assigned the given class.</summary> - /// <param name="className" type="String">The class name to search for.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'header': function() { - /// <summary>Selects all elements that are headers, like h1, h2, h3 and so on.</summary> - }, - 'height': function() { - /// <signature> - /// <summary>Set the CSS height of every matched element.</summary> - /// <param name="value" type="Number">An integer representing the number of pixels, or an integer with an optional unit of measure appended (as a string).</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set the CSS height of every matched element.</summary> - /// <param name="function(index, height)" type="Function">A function returning the height to set. Receives the index position of the element in the set and the old height as arguments. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'hidden': function() { - /// <summary>Selects all elements that are hidden.</summary> - }, - 'hide': function() { - /// <signature> - /// <summary>Hide the matched elements.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Hide the matched elements.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Hide the matched elements.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'hover': function() { - /// <signature> - /// <summary>Bind two handlers to the matched elements, to be executed when the mouse pointer enters and leaves the elements.</summary> - /// <param name="handlerIn(eventObject)" type="Function">A function to execute when the mouse pointer enters the element.</param> - /// <param name="handlerOut(eventObject)" type="Function">A function to execute when the mouse pointer leaves the element.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'html': function() { - /// <signature> - /// <summary>Set the HTML contents of each element in the set of matched elements.</summary> - /// <param name="htmlString" type="String">A string of HTML to set as the content of each matched element.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set the HTML contents of each element in the set of matched elements.</summary> - /// <param name="function(index, oldhtml)" type="Function">A function returning the HTML content to set. Receives the index position of the element in the set and the old HTML value as arguments. jQuery empties the element before calling the function; use the oldhtml argument to reference the previous content. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'id': function() { - /// <signature> - /// <summary>Selects a single element with the given id attribute.</summary> - /// <param name="id" type="String">An ID to search for, specified via the id attribute of an element.</param> - /// </signature> - }, - 'image': function() { - /// <summary>Selects all elements of type image.</summary> - }, - 'index': function() { - /// <signature> - /// <summary>Search for a given element from among the matched elements.</summary> - /// <param name="selector" type="String">A selector representing a jQuery collection in which to look for an element.</param> - /// <returns type="Number" /> - /// </signature> - /// <signature> - /// <summary>Search for a given element from among the matched elements.</summary> - /// <param name="element" type="jQuery">The DOM element or first element within the jQuery object to look for.</param> - /// <returns type="Number" /> - /// </signature> - }, - 'init': function() { - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="selector" type="String">A string containing a selector expression</param> - /// <param name="context" type="jQuery">A DOM Element, Document, or jQuery to use as context</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="element" type="Element">A DOM element to wrap in a jQuery object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="elementArray" type="Array">An array containing a set of DOM elements to wrap in a jQuery object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="object" type="PlainObject">A plain object to wrap in a jQuery object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="jQuery object" type="PlainObject">An existing jQuery object to clone.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'innerHeight': function() { - /// <summary>Get the current computed height for the first element in the set of matched elements, including padding but not border.</summary> - /// <returns type="Integer" /> - }, - 'innerWidth': function() { - /// <summary>Get the current computed width for the first element in the set of matched elements, including padding but not border.</summary> - /// <returns type="Integer" /> - }, - 'input': function() { - /// <summary>Selects all input, textarea, select and button elements.</summary> - }, - 'insertAfter': function() { - /// <signature> - /// <summary>Insert every element in the set of matched elements after the target.</summary> - /// <param name="target" type="jQuery">A selector, element, HTML string, or jQuery object; the matched set of elements will be inserted after the element(s) specified by this parameter.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'insertBefore': function() { - /// <signature> - /// <summary>Insert every element in the set of matched elements before the target.</summary> - /// <param name="target" type="jQuery">A selector, element, HTML string, or jQuery object; the matched set of elements will be inserted before the element(s) specified by this parameter.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'is': function() { - /// <signature> - /// <summary>Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="Boolean" /> - /// </signature> - /// <signature> - /// <summary>Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.</summary> - /// <param name="function(index)" type="Function">A function used as a test for the set of elements. It accepts one argument, index, which is the element's index in the jQuery collection.Within the function, this refers to the current DOM element.</param> - /// <returns type="Boolean" /> - /// </signature> - /// <signature> - /// <summary>Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.</summary> - /// <param name="jQuery object" type="Object">An existing jQuery object to match the current set of elements against.</param> - /// <returns type="Boolean" /> - /// </signature> - /// <signature> - /// <summary>Check the current matched set of elements against a selector, element, or jQuery object and return true if at least one of these elements matches the given arguments.</summary> - /// <param name="element" type="Element">An element to match the current set of elements against.</param> - /// <returns type="Boolean" /> - /// </signature> - }, - 'jquery': function() { - /// <summary>A string containing the jQuery version number.</summary> - /// <returns type="String" /> - }, - 'keydown': function() { - /// <signature> - /// <summary>Bind an event handler to the "keydown" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "keydown" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'keypress': function() { - /// <signature> - /// <summary>Bind an event handler to the "keypress" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "keypress" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'keyup': function() { - /// <signature> - /// <summary>Bind an event handler to the "keyup" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "keyup" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'lang': function() { - /// <signature> - /// <summary>Selects all elements of the specified language.</summary> - /// <param name="language" type="String">A language code.</param> - /// </signature> - }, - 'last': function() { - /// <summary>Selects the last matched element.</summary> - }, - 'last-child': function() { - /// <summary>Selects all elements that are the last child of their parent.</summary> - }, - 'last-of-type': function() { - /// <summary>Selects all elements that are the last among siblings of the same element name.</summary> - }, - 'length': function() { - /// <summary>The number of elements in the jQuery object.</summary> - /// <returns type="Number" /> - }, - 'live': function() { - /// <signature> - /// <summary>Attach an event handler for all elements which match the current selector, now and in the future.</summary> - /// <param name="events" type="String">A string containing a JavaScript event type, such as "click" or "keydown." As of jQuery 1.4 the string can contain multiple, space-separated event types or custom event names.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute at the time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach an event handler for all elements which match the current selector, now and in the future.</summary> - /// <param name="events" type="String">A string containing a JavaScript event type, such as "click" or "keydown." As of jQuery 1.4 the string can contain multiple, space-separated event types or custom event names.</param> - /// <param name="data" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute at the time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach an event handler for all elements which match the current selector, now and in the future.</summary> - /// <param name="events" type="PlainObject">A plain object of one or more JavaScript event types and functions to execute for them.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'load': function() { - /// <signature> - /// <summary>Bind an event handler to the "load" JavaScript event.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute when the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "load" JavaScript event.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'lt': function() { - /// <signature> - /// <summary>Select all elements at an index less than index within the matched set.</summary> - /// <param name="index" type="Number">Zero-based index.</param> - /// </signature> - }, - 'map': function() { - /// <signature> - /// <summary>Pass each element in the current matched set through a function, producing a new jQuery object containing the return values.</summary> - /// <param name="callback(index, domElement)" type="Function">A function object that will be invoked for each element in the current set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'mousedown': function() { - /// <signature> - /// <summary>Bind an event handler to the "mousedown" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "mousedown" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'mouseenter': function() { - /// <signature> - /// <summary>Bind an event handler to be fired when the mouse enters an element, or trigger that handler on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to be fired when the mouse enters an element, or trigger that handler on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'mouseleave': function() { - /// <signature> - /// <summary>Bind an event handler to be fired when the mouse leaves an element, or trigger that handler on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to be fired when the mouse leaves an element, or trigger that handler on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'mousemove': function() { - /// <signature> - /// <summary>Bind an event handler to the "mousemove" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "mousemove" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'mouseout': function() { - /// <signature> - /// <summary>Bind an event handler to the "mouseout" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "mouseout" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'mouseover': function() { - /// <signature> - /// <summary>Bind an event handler to the "mouseover" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "mouseover" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'mouseup': function() { - /// <signature> - /// <summary>Bind an event handler to the "mouseup" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "mouseup" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'multiple': function() { - /// <signature> - /// <summary>Selects the combined results of all the specified selectors.</summary> - /// <param name="selector1" type="String">Any valid selector.</param> - /// <param name="selector2" type="String">Another valid selector.</param> - /// <param name="selectorN" type="String">As many more valid selectors as you like.</param> - /// </signature> - }, - 'next': function() { - /// <signature> - /// <summary>Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'next adjacent': function() { - /// <signature> - /// <summary>Selects all next elements matching "next" that are immediately preceded by a sibling "prev".</summary> - /// <param name="prev" type="String">Any valid selector.</param> - /// <param name="next" type="String">A selector to match the element that is next to the first selector.</param> - /// </signature> - }, - 'next siblings': function() { - /// <signature> - /// <summary>Selects all sibling elements that follow after the "prev" element, have the same parent, and match the filtering "siblings" selector.</summary> - /// <param name="prev" type="String">Any valid selector.</param> - /// <param name="siblings" type="String">A selector to filter elements that are the following siblings of the first selector.</param> - /// </signature> - }, - 'nextAll': function() { - /// <signature> - /// <summary>Get all following siblings of each element in the set of matched elements, optionally filtered by a selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'nextUntil': function() { - /// <signature> - /// <summary>Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed.</summary> - /// <param name="selector" type="String">A string containing a selector expression to indicate where to stop matching following sibling elements.</param> - /// <param name="filter" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Get all following siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object passed.</summary> - /// <param name="element" type="Element">A DOM node or jQuery object indicating where to stop matching following sibling elements.</param> - /// <param name="filter" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'not': function() { - /// <signature> - /// <summary>Remove elements from the set of matched elements.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove elements from the set of matched elements.</summary> - /// <param name="elements" type="Array">One or more DOM elements to remove from the matched set.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove elements from the set of matched elements.</summary> - /// <param name="function(index)" type="Function">A function used as a test for each element in the set. this is the current DOM element.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove elements from the set of matched elements.</summary> - /// <param name="jQuery object" type="PlainObject">An existing jQuery object to match the current set of elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'nth-child': function() { - /// <signature> - /// <summary>Selects all elements that are the nth-child of their parent.</summary> - /// <param name="index" type="String">The index of each child to match, starting with 1, the string even or odd, or an equation ( eg. :nth-child(even), :nth-child(4n) )</param> - /// </signature> - }, - 'nth-last-child': function() { - /// <signature> - /// <summary>Selects all elements that are the nth-child of their parent, counting from the last element to the first.</summary> - /// <param name="index" type="String">The index of each child to match, starting with the last one (1), the string even or odd, or an equation ( eg. :nth-last-child(even), :nth-last-child(4n) )</param> - /// </signature> - }, - 'nth-last-of-type': function() { - /// <signature> - /// <summary>Selects all elements that are the nth-child of their parent, counting from the last element to the first.</summary> - /// <param name="index" type="String">The index of each child to match, starting with the last one (1), the string even or odd, or an equation ( eg. :nth-last-of-type(even), :nth-last-of-type(4n) )</param> - /// </signature> - }, - 'nth-of-type': function() { - /// <signature> - /// <summary>Selects all elements that are the nth child of their parent in relation to siblings with the same element name.</summary> - /// <param name="index" type="String">The index of each child to match, starting with 1, the string even or odd, or an equation ( eg. :nth-of-type(even), :nth-of-type(4n) )</param> - /// </signature> - }, - 'odd': function() { - /// <summary>Selects odd elements, zero-indexed. See also even.</summary> - }, - 'off': function() { - /// <signature> - /// <summary>Remove an event handler.</summary> - /// <param name="events" type="String">One or more space-separated event types and optional namespaces, or just namespaces, such as "click", "keydown.myPlugin", or ".myPlugin".</param> - /// <param name="selector" type="String">A selector which should match the one originally passed to .on() when attaching event handlers.</param> - /// <param name="handler(eventObject)" type="Function">A handler function previously attached for the event(s), or the special value false.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove an event handler.</summary> - /// <param name="events" type="PlainObject">An object where the string keys represent one or more space-separated event types and optional namespaces, and the values represent handler functions previously attached for the event(s).</param> - /// <param name="selector" type="String">A selector which should match the one originally passed to .on() when attaching event handlers.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'offset': function() { - /// <signature> - /// <summary>Set the current coordinates of every element in the set of matched elements, relative to the document.</summary> - /// <param name="coordinates" type="PlainObject">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" /> - /// </signature> - /// <signature> - /// <summary>Set the current coordinates of every element in the set of matched elements, relative to the document.</summary> - /// <param name="function(index, coords)" type="Function">A function to return the coordinates to set. Receives the index of the element in the collection as the first argument and the current coordinates as the second argument. The function should return an object with the new top and left properties.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'offsetParent': function() { - /// <summary>Get the closest ancestor element that is positioned.</summary> - /// <returns type="jQuery" /> - }, - 'on': function() { - /// <signature> - /// <summary>Attach an event handler function for one or more events to the selected elements.</summary> - /// <param name="events" type="String">One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin".</param> - /// <param name="selector" type="String">A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.</param> - /// <param name="data" type="Anything">Data to be passed to the handler in event.data when an event is triggered.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach an event handler function for one or more events to the selected elements.</summary> - /// <param name="events" type="PlainObject">An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s).</param> - /// <param name="selector" type="String">A selector string to filter the descendants of the selected elements that will call the handler. If the selector is null or omitted, the handler is always called when it reaches the selected element.</param> - /// <param name="data" type="Anything">Data to be passed to the handler in event.data when an event occurs.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'one': function() { - /// <signature> - /// <summary>Attach a handler to an event for the elements. The handler is executed at most once per element.</summary> - /// <param name="events" type="String">A string containing one or more JavaScript event types, such as "click" or "submit," or custom event names.</param> - /// <param name="data" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute at the time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach a handler to an event for the elements. The handler is executed at most once per element.</summary> - /// <param name="events" type="String">One or more space-separated event types and optional namespaces, such as "click" or "keydown.myPlugin".</param> - /// <param name="selector" type="String">A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.</param> - /// <param name="data" type="Anything">Data to be passed to the handler in event.data when an event is triggered.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute when the event is triggered. The value false is also allowed as a shorthand for a function that simply does return false.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Attach a handler to an event for the elements. The handler is executed at most once per element.</summary> - /// <param name="events" type="PlainObject">An object in which the string keys represent one or more space-separated event types and optional namespaces, and the values represent a handler function to be called for the event(s).</param> - /// <param name="selector" type="String">A selector string to filter the descendants of the selected elements that will call the handler. If the selector is null or omitted, the handler is always called when it reaches the selected element.</param> - /// <param name="data" type="Anything">Data to be passed to the handler in event.data when an event occurs.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'only-child': function() { - /// <summary>Selects all elements that are the only child of their parent.</summary> - }, - 'only-of-type': function() { - /// <summary>Selects all elements that have no siblings with the same element name.</summary> - }, - 'outerHeight': function() { - /// <signature> - /// <summary>Get the current computed height for the first element in the set of matched elements, including padding, border, and optionally margin. Returns an integer (without "px") representation of the value or null if called on an empty set of elements.</summary> - /// <param name="includeMargin" type="Boolean">A Boolean indicating whether to include the element's margin in the calculation.</param> - /// <returns type="Integer" /> - /// </signature> - }, - 'outerWidth': function() { - /// <signature> - /// <summary>Get the current computed width for the first element in the set of matched elements, including padding and border.</summary> - /// <param name="includeMargin" type="Boolean">A Boolean indicating whether to include the element's margin in the calculation.</param> - /// <returns type="Integer" /> - /// </signature> - }, - 'parent': function() { - /// <signature> - /// <summary>Get the parent of each element in the current set of matched elements, optionally filtered by a selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'parents': function() { - /// <signature> - /// <summary>Get the ancestors of each element in the current set of matched elements, optionally filtered by a selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'parentsUntil': function() { - /// <signature> - /// <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, DOM node, or jQuery object.</summary> - /// <param name="selector" type="String">A string containing a selector expression to indicate where to stop matching ancestor elements.</param> - /// <param name="filter" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <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, DOM node, or jQuery object.</summary> - /// <param name="element" type="Element">A DOM node or jQuery object indicating where to stop matching ancestor elements.</param> - /// <param name="filter" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'password': function() { - /// <summary>Selects all elements of type password.</summary> - }, - 'position': function() { - /// <summary>Get the current coordinates of the first element in the set of matched elements, relative to the offset parent.</summary> - /// <returns type="Object" /> - }, - 'prepend': function() { - /// <signature> - /// <summary>Insert content, specified by the parameter, to the beginning of each element in the set of matched elements.</summary> - /// <param name="content" type="jQuery">DOM element, array of elements, HTML string, or jQuery object to insert at the beginning of each element in the set of matched elements.</param> - /// <param name="content" type="jQuery">One or more additional DOM elements, arrays of elements, HTML strings, or jQuery objects to insert at the beginning of each element in the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Insert content, specified by the parameter, to the beginning of each element in the set of matched elements.</summary> - /// <param name="function(index, html)" type="Function">A function that returns an HTML string, DOM element(s), or jQuery object to insert at the beginning of each element in the set of matched elements. Receives the index position of the element in the set and the old HTML value of the element as arguments. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'prependTo': function() { - /// <signature> - /// <summary>Insert every element in the set of matched elements to the beginning of the target.</summary> - /// <param name="target" type="jQuery">A selector, element, HTML string, or jQuery object; the matched set of elements will be inserted at the beginning of the element(s) specified by this parameter.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'prev': function() { - /// <signature> - /// <summary>Get the immediately preceding sibling of each element in the set of matched elements, optionally filtered by a selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'prevAll': function() { - /// <signature> - /// <summary>Get all preceding siblings of each element in the set of matched elements, optionally filtered by a selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'prevUntil': function() { - /// <signature> - /// <summary>Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object.</summary> - /// <param name="selector" type="String">A string containing a selector expression to indicate where to stop matching preceding sibling elements.</param> - /// <param name="filter" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Get all preceding siblings of each element up to but not including the element matched by the selector, DOM node, or jQuery object.</summary> - /// <param name="element" type="Element">A DOM node or jQuery object indicating where to stop matching preceding sibling elements.</param> - /// <param name="filter" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'promise': function() { - /// <signature> - /// <summary>Return a Promise object to observe when all actions of a certain type bound to the collection, queued or not, have finished.</summary> - /// <param name="type" type="String">The type of queue that needs to be observed.</param> - /// <param name="target" type="PlainObject">Object onto which the promise methods have to be attached</param> - /// <returns type="Promise" /> - /// </signature> - }, - 'prop': function() { - /// <signature> - /// <summary>Set one or more properties for the set of matched elements.</summary> - /// <param name="propertyName" type="String">The name of the property to set.</param> - /// <param name="value" type="Boolean">A value to set for the property.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set one or more properties for the set of matched elements.</summary> - /// <param name="properties" type="PlainObject">An object of property-value pairs to set.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set one or more properties for the set of matched elements.</summary> - /// <param name="propertyName" type="String">The name of the property to set.</param> - /// <param name="function(index, oldPropertyValue)" type="Function">A function returning the value to set. Receives the index position of the element in the set and the old property value as arguments. Within the function, the keyword this refers to the current element.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'pushStack': function() { - /// <signature> - /// <summary>Add a collection of DOM elements onto the jQuery stack.</summary> - /// <param name="elements" type="Array">An array of elements to push onto the stack and make into a new jQuery object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Add a collection of DOM elements onto the jQuery stack.</summary> - /// <param name="elements" type="Array">An array of elements to push onto the stack and make into a new jQuery object.</param> - /// <param name="name" type="String">The name of a jQuery method that generated the array of elements.</param> - /// <param name="arguments" type="Array">The arguments that were passed in to the jQuery method (for serialization).</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'queue': function() { - /// <signature> - /// <summary>Manipulate the queue of functions to be executed, once for each matched element.</summary> - /// <param name="queueName" type="String">A string containing the name of the queue. Defaults to fx, the standard effects queue.</param> - /// <param name="newQueue" type="Array">An array of functions to replace the current queue contents.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Manipulate the queue of functions to be executed, once for each matched element.</summary> - /// <param name="queueName" type="String">A string containing the name of the queue. Defaults to fx, the standard effects queue.</param> - /// <param name="callback( next )" type="Function">The new function to add to the queue, with a function to call that will dequeue the next item.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'radio': function() { - /// <summary>Selects all elements of type radio.</summary> - }, - 'ready': function() { - /// <signature> - /// <summary>Specify a function to execute when the DOM is fully loaded.</summary> - /// <param name="handler" type="Function">A function to execute after the DOM is ready.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'remove': function() { - /// <signature> - /// <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" /> - /// </signature> - }, - 'removeAttr': function() { - /// <signature> - /// <summary>Remove an attribute from each element in the set of matched elements.</summary> - /// <param name="attributeName" type="String">An attribute to remove; as of version 1.7, it can be a space-separated list of attributes.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'removeClass': function() { - /// <signature> - /// <summary>Remove a single class, multiple classes, or all classes from each element in the set of matched elements.</summary> - /// <param name="className" type="String">One or more space-separated classes to be removed from the class attribute of each matched element.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove a single class, multiple classes, or all classes from each element in the set of matched elements.</summary> - /// <param name="function(index, class)" type="Function">A function returning one or more space-separated class names to be removed. Receives the index position of the element in the set and the old class value as arguments.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'removeData': function() { - /// <signature> - /// <summary>Remove a previously-stored piece of data.</summary> - /// <param name="name" type="String">A string naming the piece of data to delete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove a previously-stored piece of data.</summary> - /// <param name="list" type="String">An array or space-separated string naming the pieces of data to delete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'removeProp': function() { - /// <signature> - /// <summary>Remove a property for the set of matched elements.</summary> - /// <param name="propertyName" type="String">The name of the property to remove.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'replaceAll': function() { - /// <signature> - /// <summary>Replace each target element with the set of matched elements.</summary> - /// <param name="target" type="String">A selector expression indicating which element(s) to replace.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'replaceWith': function() { - /// <signature> - /// <summary>Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed.</summary> - /// <param name="newContent" type="jQuery">The content to insert. May be an HTML string, DOM element, or jQuery object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Replace each element in the set of matched elements with the provided new content and return the set of elements that was removed.</summary> - /// <param name="function" type="Function">A function that returns content with which to replace the set of matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'reset': function() { - /// <summary>Selects all elements of type reset.</summary> - }, - 'resize': function() { - /// <signature> - /// <summary>Bind an event handler to the "resize" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "resize" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'root': function() { - /// <signature> - /// <summary>Selects the element that is the root of the document.</summary> - /// <param name="index" type="String">The index of each child to match, starting with 1, the string even or odd, or an equation ( eg. :nth-last-child(even), :nth-last-child(4n) )</param> - /// </signature> - }, - 'scroll': function() { - /// <signature> - /// <summary>Bind an event handler to the "scroll" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "scroll" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'scrollLeft': function() { - /// <signature> - /// <summary>Set the current horizontal position of the scroll bar for each of the set of matched elements.</summary> - /// <param name="value" type="Number">An integer indicating the new position to set the scroll bar to.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'scrollTop': function() { - /// <signature> - /// <summary>Set the current vertical position of the scroll bar for each of the set of matched elements.</summary> - /// <param name="value" type="Number">An integer indicating the new position to set the scroll bar to.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'select': function() { - /// <signature> - /// <summary>Bind an event handler to the "select" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "select" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'selected': function() { - /// <summary>Selects all elements that are selected.</summary> - }, - 'selector': function() { - /// <summary>A selector representing selector originally passed to jQuery().</summary> - /// <returns type="String" /> - }, - 'serialize': function() { - /// <summary>Encode a set of form elements as a string for submission.</summary> - /// <returns type="String" /> - }, - 'serializeArray': function() { - /// <summary>Encode a set of form elements as an array of names and values.</summary> - /// <returns type="Array" /> - }, - 'show': function() { - /// <signature> - /// <summary>Display the matched elements.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display the matched elements.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display the matched elements.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'siblings': function() { - /// <signature> - /// <summary>Get the siblings of each element in the set of matched elements, optionally filtered by a selector.</summary> - /// <param name="selector" type="String">A string containing a selector expression to match elements against.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'size': function() { - /// <summary>Return the number of elements in the jQuery object.</summary> - /// <returns type="Number" /> - }, - 'slice': function() { - /// <signature> - /// <summary>Reduce the set of matched elements to a subset specified by a range of indices.</summary> - /// <param name="start" type="Number">An integer indicating the 0-based position at which the elements begin to be selected. If negative, it indicates an offset from the end of the set.</param> - /// <param name="end" type="Number">An integer indicating the 0-based position at which the elements stop being selected. If negative, it indicates an offset from the end of the set. If omitted, the range continues until the end of the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'slideDown': function() { - /// <signature> - /// <summary>Display the matched elements with a sliding motion.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display the matched elements with a sliding motion.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display the matched elements with a sliding motion.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'slideToggle': function() { - /// <signature> - /// <summary>Display or hide the matched elements with a sliding motion.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display or hide the matched elements with a sliding motion.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display or hide the matched elements with a sliding motion.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'slideUp': function() { - /// <signature> - /// <summary>Hide the matched elements with a sliding motion.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Hide the matched elements with a sliding motion.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Hide the matched elements with a sliding motion.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'stop': function() { - /// <signature> - /// <summary>Stop the currently-running animation on the matched elements.</summary> - /// <param name="clearQueue" type="Boolean">A Boolean indicating whether to remove queued animation as well. Defaults to false.</param> - /// <param name="jumpToEnd" type="Boolean">A Boolean indicating whether to complete the current animation immediately. Defaults to false.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Stop the currently-running animation on the matched elements.</summary> - /// <param name="queue" type="String">The name of the queue in which to stop animations.</param> - /// <param name="clearQueue" type="Boolean">A Boolean indicating whether to remove queued animation as well. Defaults to false.</param> - /// <param name="jumpToEnd" type="Boolean">A Boolean indicating whether to complete the current animation immediately. Defaults to false.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'submit': function() { - /// <signature> - /// <summary>Bind an event handler to the "submit" JavaScript event, or trigger that event on an element.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "submit" JavaScript event, or trigger that event on an element.</summary> - /// <param name="eventData" type="PlainObject">An object containing data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'target': function() { - /// <summary>Selects the target element indicated by the fragment identifier of the document's URI.</summary> - }, - 'text': function() { - /// <signature> - /// <summary>Set the content of each element in the set of matched elements to the specified text.</summary> - /// <param name="textString" type="String">A string of text to set as the content of each matched element.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set the content of each element in the set of matched elements to the specified text.</summary> - /// <param name="function(index, text)" type="Function">A function returning the text content to set. Receives the index position of the element in the set and the old text value as arguments.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'toArray': function() { - /// <summary>Retrieve all the DOM elements contained in the jQuery set, as an array.</summary> - /// <returns type="Array" /> - }, - 'toggle': function() { - /// <signature> - /// <summary>Display or hide the matched elements.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display or hide the matched elements.</summary> - /// <param name="options" type="PlainObject">A map of additional options to pass to the method.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display or hide the matched elements.</summary> - /// <param name="duration" type="">A string or number determining how long the animation will run.</param> - /// <param name="easing" type="String">A string indicating which easing function to use for the transition.</param> - /// <param name="complete" type="Function">A function to call once the animation is complete.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Display or hide the matched elements.</summary> - /// <param name="showOrHide" type="Boolean">A Boolean indicating whether to show or hide the elements.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'toggleClass': function() { - /// <signature> - /// <summary>Add or remove one or more classes 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="className" type="String">One or more class names (separated by spaces) to be toggled for each element in the matched set.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Add or remove one or more classes 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="className" type="String">One or more class names (separated by spaces) to be toggled for each element in the matched set.</param> - /// <param name="switch" type="Boolean">A Boolean (not just truthy/falsy) value to determine whether the class should be added or removed.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Add or remove one or more classes 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="switch" type="Boolean">A boolean value to determine whether the class should be added or removed.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Add or remove one or more classes 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="function(index, class, switch)" type="Function">A function that returns class names to be toggled in the class attribute of each element in the matched set. Receives the index position of the element in the set, the old class value, and the switch as arguments.</param> - /// <param name="switch" type="Boolean">A boolean value to determine whether the class should be added or removed.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'trigger': function() { - /// <signature> - /// <summary>Execute all handlers and behaviors attached to the matched elements for the given event type.</summary> - /// <param name="eventType" type="String">A string containing a JavaScript event type, such as click or submit.</param> - /// <param name="extraParameters" type="PlainObject">Additional parameters to pass along to the event handler.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Execute all handlers and behaviors attached to the matched elements for the given event type.</summary> - /// <param name="event" type="Event">A jQuery.Event object.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'triggerHandler': function() { - /// <signature> - /// <summary>Execute all handlers attached to an element for an event.</summary> - /// <param name="eventType" type="String">A string containing a JavaScript event type, such as click or submit.</param> - /// <param name="extraParameters" type="Array">An array of additional parameters to pass along to the event handler.</param> - /// <returns type="Object" /> - /// </signature> - }, - 'unbind': function() { - /// <signature> - /// <summary>Remove a previously-attached event handler from the elements.</summary> - /// <param name="eventType" type="String">A string containing a JavaScript event type, such as click or submit.</param> - /// <param name="handler(eventObject)" type="Function">The function that is to be no longer executed.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove a previously-attached event handler from the elements.</summary> - /// <param name="eventType" type="String">A string containing a JavaScript event type, such as click or submit.</param> - /// <param name="false" type="Boolean">Unbinds the corresponding 'return false' function that was bound using .bind( eventType, false ).</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove a previously-attached event handler from the elements.</summary> - /// <param name="event" type="Object">A JavaScript event object as passed to an event handler.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'undelegate': function() { - /// <signature> - /// <summary>Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements.</summary> - /// <param name="selector" type="String">A selector which will be used to filter the event results.</param> - /// <param name="eventType" type="String">A string containing a JavaScript event type, such as "click" or "keydown"</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements.</summary> - /// <param name="selector" type="String">A selector which will be used to filter the event results.</param> - /// <param name="eventType" type="String">A string containing a JavaScript event type, such as "click" or "keydown"</param> - /// <param name="handler(eventObject)" type="Function">A function to execute at the time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements.</summary> - /// <param name="selector" type="String">A selector which will be used to filter the event results.</param> - /// <param name="events" type="PlainObject">An object of one or more event types and previously bound functions to unbind from them.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Remove a handler from the event for all elements which match the current selector, based upon a specific set of root elements.</summary> - /// <param name="namespace" type="String">A string containing a namespace to unbind all events from.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'unload': function() { - /// <signature> - /// <summary>Bind an event handler to the "unload" JavaScript event.</summary> - /// <param name="handler(eventObject)" type="Function">A function to execute when the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Bind an event handler to the "unload" JavaScript event.</summary> - /// <param name="eventData" type="Object">A plain object of data that will be passed to the event handler.</param> - /// <param name="handler(eventObject)" type="Function">A function to execute each time the event is triggered.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - '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" /> - }, - 'val': function() { - /// <signature> - /// <summary>Set the value of each element in the set of matched elements.</summary> - /// <param name="value" type="Array">A string of text or an array of strings corresponding to the value of each matched element to set as selected/checked.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set the value of each element in the set of matched elements.</summary> - /// <param name="function(index, value)" type="Function">A function returning the value to set. this is the current element. Receives the index position of the element in the set and the old value as arguments.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'visible': function() { - /// <summary>Selects all elements that are visible.</summary> - }, - 'width': function() { - /// <signature> - /// <summary>Set the CSS width of each element in the set of matched elements.</summary> - /// <param name="value" type="Number">An integer representing the number of pixels, or an integer along with an optional unit of measure appended (as a string).</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Set the CSS width of each element in the set of matched elements.</summary> - /// <param name="function(index, width)" type="Function">A function returning the width to set. Receives the index position of the element in the set and the old width as arguments. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'wrap': function() { - /// <signature> - /// <summary>Wrap an HTML structure around each element in the set of matched elements.</summary> - /// <param name="wrappingElement" type="jQuery">An HTML snippet, selector expression, jQuery object, or DOM element specifying the structure to wrap around the matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Wrap an HTML structure around each element in the set of matched elements.</summary> - /// <param name="function(index)" type="Function">A callback function returning the HTML content or jQuery object to wrap around the matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'wrapAll': function() { - /// <signature> - /// <summary>Wrap an HTML structure around all elements in the set of matched elements.</summary> - /// <param name="wrappingElement" type="jQuery">An HTML snippet, selector expression, jQuery object, or DOM element specifying the structure to wrap around the matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - }, - 'wrapInner': function() { - /// <signature> - /// <summary>Wrap an HTML structure around the content of each element in the set of matched elements.</summary> - /// <param name="wrappingElement" type="String">An HTML snippet, selector expression, jQuery object, or DOM element specifying the structure to wrap around the content of the matched elements.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Wrap an HTML structure around the content of each element in the set of matched elements.</summary> - /// <param name="function(index)" type="Function">A callback function which generates a structure to wrap around the content of the matched elements. Receives the index position of the element in the set as an argument. Within the function, this refers to the current element in the set.</param> - /// <returns type="jQuery" /> - /// </signature> - }, -}); - -intellisense.annotate(window, { - '$': function() { - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="selector" type="String">A string containing a selector expression</param> - /// <param name="context" type="jQuery">A DOM Element, Document, or jQuery to use as context</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="element" type="Element">A DOM element to wrap in a jQuery object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="elementArray" type="Array">An array containing a set of DOM elements to wrap in a jQuery object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="object" type="PlainObject">A plain object to wrap in a jQuery object.</param> - /// <returns type="jQuery" /> - /// </signature> - /// <signature> - /// <summary>Accepts a string containing a CSS selector which is then used to match a set of elements.</summary> - /// <param name="jQuery object" type="PlainObject">An existing jQuery object to clone.</param> - /// <returns type="jQuery" /> - /// </signature> - }, -}); - diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.js deleted file mode 100644 index d3e121b8602e2bfbed5d2b1fa960d09b8e7bf153..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.js +++ /dev/null @@ -1,9803 +0,0 @@ -/* NUGET: BEGIN LICENSE TEXT - * - * Microsoft grants you the right to use these script files for the sole - * purpose of either: (i) interacting through your browser with the Microsoft - * website or online service, subject to the applicable licensing or use - * terms; or (ii) using the files as included with a Microsoft product subject - * to that product's license terms. Microsoft reserves all other rights to the - * files not expressly granted by Microsoft, whether by implication, estoppel - * or otherwise. Insofar as a script file is dual licensed under GPL, - * Microsoft neither took the code under GPL nor distributes it thereunder but - * under the terms set out in this paragraph. All notices and licenses - * below are for informational purposes only. - * - * NUGET: END LICENSE TEXT */ -/*! - * jQuery JavaScript Library v1.10.2 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2013-07-03T13:48Z - */ -(function( window, undefined ) { - -// Can't do this because several apps including ASP.NET trace -// the stack via arguments.caller.callee and Firefox dies if -// you try to trace through "use strict" call chains. (#13335) -// Support: Firefox 18+ -//"use strict"; -var - // The deferred used on DOM ready - readyList, - - // A central reference to the root jQuery(document) - rootjQuery, - - // Support: IE<10 - // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` - core_strundefined = typeof undefined, - - // Use the correct document accordingly with window argument (sandbox) - location = window.location, - document = window.document, - docElem = document.documentElement, - - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - - // Map over the $ in case of overwrite - _$ = window.$, - - // [[Class]] -> type pairs - class2type = {}, - - // List of deleted data cache ids, so we can reuse them - core_deletedIds = [], - - core_version = "1.10.2", - - // Save a reference to some core methods - core_concat = core_deletedIds.concat, - core_push = core_deletedIds.push, - core_slice = core_deletedIds.slice, - core_indexOf = core_deletedIds.indexOf, - core_toString = class2type.toString, - core_hasOwn = class2type.hasOwnProperty, - core_trim = core_version.trim, - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context, rootjQuery ); - }, - - // Used for matching numbers - core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, - - // Used for splitting on whitespace - core_rnotwhite = /\S+/g, - - // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // A simple way to check for HTML strings - // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - // Match a standalone tag - rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, - - // JSON RegExp - rvalidchars = /^[\],:{}\s]*$/, - rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, - rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, - rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([\da-z])/gi, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }, - - // The ready event handler - completed = function( event ) { - - // readyState === "complete" is good enough for us to call the dom ready in oldIE - if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { - detach(); - jQuery.ready(); - } - }, - // Clean-up method for dom ready events - detach = function() { - if ( document.addEventListener ) { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); - - } else { - document.detachEvent( "onreadystatechange", completed ); - window.detachEvent( "onload", completed ); - } - }; - -jQuery.fn = jQuery.prototype = { - // The current version of jQuery being used - jquery: core_version, - - constructor: jQuery, - init: function( selector, context, rootjQuery ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - 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 = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - - // scripts is true for back-compat - jQuery.merge( this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // 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: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - - // 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 default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return core_slice.call( this ); - }, - - // 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 ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - - // 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 ) { - // Add the callback - jQuery.ready.promise().done( fn ); - - return this; - }, - - slice: function() { - return this.pushStack( core_slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); - }, - - 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: core_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 src, copyIsArray, copy, name, options, 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({ - // Unique for each copy of jQuery on the page - // Non-digits removed to match rinlinejQuery - expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), - - 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 ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready ); - } - - // 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").off("ready"); - } - }, - - // 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"; - }, - - isWindow: function( obj ) { - /* jshint eqeqeq: false */ - return obj != null && obj == obj.window; - }, - - isNumeric: function( obj ) { - return !isNaN( parseFloat(obj) ) && isFinite( obj ); - }, - - type: function( obj ) { - if ( obj == null ) { - return String( obj ); - } - return typeof obj === "object" || typeof obj === "function" ? - class2type[ core_toString.call(obj) ] || "object" : - typeof obj; - }, - - isPlainObject: function( obj ) { - var key; - - // 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; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !core_hasOwn.call(obj, "constructor") && - !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Support: IE<9 - // Handle iteration over inherited properties before own properties. - if ( jQuery.support.ownLast ) { - for ( key in obj ) { - return core_hasOwn.call( obj, key ); - } - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - for ( key in obj ) {} - - return key === undefined || core_hasOwn.call( obj, key ); - }, - - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - error: function( msg ) { - throw new Error( msg ); - }, - - // data: string of html - // context (optional): If specified, the fragment will be created in this context, defaults to document - // keepScripts (optional): If true, will include scripts passed in the html string - parseHTML: function( data, context, keepScripts ) { - if ( !data || typeof data !== "string" ) { - return null; - } - if ( typeof context === "boolean" ) { - keepScripts = context; - context = false; - } - context = context || document; - - var parsed = rsingleTag.exec( data ), - scripts = !keepScripts && []; - - // Single tag - if ( parsed ) { - return [ context.createElement( parsed[1] ) ]; - } - - parsed = jQuery.buildFragment( [ data ], context, scripts ); - if ( scripts ) { - jQuery( scripts ).remove(); - } - return jQuery.merge( [], parsed.childNodes ); - }, - - parseJSON: function( data ) { - // Attempt to parse using the native JSON parser first - if ( window.JSON && window.JSON.parse ) { - return window.JSON.parse( data ); - } - - if ( data === null ) { - return data; - } - - if ( typeof data === "string" ) { - - // Make sure leading/trailing whitespace is removed (IE can't handle it) - data = jQuery.trim( data ); - - if ( 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 - parseXML: function( data ) { - var xml, tmp; - if ( !data || typeof data !== "string" ) { - return null; - } - try { - 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 ); - } - } catch( e ) { - xml = undefined; - } - if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { - 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 && jQuery.trim( 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 ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); - - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } - } - - return obj; - }, - - // Use native String.trim function wherever possible - trim: core_trim && !core_trim.call("\uFEFF\xA0") ? - function( text ) { - return text == null ? - "" : - core_trim.call( text ); - } : - - // Otherwise use our own trimming functionality - function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - core_push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - var len; - - if ( arr ) { - if ( core_indexOf ) { - return core_indexOf.call( arr, elem, i ); - } - - len = arr.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in arr && arr[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - merge: function( first, second ) { - var l = second.length, - i = first.length, - j = 0; - - if ( typeof l === "number" ) { - for ( ; 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 retVal, - ret = [], - i = 0, - length = elems.length; - inv = !!inv; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; 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, - i = 0, - length = elems.length, - isArray = isArraylike( elems ), - ret = []; - - // 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 ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret[ ret.length ] = value; - } - } - } - - // Flatten any nested arrays - return core_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 ) { - var args, proxy, tmp; - - if ( typeof context === "string" ) { - 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 - args = core_slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( core_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 || jQuery.guid++; - - return proxy; - }, - - // Multifunctional method to get and set values of a collection - // The value/s can optionally be executed if it's a function - access: function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - length = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < length; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - length ? fn( elems[0], key ) : emptyGet; - }, - - now: function() { - return ( new Date() ).getTime(); - }, - - // A method for quickly swapping in/out CSS properties to get correct calculations. - // Note: this method belongs to the css module but it's needed here for the support module. - // If support gets modularized, this method should be moved back to the css module. - swap: function( elem, options, callback, args ) { - var ret, name, - old = {}; - - // Remember the old values, and insert the new ones - for ( name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - ret = callback.apply( elem, args || [] ); - - // Revert the old values - for ( name in options ) { - elem.style[ name ] = old[ name ]; - } - - return ret; - } -}); - -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { - - readyList = jQuery.Deferred(); - - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // we once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); - - // Standards-based browsers support DOMContentLoaded - } else if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); - - // If IE event model is used - } else { - // Ensure firing before onload, maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", completed ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", completed ); - - // If IE and not a frame - // continually check to see if the document is ready - var top = false; - - try { - top = window.frameElement == null && document.documentElement; - } catch(e) {} - - if ( top && top.doScroll ) { - (function doScrollCheck() { - if ( !jQuery.isReady ) { - - try { - // Use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - top.doScroll("left"); - } catch(e) { - return setTimeout( doScrollCheck, 50 ); - } - - // detach all dom ready events - detach(); - - // and execute any waiting functions - jQuery.ready(); - } - })(); - } - } - } - return readyList.promise( obj ); -}; - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -function isArraylike( obj ) { - var length = obj.length, - type = jQuery.type( obj ); - - if ( jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.nodeType === 1 && length ) { - return true; - } - - return type === "array" || type !== "function" && - ( length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj ); -} - -// All jQuery objects should point back to these -rootjQuery = jQuery(document); -/*! - * Sizzle CSS Selector Engine v1.10.2 - * http://sizzlejs.com/ - * - * Copyright 2013 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2013-07-03 - */ -(function( window, undefined ) { - -var i, - support, - cachedruns, - Expr, - getText, - isXML, - compile, - outermostContext, - sortInput, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + -(new Date()), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - hasDuplicate = false, - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - return 0; - } - return 0; - }, - - // General-purpose constants - strundefined = typeof undefined, - MAX_NEGATIVE = 1 << 31, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf if we can't use a native one - indexOf = arr.indexOf || function( elem ) { - var i = 0, - len = this.length; - for ( ; i < len; i++ ) { - if ( this[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/css3-syntax/#characters - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - - // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors - // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = characterEncoding.replace( "w", "w#" ), - - // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + - "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", - - // Prefer arguments quoted, - // then not containing pseudos/brackets, - // then attribute selectors/non-parenthetical expressions, - // then anything else - // These preferences are here to reduce the number of selectors - // needing tokenize in the PSEUDO preFilter - pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rsibling = new RegExp( whitespace + "*[+~]" ), - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rescape = /'|\\/g, - - // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - // BMP codepoint - high < 0 ? - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }; - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - // QSA vars - i, groups, old, nid, newContext, newSelector; - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - - context = context || document; - results = results || []; - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { - return []; - } - - if ( documentIsHTML && !seed ) { - - // Shortcuts - if ( (match = rquickExpr.exec( selector )) ) { - // Speed-up: Sizzle("#ID") - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - // 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, Opera, and Webkit return items - // by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - } else { - // Context is not a document - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; - } - } - - // Speed-up: Sizzle("TAG") - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // QSA path - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType === 9 && selector; - - // 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 - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); - - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; - - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); - } - newContext = rsibling.test( selector ) && context.parentNode || context; - newSelector = groups.join(","); - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key += " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result - */ -function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - // release memory in IE - div = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = attrs.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); -} - -/** - * Detect xml - * @param {Element|Object} elem An element or a document - */ -isXML = 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).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var doc = node ? node.ownerDocument || node : preferredDoc, - parent = doc.defaultView; - - // If no document and documentElement is available, return - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Set our document - document = doc; - docElem = doc.documentElement; - - // Support tests - documentIsHTML = !isXML( doc ); - - // Support: IE>8 - // If iframe document is assigned to "document" variable and if iframe has been reloaded, - // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 - // IE6-8 do not support the defaultView property so parent will be undefined - if ( parent && parent.attachEvent && parent !== parent.top ) { - parent.attachEvent( "onbeforeunload", function() { - setDocument(); - }); - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) - support.attributes = assert(function( div ) { - div.className = "i"; - return !div.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( div ) { - div.appendChild( doc.createComment("") ); - return !div.getElementsByTagName("*").length; - }); - - // Check if getElementsByClassName can be trusted - support.getElementsByClassName = assert(function( div ) { - div.innerHTML = "<div class='a'></div><div class='a i'></div>"; - - // Support: Safari<4 - // Catch class over-caching - div.firstChild.className = "i"; - // Support: Opera<10 - // Catch gEBCN failure to find non-leading classes - return div.getElementsByClassName("i").length === 2; - }); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function( div ) { - docElem.appendChild( div ).id = expando; - return !doc.getElementsByName || !doc.getElementsByName( expando ).length; - }); - - // ID find and filter - if ( support.getById ) { - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== strundefined && documentIsHTML ) { - var m = context.getElementById( id ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [m] : []; - } - }; - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - } else { - // Support: IE6/7 - // getElementById is not reliable as a find shortcut - delete Expr.find["ID"]; - - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== strundefined ) { - return context.getElementsByTagName( tag ); - } - } : - function( tag, context ) { - var elem, - tmp = [], - i = 0, - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See http://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function( div ) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // http://bugs.jquery.com/ticket/12359 - div.innerHTML = "<select><option selected=''></option></select>"; - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !div.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - }); - - assert(function( div ) { - - // Support: Opera 10-12/IE8 - // ^= $= *= and empty values - // Should not select anything - // Support: Windows 8 Native Apps - // The type attribute is restricted during .innerHTML assignment - var input = doc.createElement("input"); - input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "t", "" ); - - if ( div.querySelectorAll("[t^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":enabled").length ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - div.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( div ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( div, "div" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( div, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - - // Element contains another - // Purposefully does not implement inclusive descendent - // As in, an element does not contain itself - contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = docElem.compareDocumentPosition ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); - - if ( compare ) { - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === doc || contains(preferredDoc, a) ) { - return -1; - } - if ( b === doc || contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } - - // Not directly comparable, sort on existence of method - return a.compareDocumentPosition ? -1 : 1; - } : - function( a, b ) { - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - - // Parentless nodes are either documents or disconnected - } else if ( !aup || !bup ) { - return a === doc ? -1 : - b === doc ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return doc; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch(e) {} - } - - return Sizzle( expr, document, null, [elem] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val === undefined ? - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null : - val; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - // If no nodeType, this is expected to be an array - for ( ; (node = elem[i]); i++ ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (see #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[5] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[3] && match[4] !== undefined ) { - match[2] = match[4]; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, outerCache, node, diff, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - // Seek `elem` from a previously-cached index - outerCache = parent[ expando ] || (parent[ expando ] = {}); - cache = outerCache[ type ] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = cache[0] === dirruns && cache[2]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - // Use previously-cached element index if available - } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { - diff = cache[1]; - - // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) - } else { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { - // Cache the index of each encountered element - if ( useCache ) { - (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf.call( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function( selector ) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": function( elem ) { - return elem.disabled === false; - }, - - "disabled": function( elem ) { - return elem.disabled === true; - }, - - "checked": function( elem ) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "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; - }, - - // Contents - "empty": function( elem ) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), - // not comment, processing instructions, or others - // Thanks to Diego Perini for the nodeName shortcut - // Greater than "@" means alpha characters (specifically not starting with "#" or "?") - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - // 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" && - elem.type === "text" && - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); - }, - - // Position-in-collection - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } -}; - -Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -function tokenize( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( tokens = [] ); - } - - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -} - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - checkNonElements = base && dir === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var data, cache, outerCache, - dirkey = dirruns + " " + doneName; - - // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { - if ( (data = cache[1]) === true || data === cachedruns ) { - return data === true; - } - } else { - cache = outerCache[ dir ] = [ dirkey ]; - cache[1] = matcher( elem, context, xml ) || cachedruns; - if ( cache[1] === true ) { - return true; - } - } - } - } - } - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf.call( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - // A counter to specify which element is currently being matched - var matcherCachedRuns = 0, - bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, expandContext ) { - var elem, j, matcher, - setMatched = [], - matchedCount = 0, - i = "0", - unmatched = seed && [], - outermost = expandContext != null, - contextBackup = outermostContext, - // We must always have either seed elements or context - elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); - - if ( outermost ) { - outermostContext = context !== document && context; - cachedruns = matcherCachedRuns; - } - - // Add elements passing elementMatchers directly to results - // Keep `i` a string if there are no elements so `matchedCount` will be "00" below - for ( ; (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - cachedruns = ++matcherCachedRuns; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // Apply set filters to unmatched elements - matchedCount += i; - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - // Generate a function of recursive functions that can be used to check each element - if ( !group ) { - group = tokenize( selector ); - } - i = group.length; - while ( i-- ) { - cached = matcherFromTokens( group[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - } - return cached; -}; - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; -} - -function select( selector, context, results, seed ) { - var i, tokens, token, type, find, - match = tokenize( selector ); - - if ( !seed ) { - // Try to minimize operations if there is only one group - if ( match.length === 1 ) { - - // Take a shortcut and set the context if the root selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - support.getById && context.nodeType === 9 && documentIsHTML && - Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - } - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && context.parentNode || context - )) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - } - - // Compile and execute a filtering function - // Provide `match` to avoid retokenization if we modified the selector above - compile( selector, match )( - seed, - context, - !documentIsHTML, - results, - rsibling.test( selector ) - ); - return results; -} - -// One-time assignments - -// Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; - -// Support: Chrome<14 -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( div1 ) { - // Should return 1, but returns 4 (following) - return div1.compareDocumentPosition( document.createElement("div") ) & 1; -}); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( div ) { - div.innerHTML = "<a href='#'></a>"; - return div.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( div ) { - div.innerHTML = "<input/>"; - div.firstChild.setAttribute( "value", "" ); - return div.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( div ) { - return div.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - elem[ name ] === true ? name.toLowerCase() : null; - } - }); -} - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.pseudos; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - -})( window ); -// String to Object options format cache -var optionsCache = {}; - -// Convert String-formatted options into Object-formatted ones and store in cache -function createOptions( options ) { - var object = optionsCache[ options ] = {}; - jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { - object[ flag ] = true; - }); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - ( optionsCache[ options ] || createOptions( options ) ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list was already fired - fired, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // First callback to fire (used internally by add and fireWith) - firingStart, - // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = !options.once && [], - // Fire callbacks - fire = function( data ) { - memory = options.memory && data; - fired = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - firing = true; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { - memory = false; // To prevent further calls using add - break; - } - } - firing = false; - if ( list ) { - if ( stack ) { - if ( stack.length ) { - fire( stack.shift() ); - } - } else if ( memory ) { - list = []; - } else { - self.disable(); - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - // First, we save the current length - var start = list.length; - (function add( args ) { - jQuery.each( args, function( _, arg ) { - var type = jQuery.type( arg ); - if ( type === "function" ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && type !== "string" ) { - // Inspect recursively - add( arg ); - } - }); - })( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away - } else if ( memory ) { - firingStart = start; - fire( memory ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - jQuery.each( arguments, function( _, arg ) { - var index; - while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - // Handle firing indexes - if ( firing ) { - if ( index <= firingLength ) { - firingLength--; - } - if ( index <= firingIndex ) { - firingIndex--; - } - } - } - }); - } - return this; - }, - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); - }, - // Remove all callbacks from the list - empty: function() { - list = []; - firingLength = 0; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( list && ( !fired || stack ) ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - if ( firing ) { - stack.push( args ); - } else { - fire( args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; -jQuery.extend({ - - Deferred: function( func ) { - var tuples = [ - // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], - [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], - [ "notify", "progress", jQuery.Callbacks("memory") ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - then: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - return jQuery.Deferred(function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var action = tuple[ 0 ], - fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ](function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); - } - }); - }); - fns = null; - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 3 ]; - - // promise[ done | fail | progress ] = list.add - promise[ tuple[1] ] = list.add; - - // Handle state - if ( stateString ) { - list.add(function() { - // state = [ resolved | rejected ] - state = stateString; - - // [ reject_list | resolve_list ].disable; progress_list.lock - }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); - } - - // deferred[ resolve | reject | notify ] - deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); - return this; - }; - deferred[ tuple[0] + "With" ] = list.fireWith; - }); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( subordinate /* , ..., subordinateN */ ) { - var i = 0, - resolveValues = core_slice.call( arguments ), - length = resolveValues.length, - - // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - - // the master Deferred. If resolveValues consist of only a single Deferred, just use that. - deferred = remaining === 1 ? subordinate : jQuery.Deferred(), - - // Update function for both resolve and progress values - updateFunc = function( i, contexts, values ) { - return function( value ) { - contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; - if( values === progressValues ) { - deferred.notifyWith( contexts, values ); - } else if ( !( --remaining ) ) { - deferred.resolveWith( contexts, values ); - } - }; - }, - - progressValues, progressContexts, resolveContexts; - - // add listeners to Deferred subordinates; treat others as resolved - if ( length > 1 ) { - progressValues = new Array( length ); - progressContexts = new Array( length ); - resolveContexts = new Array( length ); - for ( ; i < length; i++ ) { - if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { - resolveValues[ i ].promise() - .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ) - .progress( updateFunc( i, progressContexts, progressValues ) ); - } else { - --remaining; - } - } - } - - // if we're not waiting on anything, resolve the master - if ( !remaining ) { - deferred.resolveWith( resolveContexts, resolveValues ); - } - - return deferred.promise(); - } -}); -jQuery.support = (function( support ) { - - var all, a, input, select, fragment, opt, eventName, isSupported, i, - div = document.createElement("div"); - - // Setup - div.setAttribute( "className", "t" ); - div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; - - // Finish early in limited (non-browser) environments - all = div.getElementsByTagName("*") || []; - a = div.getElementsByTagName("a")[ 0 ]; - if ( !a || !a.style || !all.length ) { - return support; - } - - // First batch of tests - select = document.createElement("select"); - opt = select.appendChild( document.createElement("option") ); - input = div.getElementsByTagName("input")[ 0 ]; - - a.style.cssText = "top:1px;float:left;opacity:.5"; - - // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) - support.getSetAttribute = div.className !== "t"; - - // IE strips leading whitespace when .innerHTML is used - support.leadingWhitespace = div.firstChild.nodeType === 3; - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - support.tbody = !div.getElementsByTagName("tbody").length; - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - support.htmlSerialize = !!div.getElementsByTagName("link").length; - - // Get the style information from getAttribute - // (IE uses .cssText instead) - support.style = /top/.test( a.getAttribute("style") ); - - // Make sure that URLs aren't manipulated - // (IE normalizes it by default) - support.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 - support.opacity = /^0.5/.test( a.style.opacity ); - - // Verify style float existence - // (IE uses styleFloat instead of cssFloat) - support.cssFloat = !!a.style.cssFloat; - - // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) - support.checkOn = !!input.value; - - // 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) - support.optSelected = opt.selected; - - // Tests for enctype support on a form (#6743) - support.enctype = !!document.createElement("form").enctype; - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>"; - - // Will be defined later - support.inlineBlockNeedsLayout = false; - support.shrinkWrapBlocks = false; - support.pixelPosition = false; - support.deleteExpando = true; - support.noCloneEvent = true; - support.reliableMarginRight = true; - support.boxSizingReliable = 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; - - // Support: IE<9 - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - - // Check if we can trust getAttribute("value") - input = document.createElement("input"); - input.setAttribute( "value", "" ); - support.input = input.getAttribute( "value" ) === ""; - - // Check if an input maintains its value after becoming a radio - input.value = "t"; - input.setAttribute( "type", "radio" ); - support.radioValue = input.value === "t"; - - // #11217 - WebKit loses check when the name is after the checked attribute - input.setAttribute( "checked", "t" ); - input.setAttribute( "name", "t" ); - - fragment = document.createDocumentFragment(); - fragment.appendChild( input ); - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - support.appendChecked = input.checked; - - // WebKit doesn't clone checked state correctly in fragments - support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE<9 - // Opera does not clone events (and typeof div.attachEvent === undefined). - // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() - if ( div.attachEvent ) { - div.attachEvent( "onclick", function() { - support.noCloneEvent = false; - }); - - div.cloneNode( true ).click(); - } - - // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) - // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) - for ( i in { submit: true, change: true, focusin: true }) { - div.setAttribute( eventName = "on" + i, "t" ); - - support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; - } - - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - - // Support: IE<9 - // Iteration over object's inherited properties before its own. - for ( i in jQuery( support ) ) { - break; - } - support.ownLast = i !== "0"; - - // Run tests that need a body at doc ready - jQuery(function() { - var container, marginDiv, tds, - divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", - body = document.getElementsByTagName("body")[0]; - - if ( !body ) { - // Return for frameset docs that don't have a body - return; - } - - container = document.createElement("div"); - container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; - - body.appendChild( container ).appendChild( div ); - - // Support: IE8 - // 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). - div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; - tds = div.getElementsByTagName("td"); - tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; - isSupported = ( tds[ 0 ].offsetHeight === 0 ); - - tds[ 0 ].style.display = ""; - tds[ 1 ].style.display = "none"; - - // Support: IE8 - // Check if empty table cells still have offsetWidth/Height - support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); - - // Check box-sizing and margin behavior. - div.innerHTML = ""; - div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; - - // Workaround failing boxSizing test due to offsetWidth returning wrong value - // with some non-1 values of body zoom, ticket #13543 - jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { - support.boxSizing = div.offsetWidth === 4; - }); - - // Use window.getComputedStyle because jsdom on node.js will break without it. - if ( window.getComputedStyle ) { - support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; - support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; - - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. (#3333) - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - marginDiv = div.appendChild( document.createElement("div") ); - marginDiv.style.cssText = div.style.cssText = divReset; - marginDiv.style.marginRight = marginDiv.style.width = "0"; - div.style.width = "1px"; - - support.reliableMarginRight = - !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); - } - - if ( typeof div.style.zoom !== core_strundefined ) { - // Support: IE<8 - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - div.innerHTML = ""; - div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; - support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); - - // Support: IE6 - // Check if elements with layout shrink-wrap their children - div.style.display = "block"; - div.innerHTML = "<div></div>"; - div.firstChild.style.width = "5px"; - support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); - - if ( support.inlineBlockNeedsLayout ) { - // Prevent IE 6 from affecting layout for positioned elements #11048 - // Prevent IE from shrinking the body in IE 7 mode #12869 - // Support: IE<8 - body.style.zoom = 1; - } - } - - body.removeChild( container ); - - // Null elements to avoid leaks in IE - container = div = tds = marginDiv = null; - }); - - // Null elements to avoid leaks in IE - all = select = fragment = opt = a = input = null; - - return support; -})({}); - -var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, - rmultiDash = /([A-Z])/g; - -function internalData( elem, name, data, pvt /* Internal Use Only */ ){ - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var ret, thisCache, - internalKey = jQuery.expando, - - // 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[ internalKey ] : elem[ internalKey ] && internalKey; - - // 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 || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { - 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 ) { - id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++; - } else { - id = internalKey; - } - } - - if ( !cache[ id ] ) { - // Avoid exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - cache[ id ] = isNode ? {} : { 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 ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( typeof name === "string" ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; -} - -function internalRemoveData( elem, name, pvt ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var thisCache, i, - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - 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 ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support array or space separated string names for data keys - if ( !jQuery.isArray( name ) ) { - - // try the string as a key before any manipulation - if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces unless a key with the spaces exists - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split(" "); - } - } - } else { - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = name.concat( jQuery.map( name, jQuery.camelCase ) ); - } - - i = name.length; - while ( i-- ) { - delete thisCache[ name[i] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject( cache[ id ] ) ) { - return; - } - } - - // Destroy the cache - if ( isNode ) { - jQuery.cleanData( [ elem ], true ); - - // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) - /* jshint eqeqeq: false */ - } else if ( jQuery.support.deleteExpando || cache != cache.window ) { - /* jshint eqeqeq: true */ - delete cache[ id ]; - - // When all else fails, null - } else { - cache[ id ] = null; - } -} - -jQuery.extend({ - cache: {}, - - // The following elements throw uncatchable exceptions if you - // attempt to add expando properties to them. - noData: { - "applet": true, - "embed": true, - // Ban all objects except for Flash (which handle expandos) - "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data ) { - return internalData( elem, name, data ); - }, - - removeData: function( elem, name ) { - return internalRemoveData( elem, name ); - }, - - // For internal use only. - _data: function( elem, name, data ) { - return internalData( elem, name, data, true ); - }, - - _removeData: function( elem, name ) { - return internalRemoveData( elem, name, true ); - }, - - // A method for determining if a DOM node can handle the data expando - acceptData: function( elem ) { - // Do not set data on non-element because it will not be cleared (#8335). - if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { - return false; - } - - var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; - - // nodes accept data unless otherwise specified; rejection can be conditional - return !noData || noData !== true && elem.getAttribute("classid") === noData; - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var attrs, name, - data = null, - i = 0, - elem = this[0]; - - // Special expections of .data basically thwart jQuery.access, - // so implement the relevant behavior ourselves - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = jQuery.data( elem ); - - if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { - attrs = elem.attributes; - for ( ; i < attrs.length; i++ ) { - name = attrs[i].name; - - if ( name.indexOf("data-") === 0 ) { - name = jQuery.camelCase( name.slice(5) ); - - dataAttr( elem, name, data[ name ] ); - } - } - jQuery._data( elem, "parsedAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - return arguments.length > 1 ? - - // Sets one value - this.each(function() { - jQuery.data( this, key, value ); - }) : - - // Gets one value - // Try to fetch any internally stored data first - elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; - }, - - 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" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - // Only convert to a number if it doesn't change the string - +data + "" === data ? +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; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - var name; - for ( name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} -jQuery.extend({ - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || jQuery.isArray(data) ) { - queue = jQuery._data( elem, type, jQuery.makeArray(data) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // not intended for public consumption - generates a queueHooks object, or returns the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return jQuery._data( elem, key ) || jQuery._data( elem, key, { - empty: jQuery.Callbacks("once memory").add(function() { - jQuery._removeData( elem, type + "queue" ); - jQuery._removeData( elem, key ); - }) - }); - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); - } - - return data === undefined ? - this : - this.each(function() { - var queue = jQuery.queue( this, type, data ); - - // ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - 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( next, hooks ) { - var timeout = setTimeout( next, time ); - hooks.stop = function() { - clearTimeout( timeout ); - }; - }); - }, - 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, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while( i-- ) { - tmp = jQuery._data( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -}); -var nodeHook, boolHook, - rclass = /[\t\r\n\f]/g, - rreturn = /\r/g, - rfocusable = /^(?:input|select|textarea|button|object)$/i, - rclickable = /^(?:a|area)$/i, - ruseDefault = /^(?:checked|selected)$/i, - getSetAttribute = jQuery.support.getSetAttribute, - getSetInput = jQuery.support.input; - -jQuery.fn.extend({ - attr: function( name, value ) { - return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); - }, - - removeAttr: function( name ) { - return this.each(function() { - jQuery.removeAttr( this, name ); - }); - }, - - prop: function( name, value ) { - return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); - }, - - 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 ) { - var classes, elem, cur, clazz, j, - i = 0, - len = this.length, - proceed = typeof value === "string" && value; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).addClass( value.call( this, j, this.className ) ); - }); - } - - if ( proceed ) { - // The disjunction here is for better compressibility (see removeClass) - classes = ( value || "" ).match( core_rnotwhite ) || []; - - for ( ; i < len; i++ ) { - elem = this[ i ]; - cur = elem.nodeType === 1 && ( elem.className ? - ( " " + elem.className + " " ).replace( rclass, " " ) : - " " - ); - - if ( cur ) { - j = 0; - while ( (clazz = classes[j++]) ) { - if ( cur.indexOf( " " + clazz + " " ) < 0 ) { - cur += clazz + " "; - } - } - elem.className = jQuery.trim( cur ); - - } - } - } - - return this; - }, - - removeClass: function( value ) { - var classes, elem, cur, clazz, j, - i = 0, - len = this.length, - proceed = arguments.length === 0 || typeof value === "string" && value; - - if ( jQuery.isFunction( value ) ) { - return this.each(function( j ) { - jQuery( this ).removeClass( value.call( this, j, this.className ) ); - }); - } - if ( proceed ) { - classes = ( value || "" ).match( core_rnotwhite ) || []; - - for ( ; i < len; i++ ) { - elem = this[ i ]; - // This expression is here for better compressibility (see addClass) - cur = elem.nodeType === 1 && ( elem.className ? - ( " " + elem.className + " " ).replace( rclass, " " ) : - "" - ); - - if ( cur ) { - j = 0; - while ( (clazz = classes[j++]) ) { - // Remove *all* instances - while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { - cur = cur.replace( " " + clazz + " ", " " ); - } - } - elem.className = value ? jQuery.trim( cur ) : ""; - } - } - } - - return this; - }, - - toggleClass: function( value, stateVal ) { - var type = typeof value; - - if ( typeof stateVal === "boolean" && type === "string" ) { - return stateVal ? this.addClass( value ) : this.removeClass( value ); - } - - if ( jQuery.isFunction( value ) ) { - return this.each(function( i ) { - jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); - }); - } - - return this.each(function() { - if ( type === "string" ) { - // toggle individual class names - var className, - i = 0, - self = jQuery( this ), - classNames = value.match( core_rnotwhite ) || []; - - while ( (className = classNames[ i++ ]) ) { - // check each className given, space separated list - if ( self.hasClass( className ) ) { - self.removeClass( className ); - } else { - self.addClass( className ); - } - } - - // Toggle whole class name - } else if ( type === core_strundefined || type === "boolean" ) { - if ( this.className ) { - // store className if set - jQuery._data( this, "__className__", this.className ); - } - - // If the element has a class name or if we're passed "false", - // then remove the whole classname (if there was one, the above saved it). - // Otherwise bring back whatever was previously saved (if anything), - // falling back to the empty string if nothing was stored. - this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; - } - }); - }, - - hasClass: function( selector ) { - var className = " " + selector + " ", - i = 0, - l = this.length; - for ( ; i < l; i++ ) { - if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { - return true; - } - } - - return false; - }, - - val: function( value ) { - var ret, hooks, isFunction, - elem = this[0]; - - if ( !arguments.length ) { - if ( elem ) { - hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; - - if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { - return ret; - } - - ret = elem.value; - - return typeof ret === "string" ? - // handle most common string cases - ret.replace(rreturn, "") : - // handle cases where value is null/undef or number - ret == null ? "" : ret; - } - - return; - } - - isFunction = jQuery.isFunction( value ); - - return this.each(function( i ) { - var val; - - if ( this.nodeType !== 1 ) { - return; - } - - if ( isFunction ) { - val = value.call( this, i, jQuery( this ).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.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; - - // 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 ) { - // Use proper attribute retrieval(#6932, #12072) - var val = jQuery.find.attr( elem, "value" ); - return val != null ? - val : - elem.text; - } - }, - select: { - get: function( elem ) { - var value, option, - options = elem.options, - index = elem.selectedIndex, - one = elem.type === "select-one" || index < 0, - values = one ? null : [], - max = one ? index + 1 : options.length, - i = index < 0 ? - max : - one ? index : 0; - - // Loop through all the selected options - for ( ; i < max; i++ ) { - option = options[ i ]; - - // oldIE doesn't update selected after form reset (#2551) - if ( ( option.selected || i === index ) && - // Don't return options that are disabled or in a disabled optgroup - ( 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 ); - } - } - - return values; - }, - - set: function( elem, value ) { - var optionSet, option, - options = elem.options, - values = jQuery.makeArray( value ), - i = options.length; - - while ( i-- ) { - option = options[ i ]; - if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { - optionSet = true; - } - } - - // force browsers to behave consistently when non-matching value is set - if ( !optionSet ) { - elem.selectedIndex = -1; - } - return values; - } - } - }, - - attr: function( elem, name, value ) { - var hooks, ret, - nType = elem.nodeType; - - // don't get/set attributes on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === core_strundefined ) { - return jQuery.prop( elem, name, value ); - } - - // All attributes are lowercase - // Grab necessary hook if one is defined - if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { - name = name.toLowerCase(); - hooks = jQuery.attrHooks[ name ] || - ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); - } - - if ( value !== undefined ) { - - if ( value === null ) { - jQuery.removeAttr( elem, name ); - - } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { - return ret; - - } else { - elem.setAttribute( name, value + "" ); - return value; - } - - } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { - return ret; - - } else { - ret = jQuery.find.attr( elem, name ); - - // Non-existent attributes return null, we normalize to undefined - return ret == null ? - undefined : - ret; - } - }, - - removeAttr: function( elem, value ) { - var name, propName, - i = 0, - attrNames = value && value.match( core_rnotwhite ); - - if ( attrNames && elem.nodeType === 1 ) { - while ( (name = attrNames[i++]) ) { - propName = jQuery.propFix[ name ] || name; - - // Boolean attributes get special treatment (#10870) - if ( jQuery.expr.match.bool.test( name ) ) { - // Set corresponding property to false - if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { - elem[ propName ] = false; - // Support: IE<9 - // Also clear defaultChecked/defaultSelected (if appropriate) - } else { - elem[ jQuery.camelCase( "default-" + name ) ] = - elem[ propName ] = false; - } - - // See #9699 for explanation of this approach (setting first, then removal) - } else { - jQuery.attr( elem, name, "" ); - } - - elem.removeAttribute( getSetAttribute ? name : propName ); - } - } - }, - - attrHooks: { - type: { - set: function( elem, value ) { - 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 default in case type is set after value during creation - var val = elem.value; - elem.setAttribute( "type", value ); - if ( val ) { - elem.value = val; - } - return value; - } - } - } - }, - - propFix: { - "for": "htmlFor", - "class": "className" - }, - - prop: function( elem, name, value ) { - var ret, hooks, notxml, - nType = elem.nodeType; - - // don't get/set properties on text, comment and attribute nodes - if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { - return; - } - - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - - if ( notxml ) { - // Fix name and attach hooks - name = jQuery.propFix[ name ] || name; - hooks = jQuery.propHooks[ name ]; - } - - if ( value !== undefined ) { - return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? - ret : - ( elem[ name ] = value ); - - } else { - return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? - ret : - elem[ name ]; - } - }, - - propHooks: { - 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/ - // Use proper attribute retrieval(#12072) - var tabindex = jQuery.find.attr( elem, "tabindex" ); - - return tabindex ? - parseInt( tabindex, 10 ) : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - -1; - } - } - } -}); - -// Hooks for boolean attributes -boolHook = { - set: function( elem, value, name ) { - if ( value === false ) { - // Remove boolean attributes when set to false - jQuery.removeAttr( elem, name ); - } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { - // IE<8 needs the *property* name - elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); - - // Use defaultChecked and defaultSelected for oldIE - } else { - elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; - } - - return name; - } -}; -jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { - var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; - - jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? - function( elem, name, isXML ) { - var fn = jQuery.expr.attrHandle[ name ], - ret = isXML ? - undefined : - /* jshint eqeqeq: false */ - (jQuery.expr.attrHandle[ name ] = undefined) != - getter( elem, name, isXML ) ? - - name.toLowerCase() : - null; - jQuery.expr.attrHandle[ name ] = fn; - return ret; - } : - function( elem, name, isXML ) { - return isXML ? - undefined : - elem[ jQuery.camelCase( "default-" + name ) ] ? - name.toLowerCase() : - null; - }; -}); - -// fix oldIE attroperties -if ( !getSetInput || !getSetAttribute ) { - jQuery.attrHooks.value = { - set: function( elem, value, name ) { - if ( jQuery.nodeName( elem, "input" ) ) { - // Does not return so that setAttribute is also used - elem.defaultValue = value; - } else { - // Use nodeHook if defined (#1954); otherwise setAttribute is fine - return nodeHook && nodeHook.set( elem, value, name ); - } - } - }; -} - -// IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !getSetAttribute ) { - - // Use this for any attribute in IE6/7 - // This fixes almost every IE6/7 issue - nodeHook = { - set: function( elem, value, name ) { - // Set the existing or create a new attribute node - var ret = elem.getAttributeNode( name ); - if ( !ret ) { - elem.setAttributeNode( - (ret = elem.ownerDocument.createAttribute( name )) - ); - } - - ret.value = value += ""; - - // Break association with cloned elements by also using setAttribute (#9646) - return name === "value" || value === elem.getAttribute( name ) ? - value : - undefined; - } - }; - jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = - // Some attributes are constructed with empty-string values when not defined - function( elem, name, isXML ) { - var ret; - return isXML ? - undefined : - (ret = elem.getAttributeNode( name )) && ret.value !== "" ? - ret.value : - null; - }; - jQuery.valHooks.button = { - get: function( elem, name ) { - var ret = elem.getAttributeNode( name ); - return ret && ret.specified ? - ret.value : - undefined; - }, - set: nodeHook.set - }; - - // Set contenteditable to false on removals(#10429) - // Setting to empty string throws an error as an invalid value - jQuery.attrHooks.contenteditable = { - set: function( elem, value, name ) { - nodeHook.set( elem, value === "" ? false : value, name ); - } - }; - - // 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 ] = { - set: function( elem, value ) { - if ( value === "" ) { - elem.setAttribute( name, "auto" ); - return value; - } - } - }; - }); -} - - -// Some attributes require a special call on IE -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !jQuery.support.hrefNormalized ) { - // href/src property should get the full normalized URL (#10299/#12915) - jQuery.each([ "href", "src" ], function( i, name ) { - jQuery.propHooks[ name ] = { - get: function( elem ) { - return elem.getAttribute( name, 4 ); - } - }; - }); -} - -if ( !jQuery.support.style ) { - jQuery.attrHooks.style = { - get: function( elem ) { - // Return undefined in the case of empty string - // Note: IE uppercases css property names, but if we were to .toLowerCase() - // .cssText, that would destroy case senstitivity in URL's, like in "background" - return elem.style.cssText || 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 = { - 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; - } - } - return null; - } - }; -} - -jQuery.each([ - "tabIndex", - "readOnly", - "maxLength", - "cellSpacing", - "cellPadding", - "rowSpan", - "colSpan", - "useMap", - "frameBorder", - "contentEditable" -], function() { - jQuery.propFix[ this.toLowerCase() ] = this; -}); - -// IE6/7 call enctype encoding -if ( !jQuery.support.enctype ) { - jQuery.propFix.enctype = "encoding"; -} - -// Radios and checkboxes getter/setter -jQuery.each([ "radio", "checkbox" ], function() { - jQuery.valHooks[ this ] = { - set: function( elem, value ) { - if ( jQuery.isArray( value ) ) { - return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); - } - } - }; - if ( !jQuery.support.checkOn ) { - jQuery.valHooks[ this ].get = function( elem ) { - // Support: Webkit - // "" is returned instead of "on" if a value isn't specified - return elem.getAttribute("value") === null ? "on" : elem.value; - }; - } -}); -var rformElems = /^(?:input|select|textarea)$/i, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - var tmp, events, t, handleObjIn, - special, eventHandle, handleObj, - handlers, type, namespaces, origType, - elemData = jQuery._data( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !(events = elemData.events) ) { - events = elemData.events = {}; - } - if ( !(eventHandle = elemData.handle) ) { - eventHandle = elemData.handle = 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 !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( core_rnotwhite ) || [""]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !(handlers = events[ type ]) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // 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 to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - var j, handleObj, tmp, - origCount, t, events, - special, handlers, type, - namespaces, origType, - elemData = jQuery.hasData( elem ) && jQuery._data( elem ); - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( core_rnotwhite ) || [""]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery._removeData( elem, "events" ); - } - }, - - trigger: function( event, data, elem, onlyHandlers ) { - var handle, ontype, cur, - bubbleType, special, tmp, i, - eventPath = [ elem || document ], - type = core_hasOwn.call( event, "type" ) ? event.type : event, - namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.namespace_re = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === (elem.ownerDocument || document) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { - event.preventDefault(); - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && - 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. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - try { - elem[ type ](); - } catch ( e ) { - // IE<9 dies on focus/blur to hidden element (#1486,#12518) - // only reproducible on winXP IE8 native, not IE9 in IE8 mode - } - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event ); - - var i, ret, handleObj, matched, j, - handlerQueue = [], - args = core_slice.call( arguments ), - handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( (event.result = ret) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var sel, handleObj, matches, i, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - // Black-hole SVG <use> instance trees (#13180) - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { - - /* jshint eqeqeq: false */ - for ( ; cur != this; cur = cur.parentNode || this ) { - /* jshint eqeqeq: true */ - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matches[ sel ] === undefined ) { - matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matches[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( delegateCount < handlers.length ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); - } - - return handlerQueue; - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, copy, - type = event.type, - originalEvent = event, - fixHook = this.fixHooks[ type ]; - - if ( !fixHook ) { - this.fixHooks[ type ] = fixHook = - rmouseEvent.test( type ) ? this.mouseHooks : - rkeyEvent.test( type ) ? this.keyHooks : - {}; - } - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = new jQuery.Event( originalEvent ); - - i = copy.length; - while ( i-- ) { - prop = copy[ i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Support: IE<9 - // Fix target property (#1925) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Support: Chrome 23+, Safari? - // Target should not be a text node (#504, #13143) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // Support: IE<9 - // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) - event.metaKey = !!event.metaKey; - - return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var body, eventDoc, doc, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - special: { - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - try { - this.focus(); - return false; - } catch ( e ) { - // Support: IE<9 - // If we error on focus to hidden element (#1486, #12518), - // let .trigger() run the handlers - } - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Even when returnValue equals to undefined Firefox will still show alert - if ( event.result !== undefined ) { - event.originalEvent.returnValue = event.result; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // 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. - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - var name = "on" + type; - - if ( elem.detachEvent ) { - - // #8545, #7054, preventing memory leaks for custom events in IE6-8 - // detachEvent needed property on element, by name of that event, to properly expose it to GC - if ( typeof elem[ name ] === core_strundefined ) { - elem[ name ] = null; - } - - elem.detachEvent( name, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - 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 ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = 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 = { - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - if ( !e ) { - return; - } - - // If preventDefault exists, run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // Support: IE - // Otherwise set the returnValue property of the original event to false - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - if ( !e ) { - return; - } - // If stopPropagation exists, run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - - // Support: IE - // Set the cancelBubble property of the original event to true - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - } -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// IE submit delegation -if ( !jQuery.support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !jQuery._data( form, "submitBubbles" ) ) { - jQuery.event.add( form, "submit._submit", function( event ) { - event._submit_bubble = true; - }); - jQuery._data( form, "submitBubbles", true ); - } - }); - // return undefined since we don't need an event listener - }, - - postDispatch: function( event ) { - // If form was submitted by the user, bubble the event up the tree - if ( event._submit_bubble ) { - delete event._submit_bubble; - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } - } - }, - - teardown: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !jQuery.support.changeBubbles ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._just_changed = true; - } - }); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._just_changed && !event.isTrigger ) { - this._just_changed = false; - } - // Allow triggered, simulated change events (#11500) - jQuery.event.simulate( "change", this, event, true ); - }); - } - return false; - } - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { - jQuery.event.simulate( "change", this.parentNode, event, true ); - } - }); - jQuery._data( elem, "changeBubbles", true ); - } - }); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return !rformElems.test( this.nodeName ); - } - }; -} - -// 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, - handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - if ( attaches++ === 0 ) { - document.addEventListener( orig, handler, true ); - } - }, - teardown: function() { - if ( --attaches === 0 ) { - document.removeEventListener( orig, handler, true ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var type, origFn; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - var elem = this[0]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -}); -var isSimple = /^.[^:#\[\.,]*$/, - rparentsprev = /^(?:parents|prev(?:Until|All))/, - rneedsContext = jQuery.expr.match.needsContext, - // 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 i, - ret = [], - self = this, - len = self.length; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - - has: function( target ) { - var i, - targets = jQuery( target, this ), - len = targets.length; - - return this.filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); - }, - - filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); - }, - - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - ret = [], - pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( ; i < l; i++ ) { - for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { - // Always skip document fragments - if ( cur.nodeType < 11 && (pos ? - pos.index(cur) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors)) ) { - - cur = ret.push( cur ); - break; - } - } - } - - return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // 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( jQuery.unique(all) ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter(selector) - ); - } -}); - -function sibling( cur, dir ) { - do { - cur = cur[ dir ]; - } while ( cur && cur.nodeType !== 1 ); - - return cur; -} - -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 sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "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.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - if ( this.length > 1 ) { - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - ret = jQuery.unique( ret ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - } - - return this.pushStack( ret ); - }; -}); - -jQuery.extend({ - filter: function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - })); - }, - - 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; - }, - - 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, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - }); - - } - - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - }); - - } - - if ( typeof qualifier === "string" ) { - if ( isSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - qualifier = jQuery.filter( qualifier, elements ); - } - - return jQuery.grep( elements, function( elem ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; - }); -} -function createSafeFragment( document ) { - var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - -var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + - "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, - rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - rtagName = /<([\w:]+)/, - rtbody = /<tbody/i, - rhtml = /<|&#?\w+;/, - rnoInnerhtml = /<(?:script|style|link)/i, - manipulation_rcheckableType = /^(?:checkbox|radio)$/i, - // checked="checked" or checked - rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, - rscriptType = /^$|\/(?:java|ecma)script/i, - rscriptTypeMasked = /^true\/(.*)/, - rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, - - // We have to close these tags to support XHTML (#13200) - wrapMap = { - option: [ 1, "<select multiple='multiple'>", "</select>" ], - legend: [ 1, "<fieldset>", "</fieldset>" ], - area: [ 1, "<map>", "</map>" ], - param: [ 1, "<object>", "</object>" ], - thead: [ 1, "<table>", "</table>" ], - tr: [ 2, "<table><tbody>", "</tbody></table>" ], - col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], - td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], - - // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, - // unless wrapped in a div with non-breaking characters in front of it. - _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ] - }, - safeFragment = createSafeFragment( document ), - fragmentDiv = safeFragment.appendChild( document.createElement("div") ); - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -jQuery.fn.extend({ - text: function( value ) { - return jQuery.access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); - }, null, value, arguments.length ); - }, - - append: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - }); - }, - - prepend: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - }); - }, - - before: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - }); - }, - - after: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - }); - }, - - // keepData is for internal use only--do not document - remove: function( selector, keepData ) { - var elem, - elems = selector ? jQuery.filter( selector, this ) : this, - i = 0; - - for ( ; (elem = elems[i]) != null; i++ ) { - - if ( !keepData && elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem ) ); - } - - if ( elem.parentNode ) { - if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { - setGlobalEval( getAll( elem, "script" ) ); - } - elem.parentNode.removeChild( elem ); - } - } - - return this; - }, - - empty: function() { - var elem, - i = 0; - - for ( ; (elem = this[i]) != null; i++ ) { - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - } - - // Remove any remaining nodes - while ( elem.firstChild ) { - elem.removeChild( elem.firstChild ); - } - - // If this is a select, ensure that it displays empty (#12336) - // Support: IE<9 - if ( elem.options && jQuery.nodeName( elem, "select" ) ) { - elem.options.length = 0; - } - } - - 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 ) { - return jQuery.access( this, function( value ) { - var elem = this[0] || {}, - i = 0, - l = this.length; - - if ( value === undefined ) { - return elem.nodeType === 1 ? - elem.innerHTML.replace( rinlinejQuery, "" ) : - undefined; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && - ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && - !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { - - value = value.replace( rxhtmlTag, "<$1></$2>" ); - - try { - for (; i < l; i++ ) { - // Remove element nodes and prevent memory leaks - elem = this[i] || {}; - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch(e) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var - // Snapshot the DOM in case .domManip sweeps something relevant into its fragment - args = jQuery.map( this, function( elem ) { - return [ elem.nextSibling, elem.parentNode ]; - }), - i = 0; - - // Make the changes, replacing each context element with the new content - this.domManip( arguments, function( elem ) { - var next = args[ i++ ], - parent = args[ i++ ]; - - if ( parent ) { - // Don't use the snapshot next if it has moved (#13810) - if ( next && next.parentNode !== parent ) { - next = this.nextSibling; - } - jQuery( this ).remove(); - parent.insertBefore( elem, next ); - } - // Allow new content to include elements from the context set - }, true ); - - // Force removal if there was no new content (e.g., from empty arguments) - return i ? this : this.remove(); - }, - - detach: function( selector ) { - return this.remove( selector, true ); - }, - - domManip: function( args, callback, allowIntersection ) { - - // Flatten any nested arrays - args = core_concat.apply( [], args ); - - var first, node, hasScripts, - scripts, doc, fragment, - i = 0, - l = this.length, - set = this, - iNoClone = l - 1, - value = args[0], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { - return this.each(function( index ) { - var self = set.eq( index ); - if ( isFunction ) { - args[0] = value.call( this, index, self.html() ); - } - self.domManip( args, callback, allowIntersection ); - }); - } - - if ( l ) { - fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - if ( first ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( this[i], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - - if ( node.src ) { - // Hope ajax is available... - jQuery._evalUrl( node.src ); - } else { - jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); - } - } - } - } - - // Fix #11809: Avoid leaking memory - fragment = first = null; - } - } - - return this; - } -}); - -// Support: IE<8 -// Manipulating tables requires a tbody -function manipulationTarget( elem, content ) { - return jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? - - elem.getElementsByTagName("tbody")[0] || - elem.appendChild( elem.ownerDocument.createElement("tbody") ) : - elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - if ( match ) { - elem.type = match[1]; - } else { - elem.removeAttribute("type"); - } - return elem; -} - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var elem, - i = 0; - for ( ; (elem = elems[i]) != null; i++ ) { - jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); - } -} - -function cloneCopyEvent( src, dest ) { - - if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { - return; - } - - var type, i, l, - oldData = jQuery._data( src ), - curData = jQuery._data( dest, oldData ), - events = oldData.events; - - if ( events ) { - delete curData.handle; - curData.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - - // make the cloned public data object a copy from the original - if ( curData.data ) { - curData.data = jQuery.extend( {}, curData.data ); - } -} - -function fixCloneNodeIssues( src, dest ) { - var nodeName, e, data; - - // We do not need to do anything for non-Elements - if ( dest.nodeType !== 1 ) { - return; - } - - nodeName = dest.nodeName.toLowerCase(); - - // IE6-8 copies events bound via attachEvent when using cloneNode. - if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { - data = jQuery._data( dest ); - - for ( e in data.events ) { - jQuery.removeEvent( dest, e, data.handle ); - } - - // Event data gets referenced instead of copied if the expando gets copied too - dest.removeAttribute( jQuery.expando ); - } - - // IE blanks contents when cloning scripts, and tries to evaluate newly-set text - if ( nodeName === "script" && dest.text !== src.text ) { - disableScript( dest ).text = src.text; - restoreScript( dest ); - - // IE6-10 improperly clones children of object elements using classid. - // IE10 throws NoModificationAllowedError if parent is null, #12132. - } else if ( nodeName === "object" ) { - if ( dest.parentNode ) { - dest.outerHTML = src.outerHTML; - } - - // This path appears unavoidable for IE9. When cloning an object - // element in IE9, the outerHTML strategy above is not sufficient. - // If the src has innerHTML and the destination does not, - // copy the src.innerHTML into the dest.innerHTML. #10324 - if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { - dest.innerHTML = src.innerHTML; - } - - } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { - // 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 - - 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.defaultSelected = 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; - } -} - -jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - i = 0, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone(true); - jQuery( insert[i] )[ original ]( elems ); - - // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() - core_push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -}); - -function getAll( context, tag ) { - var elems, elem, - i = 0, - found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : - typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : - undefined; - - if ( !found ) { - for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { - if ( !tag || jQuery.nodeName( elem, tag ) ) { - found.push( elem ); - } else { - jQuery.merge( found, getAll( elem, tag ) ); - } - } - } - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], found ) : - found; -} - -// Used in buildFragment, fixes the defaultChecked property -function fixDefaultChecked( elem ) { - if ( manipulation_rcheckableType.test( elem.type ) ) { - elem.defaultChecked = elem.checked; - } -} - -jQuery.extend({ - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var destElements, node, clone, i, srcElements, - inPage = jQuery.contains( elem.ownerDocument, elem ); - - if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { - clone = elem.cloneNode( true ); - - // IE<=8 does not properly clone detached, unknown element nodes - } else { - fragmentDiv.innerHTML = elem.outerHTML; - fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); - } - - if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && - (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { - - // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - // Fix all IE cloning issues - for ( i = 0; (node = srcElements[i]) != null; ++i ) { - // Ensure that the destination node is not null; Fixes #9587 - if ( destElements[i] ) { - fixCloneNodeIssues( node, destElements[i] ); - } - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0; (node = srcElements[i]) != null; i++ ) { - cloneCopyEvent( node, destElements[i] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - destElements = srcElements = node = null; - - // Return the cloned set - return clone; - }, - - buildFragment: function( elems, context, scripts, selection ) { - var j, elem, contains, - tmp, tag, tbody, wrap, - l = elems.length, - - // Ensure a safe fragment - safe = createSafeFragment( context ), - - nodes = [], - i = 0; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || safe.appendChild( context.createElement("div") ); - - // Deserialize a standard representation - tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - - tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2]; - - // Descend through wrappers to the right content - j = wrap[0]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Manually add leading whitespace removed by IE - if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { - nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); - } - - // Remove IE's autoinserted <tbody> from table fragments - if ( !jQuery.support.tbody ) { - - // String was a <table>, *may* have spurious <tbody> - elem = tag === "table" && !rtbody.test( elem ) ? - tmp.firstChild : - - // String was a bare <thead> or <tfoot> - wrap[1] === "<table>" && !rtbody.test( elem ) ? - tmp : - 0; - - j = elem && elem.childNodes.length; - while ( j-- ) { - if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { - elem.removeChild( tbody ); - } - } - } - - jQuery.merge( nodes, tmp.childNodes ); - - // Fix #12392 for WebKit and IE > 9 - tmp.textContent = ""; - - // Fix #12392 for oldIE - while ( tmp.firstChild ) { - tmp.removeChild( tmp.firstChild ); - } - - // Remember the top-level container for proper cleanup - tmp = safe.lastChild; - } - } - } - - // Fix #11356: Clear elements from fragment - if ( tmp ) { - safe.removeChild( tmp ); - } - - // Reset defaultChecked for any radios and checkboxes - // about to be appended to the DOM in IE 6/7 (#8060) - if ( !jQuery.support.appendChecked ) { - jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); - } - - i = 0; - while ( (elem = nodes[ i++ ]) ) { - - // #4087 - If origin and destination elements are the same, and this is - // that element, do not do anything - if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( safe.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( (elem = tmp[ j++ ]) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - tmp = null; - - return safe; - }, - - cleanData: function( elems, /* internal */ acceptData ) { - var elem, type, id, data, - i = 0, - internalKey = jQuery.expando, - cache = jQuery.cache, - deleteExpando = jQuery.support.deleteExpando, - special = jQuery.event.special; - - for ( ; (elem = elems[i]) != null; i++ ) { - - if ( acceptData || jQuery.acceptData( elem ) ) { - - id = elem[ internalKey ]; - data = id && cache[ id ]; - - if ( data ) { - if ( data.events ) { - for ( 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 ); - } - } - } - - // Remove cache only if it was not already removed by jQuery.event.remove - if ( cache[ id ] ) { - - delete cache[ id ]; - - // 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 ( deleteExpando ) { - delete elem[ internalKey ]; - - } else if ( typeof elem.removeAttribute !== core_strundefined ) { - elem.removeAttribute( internalKey ); - - } else { - elem[ internalKey ] = null; - } - - core_deletedIds.push( id ); - } - } - } - } - }, - - _evalUrl: function( url ) { - return jQuery.ajax({ - url: url, - type: "GET", - dataType: "script", - async: false, - global: false, - "throws": true - }); - } -}); -jQuery.fn.extend({ - 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 ) { - var isFunction = jQuery.isFunction( html ); - - return this.each(function(i) { - jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); - }); - }, - - unwrap: function() { - return this.parent().each(function() { - if ( !jQuery.nodeName( this, "body" ) ) { - jQuery( this ).replaceWith( this.childNodes ); - } - }).end(); - } -}); -var iframe, getStyles, curCSS, - ralpha = /alpha\([^)]*\)/i, - ropacity = /opacity\s*=\s*([^)]*)/, - rposition = /^(top|right|bottom|left)$/, - // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" - // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display - rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rmargin = /^margin/, - rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), - rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), - rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), - elemdisplay = { BODY: "block" }, - - cssShow = { position: "absolute", visibility: "hidden", display: "block" }, - cssNormalTransform = { - letterSpacing: 0, - fontWeight: 400 - }, - - cssExpand = [ "Top", "Right", "Bottom", "Left" ], - cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; - -// return a css property mapped to a potentially vendor prefixed property -function vendorPropName( style, name ) { - - // shortcut for names that are not vendor prefixed - if ( name in style ) { - return name; - } - - // check for vendor prefixed names - var capName = name.charAt(0).toUpperCase() + name.slice(1), - origName = name, - i = cssPrefixes.length; - - while ( i-- ) { - name = cssPrefixes[ i ] + capName; - if ( name in style ) { - return name; - } - } - - return origName; -} - -function isHidden( elem, el ) { - // isHidden might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); -} - -function showHide( elements, show ) { - var display, elem, hidden, - values = [], - index = 0, - length = elements.length; - - for ( ; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - - values[ index ] = jQuery._data( elem, "olddisplay" ); - display = elem.style.display; - if ( show ) { - // Reset the inline display of this element to learn if it is - // being hidden by cascaded rules or not - if ( !values[ index ] && display === "none" ) { - 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 ( elem.style.display === "" && isHidden( elem ) ) { - values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); - } - } else { - - if ( !values[ index ] ) { - hidden = isHidden( elem ); - - if ( display && display !== "none" || !hidden ) { - jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); - } - } - } - } - - // Set the display of most of the elements in a second loop - // to avoid the constant reflow - for ( index = 0; index < length; index++ ) { - elem = elements[ index ]; - if ( !elem.style ) { - continue; - } - if ( !show || elem.style.display === "none" || elem.style.display === "" ) { - elem.style.display = show ? values[ index ] || "" : "none"; - } - } - - return elements; -} - -jQuery.fn.extend({ - css: function( name, value ) { - return jQuery.access( this, function( elem, name, value ) { - var len, styles, - map = {}, - i = 0; - - if ( jQuery.isArray( name ) ) { - styles = getStyles( elem ); - len = name.length; - - for ( ; i < len; i++ ) { - map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); - } - - return map; - } - - return value !== undefined ? - jQuery.style( elem, name, value ) : - jQuery.css( elem, name ); - }, name, value, arguments.length > 1 ); - }, - show: function() { - return showHide( this, true ); - }, - hide: function() { - return showHide( this ); - }, - toggle: function( state ) { - if ( typeof state === "boolean" ) { - return state ? this.show() : this.hide(); - } - - return this.each(function() { - if ( isHidden( this ) ) { - jQuery( this ).show(); - } else { - jQuery( this ).hide(); - } - }); - } -}); - -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" ); - return ret === "" ? "1" : ret; - } - } - } - }, - - // Don't automatically add "px" to these possibly-unitless properties - cssNumber: { - "columnCount": true, - "fillOpacity": true, - "fontWeight": true, - "lineHeight": true, - "opacity": true, - "order": true, - "orphans": true, - "widows": true, - "zIndex": true, - "zoom": 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, hooks, - origName = jQuery.camelCase( name ), - style = elem.style; - - name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); - - // gets hook for the prefixed version - // followed by the unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // Check if we're setting a value - if ( value !== undefined ) { - type = typeof value; - - // convert relative number strings (+= or -=) to relative numbers. #7345 - if ( type === "string" && (ret = rrelNum.exec( value )) ) { - value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); - // Fixes bug #9237 - type = "number"; - } - - // Make sure that NaN and null values aren't set. See: #7116 - if ( value == null || type === "number" && isNaN( value ) ) { - return; - } - - // If a number was passed in, add 'px' to the (except for certain CSS properties) - if ( type === "number" && !jQuery.cssNumber[ origName ] ) { - value += "px"; - } - - // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, - // but it would mean to define eight (for every problematic property) identical functions - if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { - style[ name ] = "inherit"; - } - - // If a hook was provided, use that value, otherwise just set the specified value - if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== 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, styles ) { - var num, val, hooks, - origName = jQuery.camelCase( name ); - - // Make sure that we're working with the right name - name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); - - // gets hook for the prefixed version - // followed by the unprefixed version - hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; - - // If a hook was provided get the computed value from there - if ( hooks && "get" in hooks ) { - val = hooks.get( elem, true, extra ); - } - - // Otherwise, if a way to get the computed value exists, use that - if ( val === undefined ) { - val = curCSS( elem, name, styles ); - } - - //convert "normal" to computed value - if ( val === "normal" && name in cssNormalTransform ) { - val = cssNormalTransform[ name ]; - } - - // Return, converting to number if forced or a qualifier was provided and val looks numeric - if ( extra === "" || extra ) { - num = parseFloat( val ); - return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; - } - return val; - } -}); - -// NOTE: we've included the "window" in window.getComputedStyle -// because jsdom on node.js will break without it. -if ( window.getComputedStyle ) { - getStyles = function( elem ) { - return window.getComputedStyle( elem, null ); - }; - - curCSS = function( elem, name, _computed ) { - var width, minWidth, maxWidth, - computed = _computed || getStyles( elem ), - - // getPropertyValue is only needed for .css('filter') in IE9, see #12537 - ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, - style = elem.style; - - if ( computed ) { - - if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { - ret = jQuery.style( elem, name ); - } - - // A tribute to the "awesome hack by Dean Edwards" - // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right - // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels - // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values - if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { - - // Remember the original values - width = style.width; - minWidth = style.minWidth; - maxWidth = style.maxWidth; - - // Put in the new values to get a computed value out - style.minWidth = style.maxWidth = style.width = ret; - ret = computed.width; - - // Revert the changed values - style.width = width; - style.minWidth = minWidth; - style.maxWidth = maxWidth; - } - } - - return ret; - }; -} else if ( document.documentElement.currentStyle ) { - getStyles = function( elem ) { - return elem.currentStyle; - }; - - curCSS = function( elem, name, _computed ) { - var left, rs, rsLeft, - computed = _computed || getStyles( elem ), - ret = computed ? computed[ name ] : undefined, - style = elem.style; - - // Avoid setting ret to empty string here - // so we don't default to auto - if ( ret == null && style && style[ name ] ) { - ret = style[ name ]; - } - - // 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 - // but not position css attributes, as those are proportional to the parent element instead - // and we can't measure the parent instead because it might trigger a "stacking dolls" problem - if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { - - // Remember the original values - left = style.left; - rs = elem.runtimeStyle; - rsLeft = rs && rs.left; - - // Put in the new values to get a computed value out - if ( rsLeft ) { - rs.left = elem.currentStyle.left; - } - style.left = name === "fontSize" ? "1em" : ret; - ret = style.pixelLeft + "px"; - - // Revert the changed values - style.left = left; - if ( rsLeft ) { - rs.left = rsLeft; - } - } - - return ret === "" ? "auto" : ret; - }; -} - -function setPositiveNumber( elem, value, subtract ) { - var matches = rnumsplit.exec( value ); - return matches ? - // Guard against undefined "subtract", e.g., when used as in cssHooks - Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : - value; -} - -function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { - var i = extra === ( isBorderBox ? "border" : "content" ) ? - // If we already have the right measurement, avoid augmentation - 4 : - // Otherwise initialize for horizontal or vertical properties - name === "width" ? 1 : 0, - - val = 0; - - for ( ; i < 4; i += 2 ) { - // both box models exclude margin, so add it if we want it - if ( extra === "margin" ) { - val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); - } - - if ( isBorderBox ) { - // border-box includes padding, so remove it if we want content - if ( extra === "content" ) { - val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - } - - // at this point, extra isn't border nor margin, so remove border - if ( extra !== "margin" ) { - val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } else { - // at this point, extra isn't content, so add padding - val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); - - // at this point, extra isn't content nor padding, so add border - if ( extra !== "padding" ) { - val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); - } - } - } - - return val; -} - -function getWidthOrHeight( elem, name, extra ) { - - // Start with offset property, which is equivalent to the border-box value - var valueIsBorderBox = true, - val = name === "width" ? elem.offsetWidth : elem.offsetHeight, - styles = getStyles( elem ), - isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; - - // some non-html elements return undefined for offsetWidth, so check for null/undefined - // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 - // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 - if ( val <= 0 || val == null ) { - // Fall back to computed then uncomputed css if necessary - val = curCSS( elem, name, styles ); - if ( val < 0 || val == null ) { - val = elem.style[ name ]; - } - - // Computed unit is not pixels. Stop here and return. - if ( rnumnonpx.test(val) ) { - return val; - } - - // we need the check for style in case a browser which returns unreliable values - // for getComputedStyle silently falls back to the reliable elem.style - valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); - - // Normalize "", auto, and prepare for extra - val = parseFloat( val ) || 0; - } - - // use the active box-sizing model to add/subtract irrelevant styles - return ( val + - augmentWidthOrHeight( - elem, - name, - extra || ( isBorderBox ? "border" : "content" ), - valueIsBorderBox, - styles - ) - ) + "px"; -} - -// Try to determine the default display value of an element -function css_defaultDisplay( nodeName ) { - var doc = document, - display = elemdisplay[ nodeName ]; - - if ( !display ) { - display = actualDisplay( nodeName, doc ); - - // If the simple way fails, read from inside an iframe - if ( display === "none" || !display ) { - // Use the already-created iframe if possible - iframe = ( iframe || - jQuery("<iframe frameborder='0' width='0' height='0'/>") - .css( "cssText", "display:block !important" ) - ).appendTo( doc.documentElement ); - - // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse - doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document; - doc.write("<!doctype html><html><body>"); - doc.close(); - - display = actualDisplay( nodeName, doc ); - iframe.detach(); - } - - // Store the correct default display - elemdisplay[ nodeName ] = display; - } - - return display; -} - -// Called ONLY from within css_defaultDisplay -function actualDisplay( name, doc ) { - var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - display = jQuery.css( elem[0], "display" ); - elem.remove(); - return display; -} - -jQuery.each([ "height", "width" ], function( i, name ) { - jQuery.cssHooks[ name ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - // certain elements can have dimension info if we invisibly show them - // however, it must have a current display style that would benefit from this - return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ? - jQuery.swap( elem, cssShow, function() { - return getWidthOrHeight( elem, name, extra ); - }) : - getWidthOrHeight( elem, name, extra ); - } - }, - - set: function( elem, value, extra ) { - var styles = extra && getStyles( elem ); - return setPositiveNumber( elem, value, extra ? - augmentWidthOrHeight( - elem, - name, - extra, - jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", - styles - ) : 0 - ); - } - }; -}); - -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) || "" ) ? - ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : - computed ? "1" : ""; - }, - - set: function( elem, value ) { - var style = elem.style, - currentStyle = elem.currentStyle, - opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", - filter = currentStyle && currentStyle.filter || style.filter || ""; - - // IE has trouble with opacity if it does not have layout - // Force it by setting the zoom level - style.zoom = 1; - - // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 - // if value === "", then remove inline opacity #12685 - if ( ( value >= 1 || value === "" ) && - jQuery.trim( filter.replace( ralpha, "" ) ) === "" && - style.removeAttribute ) { - - // Setting style.filter to null, "" & " " still leave "filter:" in the cssText - // if "filter:" is present at all, clearType is disabled, we want to avoid this - // style.removeAttribute is IE Only, but so apparently is this code path... - style.removeAttribute( "filter" ); - - // if there is no filter style applied in a css rule or unset inline opacity, we are done - if ( value === "" || currentStyle && !currentStyle.filter ) { - return; - } - } - - // otherwise, set new filter values - style.filter = ralpha.test( filter ) ? - filter.replace( ralpha, opacity ) : - filter + " " + opacity; - } - }; -} - -// These hooks cannot be added until DOM ready because the support test -// for it is not run until after DOM ready -jQuery(function() { - if ( !jQuery.support.reliableMarginRight ) { - jQuery.cssHooks.marginRight = { - get: function( elem, computed ) { - if ( computed ) { - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - // Work around by temporarily setting element display to inline-block - return jQuery.swap( elem, { "display": "inline-block" }, - curCSS, [ elem, "marginRight" ] ); - } - } - }; - } - - // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 - // getComputedStyle returns percent when specified for top/left/bottom/right - // rather than make the css module depend on the offset module, we just check for it here - if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { - jQuery.each( [ "top", "left" ], function( i, prop ) { - jQuery.cssHooks[ prop ] = { - get: function( elem, computed ) { - if ( computed ) { - computed = curCSS( elem, prop ); - // if curCSS returns percentage, fallback to offset - return rnumnonpx.test( computed ) ? - jQuery( elem ).position()[ prop ] + "px" : - computed; - } - } - }; - }); - } - -}); - -if ( jQuery.expr && jQuery.expr.filters ) { - jQuery.expr.filters.hidden = function( elem ) { - // Support: Opera <= 12.12 - // Opera reports offsetWidths and offsetHeights less than zero on some elements - return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 || - (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); - }; - - jQuery.expr.filters.visible = function( elem ) { - return !jQuery.expr.filters.hidden( elem ); - }; -} - -// These hooks are used by animate to expand properties -jQuery.each({ - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i = 0, - expanded = {}, - - // assumes a single number if not a string - parts = typeof value === "string" ? value.split(" ") : [ value ]; - - for ( ; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; - } - }; - - if ( !rmargin.test( prefix ) ) { - jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; - } -}); -var r20 = /%20/g, - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, - rsubmittable = /^(?:input|select|textarea|keygen)/i; - -jQuery.fn.extend({ - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - serializeArray: function() { - return this.map(function(){ - // Can add propHook for "elements" to filter or add form elements - var elements = jQuery.prop( this, "elements" ); - return elements ? jQuery.makeArray( elements ) : this; - }) - .filter(function(){ - var type = this.type; - // Use .is(":disabled") so that fieldset[disabled] works - return this.name && !jQuery( this ).is( ":disabled" ) && - rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && - ( this.checked || !manipulation_rcheckableType.test( type ) ); - }) - .map(function( i, elem ){ - var val = jQuery( this ).val(); - - return val == null ? - null : - jQuery.isArray( val ) ? - jQuery.map( val, function( val ){ - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - }) : - { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - }).get(); - } -}); - -//Serialize an array of form elements or a set of -//key/values into a query string -jQuery.param = function( a, traditional ) { - var prefix, - s = [], - add = function( key, value ) { - // If value is a function, invoke it and return its value - value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); - s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); - }; - - // Set traditional to true for jQuery <= 1.3.2 behavior. - if ( traditional === undefined ) { - traditional = jQuery.ajaxSettings && 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 ( prefix in a ) { - buildParams( prefix, a[ prefix ], traditional, add ); - } - } - - // Return the resulting serialization - return s.join( "&" ).replace( r20, "+" ); -}; - -function buildParams( prefix, obj, traditional, add ) { - var name; - - 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 { - // Item is non-scalar (array or object), encode its numeric index. - buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); - } - }); - - } else if ( !traditional && jQuery.type( obj ) === "object" ) { - // Serialize object item. - for ( name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } - - } else { - // Serialize scalar item. - add( prefix, obj ); - } -} -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 contextmenu").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; -}); - -jQuery.fn.extend({ - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - }, - - bind: function( types, data, fn ) { - return this.on( types, null, data, fn ); - }, - unbind: function( types, fn ) { - return this.off( types, null, fn ); - }, - - delegate: function( selector, types, data, fn ) { - return this.on( types, selector, data, fn ); - }, - undelegate: function( selector, types, fn ) { - // ( namespace ) or ( selector, types [, fn] ) - return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); - } -}); -var - // Document location - ajaxLocParts, - ajaxLocation, - ajax_nonce = jQuery.now(), - - ajax_rquery = /\?/, - rhash = /#.*$/, - rts = /([?&])_=[^&]*/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - 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 = {}, - - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = "*/".concat("*"); - -// #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 = "*"; - } - - var dataType, - i = 0, - dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || []; - - if ( jQuery.isFunction( func ) ) { - // For each dataType in the dataTypeExpression - while ( (dataType = dataTypes[i++]) ) { - // Prepend if requested - if ( dataType[0] === "+" ) { - dataType = dataType.slice( 1 ) || "*"; - (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); - - // Otherwise append - } else { - (structure[ dataType ] = structure[ dataType ] || []).push( func ); - } - } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { - - var inspected = {}, - seekingTransport = ( structure === transports ); - - function inspect( dataType ) { - var selected; - inspected[ dataType ] = true; - jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { - var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); - if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { - options.dataTypes.unshift( dataTypeOrTransport ); - inspect( dataTypeOrTransport ); - return false; - } else if ( seekingTransport ) { - return !( selected = dataTypeOrTransport ); - } - }); - return selected; - } - - return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); -} - -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var deep, key, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; - } - } - if ( deep ) { - jQuery.extend( true, target, deep ); - } - - return target; -} - -jQuery.fn.load = function( url, params, callback ) { - if ( typeof url !== "string" && _load ) { - return _load.apply( this, arguments ); - } - - var selector, response, type, - self = this, - off = url.indexOf(" "); - - if ( off >= 0 ) { - selector = url.slice( off, url.length ); - url = url.slice( 0, off ); - } - - // 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 ( params && typeof params === "object" ) { - type = "POST"; - } - - // If we have elements to modify, make the request - if ( self.length > 0 ) { - jQuery.ajax({ - url: url, - - // if "type" variable is undefined, then "GET" method will be used - type: type, - dataType: "html", - data: params - }).done(function( responseText ) { - - // Save response for use in complete callback - response = arguments; - - self.html( selector ? - - // If a selector was specified, locate the right elements in a dummy div - // Exclude scripts to avoid IE 'Permission Denied' errors - jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : - - // Otherwise use the full result - responseText ); - - }).complete( callback && function( jqXHR, status ) { - self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); - }); - } - - return this; -}; - -// Attach a bunch of functions for handling common AJAX events -jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){ - jQuery.fn[ type ] = function( fn ){ - return this.on( type, fn ); - }; -}); - -jQuery.extend({ - - // Counter for holding the number of active queries - active: 0, - - // Last-Modified header cache for next request - lastModified: {}, - etag: {}, - - ajaxSettings: { - url: ajaxLocation, - type: "GET", - isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), - global: true, - processData: true, - async: true, - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - throws: false, - traditional: false, - headers: {}, - */ - - accepts: { - "*": allTypes, - text: "text/plain", - html: "text/html", - xml: "application/xml, text/xml", - json: "application/json, text/javascript" - }, - - contents: { - xml: /xml/, - html: /html/, - json: /json/ - }, - - responseFields: { - xml: "responseXML", - text: "responseText", - json: "responseJSON" - }, - - // Data converters - // Keys separate source (or catchall "*") and destination types with a single space - converters: { - - // Convert anything to text - "* text": 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 - }, - - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - url: true, - context: true - } - }, - - // 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 ) { - return settings ? - - // Building a settings object - ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : - - // Extending ajaxSettings - ajaxExtend( jQuery.ajaxSettings, target ); - }, - - 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 // Cross-domain detection vars - parts, - // Loop variable - i, - // URL without anti-cache param - cacheURL, - // Response headers as string - responseHeadersString, - // timeout handle - timeoutTimer, - - // To know if global events are to be dispatched - fireGlobals, - - transport, - // Response headers - responseHeaders, - // Create the final options object - s = jQuery.ajaxSetup( {}, options ), - // Callbacks context - callbackContext = s.context || s, - // Context for global events is callbackContext if it is a DOM node or jQuery collection - globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? - jQuery( callbackContext ) : - jQuery.event, - // Deferreds - deferred = jQuery.Deferred(), - completeDeferred = jQuery.Callbacks("once memory"), - // Status-dependent callbacks - statusCode = s.statusCode || {}, - // Headers (they are sent all at once) - requestHeaders = {}, - requestHeadersNames = {}, - // The jqXHR state - state = 0, - // Default abort message - strAbort = "canceled", - // Fake xhr - jqXHR = { - readyState: 0, - - // 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 == null ? null : match; - }, - - // Raw string - getAllResponseHeaders: function() { - return state === 2 ? responseHeadersString : null; - }, - - // Caches the header - setRequestHeader: function( name, value ) { - var lname = name.toLowerCase(); - if ( !state ) { - name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; - requestHeaders[ name ] = value; - } - return this; - }, - - // Overrides response content-type header - overrideMimeType: function( type ) { - if ( !state ) { - s.mimeType = type; - } - return this; - }, - - // Status-dependent callbacks - statusCode: function( map ) { - var code; - if ( map ) { - if ( state < 2 ) { - for ( code in map ) { - // Lazy-add the new callback in a way that preserves old ones - statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; - } - } else { - // Execute the appropriate callbacks - jqXHR.always( map[ jqXHR.status ] ); - } - } - return this; - }, - - // Cancel the request - abort: function( statusText ) { - var finalText = statusText || strAbort; - if ( transport ) { - transport.abort( finalText ); - } - done( 0, finalText ); - return this; - } - }; - - // Attach deferreds - deferred.promise( jqXHR ).complete = completeDeferred.add; - jqXHR.success = jqXHR.done; - jqXHR.error = jqXHR.fail; - - // Remove hash character (#7531: and string promotion) - // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) - // Handle falsy url in the settings object (#10093: consistency with old signature) - // We also use the url parameter if available - s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); - - // Alias method option to type as per ticket #12004 - s.type = options.method || options.type || s.method || s.type; - - // Extract dataTypes list - s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""]; - - // A cross-domain request is in order when we have a protocol:host:port mismatch - 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 prefilter, stop there - if ( state === 2 ) { - return jqXHR; - } - - // We can fire global events as of now if asked to - fireGlobals = s.global; - - // Watch for a new set of requests - if ( fireGlobals && jQuery.active++ === 0 ) { - jQuery.event.trigger("ajaxStart"); - } - - // Uppercase the type - s.type = s.type.toUpperCase(); - - // Determine if request has content - s.hasContent = !rnoContent.test( s.type ); - - // Save the URL in case we're toying with the If-Modified-Since - // and/or If-None-Match header later on - cacheURL = s.url; - - // More options handling for requests with no content - if ( !s.hasContent ) { - - // If data is available, append data to url - if ( s.data ) { - cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); - // #9682: remove data so that it's not used in an eventual retry - delete s.data; - } - - // Add anti-cache in url if needed - if ( s.cache === false ) { - s.url = rts.test( cacheURL ) ? - - // If there is already a '_' parameter, set its value - cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) : - - // Otherwise add one to the end - cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++; - } - } - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - if ( jQuery.lastModified[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); - } - if ( jQuery.etag[ cacheURL ] ) { - jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); - } - } - - // 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 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 ] !== "*" ? ", " + allTypes + "; 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 and return - return jqXHR.abort(); - } - - // aborting is no longer a cancellation - strAbort = "abort"; - - // 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 ( state < 2 ) { - done( -1, e ); - // Simply rethrow otherwise - } else { - throw e; - } - } - } - - // Callback for when everything is done - function done( status, nativeStatusText, responses, headers ) { - var isSuccess, success, error, response, modified, - statusText = nativeStatusText; - - // 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 > 0 ? 4 : 0; - - // Determine if successful - isSuccess = status >= 200 && status < 300 || status === 304; - - // Get response data - if ( responses ) { - response = ajaxHandleResponses( s, jqXHR, responses ); - } - - // Convert no matter what (that way responseXXX fields are always set) - response = ajaxConvert( s, response, jqXHR, isSuccess ); - - // If successful, handle type chaining - if ( isSuccess ) { - - // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. - if ( s.ifModified ) { - modified = jqXHR.getResponseHeader("Last-Modified"); - if ( modified ) { - jQuery.lastModified[ cacheURL ] = modified; - } - modified = jqXHR.getResponseHeader("etag"); - if ( modified ) { - jQuery.etag[ cacheURL ] = modified; - } - } - - // if no content - if ( status === 204 || s.type === "HEAD" ) { - statusText = "nocontent"; - - // if not modified - } else if ( status === 304 ) { - statusText = "notmodified"; - - // If we have data, let's convert it - } else { - statusText = response.state; - success = response.data; - error = response.error; - isSuccess = !error; - } - } else { - // We extract error from statusText - // then normalize statusText and status for non-aborts - error = statusText; - if ( status || !statusText ) { - statusText = "error"; - if ( status < 0 ) { - status = 0; - } - } - } - - // Set data for the fake xhr object - jqXHR.status = status; - jqXHR.statusText = ( nativeStatusText || 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( isSuccess ? "ajaxSuccess" : "ajaxError", - [ jqXHR, s, isSuccess ? success : error ] ); - } - - // Complete - completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); - - if ( fireGlobals ) { - globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); - // Handle the global AJAX counter - if ( !( --jQuery.active ) ) { - jQuery.event.trigger("ajaxStop"); - } - } - } - - return jqXHR; - }, - - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, - - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - } -}); - -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({ - url: url, - type: method, - dataType: type, - data: data, - success: callback - }); - }; -}); - -/* Handles responses to an ajax request: - * - finds the right dataType (mediates between content-type and expected dataType) - * - returns the corresponding response - */ -function ajaxHandleResponses( s, jqXHR, responses ) { - var firstDataType, ct, finalDataType, type, - contents = s.contents, - dataTypes = s.dataTypes; - - // 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 - * Also sets the responseXXX fields on the jqXHR instance - */ -function ajaxConvert( s, response, jqXHR, isSuccess ) { - var conv2, current, conv, tmp, prev, - converters = {}, - // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(); - - // Create converters map with lowercased keys - if ( dataTypes[ 1 ] ) { - for ( conv in s.converters ) { - converters[ conv.toLowerCase() ] = s.converters[ conv ]; - } - } - - current = dataTypes.shift(); - - // Convert to each sequential dataType - while ( current ) { - - if ( s.responseFields[ current ] ) { - jqXHR[ s.responseFields[ current ] ] = response; - } - - // Apply the dataFilter if provided - if ( !prev && isSuccess && s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } - - prev = current; - current = dataTypes.shift(); - - if ( current ) { - - // There's only work to do if current dataType is non-auto - if ( current === "*" ) { - - current = prev; - - // Convert response if prev dataType is non-auto and differs from current - } else if ( prev !== "*" && prev !== current ) { - - // Seek a direct converter - conv = converters[ prev + " " + current ] || converters[ "* " + current ]; - - // If none found, seek a pair - if ( !conv ) { - for ( conv2 in converters ) { - - // If conv2 outputs current - tmp = conv2.split( " " ); - if ( tmp[ 1 ] === current ) { - - // If prev can be converted to accepted input - conv = converters[ prev + " " + tmp[ 0 ] ] || - converters[ "* " + tmp[ 0 ] ]; - if ( conv ) { - // Condense equivalence converters - if ( conv === true ) { - conv = converters[ conv2 ]; - - // Otherwise, insert the intermediate dataType - } else if ( converters[ conv2 ] !== true ) { - current = tmp[ 0 ]; - dataTypes.unshift( tmp[ 1 ] ); - } - break; - } - } - } - } - - // Apply converter (if not an equivalence) - if ( conv !== true ) { - - // Unless errors are allowed to bubble, catch and return them - if ( conv && s[ "throws" ] ) { - response = conv( response ); - } else { - try { - response = conv( response ); - } catch ( e ) { - return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; - } - } - } - } - } - } - - return { state: "success", data: response }; -} -// Install script dataType -jQuery.ajaxSetup({ - accepts: { - script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" - }, - contents: { - script: /(?:java|ecma)script/ - }, - 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 || jQuery("head")[0] || document.documentElement; - - return { - - send: function( _, callback ) { - - script = document.createElement("script"); - - script.async = true; - - 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 ( script.parentNode ) { - script.parentNode.removeChild( script ); - } - - // Dereference the script - script = null; - - // Callback if not abort - if ( !isAbort ) { - callback( 200, "success" ); - } - } - }; - - // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending - // Use native DOM manipulation to avoid our domManip AJAX trickery - head.insertBefore( script, head.firstChild ); - }, - - abort: function() { - if ( script ) { - script.onload( undefined, true ); - } - } - }; - } -}); -var oldCallbacks = [], - rjsonp = /(=)\?(?=&|$)|\?\?/; - -// Default jsonp settings -jQuery.ajaxSetup({ - jsonp: "callback", - jsonpCallback: function() { - var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) ); - this[ callback ] = true; - return callback; - } -}); - -// Detect, normalize options and install callbacks for jsonp requests -jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { - - var callbackName, overwritten, responseContainer, - jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? - "url" : - typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" - ); - - // Handle iff the expected data type is "jsonp" or we have a parameter to set - if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { - - // Get callback name, remembering preexisting value associated with it - callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? - s.jsonpCallback() : - s.jsonpCallback; - - // Insert callback into url or form data - if ( jsonProp ) { - s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); - } else if ( s.jsonp !== false ) { - s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; - } - - // Use data converter to retrieve json after script execution - s.converters["script json"] = function() { - if ( !responseContainer ) { - jQuery.error( callbackName + " was not called" ); - } - return responseContainer[ 0 ]; - }; - - // force json dataType - s.dataTypes[ 0 ] = "json"; - - // Install callback - overwritten = window[ callbackName ]; - window[ callbackName ] = function() { - responseContainer = arguments; - }; - - // Clean-up function (fires after converters) - jqXHR.always(function() { - // Restore preexisting value - window[ callbackName ] = overwritten; - - // Save back as free - if ( s[ callbackName ] ) { - // make sure that re-using the options doesn't screw things around - s.jsonpCallback = originalSettings.jsonpCallback; - - // save the callback name for future use - oldCallbacks.push( callbackName ); - } - - // Call if it was a function and we have a response - if ( responseContainer && jQuery.isFunction( overwritten ) ) { - overwritten( responseContainer[ 0 ] ); - } - - responseContainer = overwritten = undefined; - }); - - // Delegate to script - return "script"; - } -}); -var xhrCallbacks, xhrSupported, - xhrId = 0, - // #5280: Internet Explorer will keep connections alive if we don't abort on unload - xhrOnUnloadAbort = window.ActiveXObject && function() { - // Abort all pending requests - var key; - for ( key in xhrCallbacks ) { - xhrCallbacks[ key ]( undefined, true ); - } - }; - -// 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 -xhrSupported = jQuery.ajaxSettings.xhr(); -jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); -xhrSupported = jQuery.support.ajax = !!xhrSupported; - -// Create transport if the browser can provide an xhr -if ( xhrSupported ) { - - 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 handle, i, - xhr = s.xhr(); - - // 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( err ) {} - - // 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, responseHeaders, statusText, responses; - - // Firefox throws exceptions when accessing properties - // of an xhr when a network error occurred - // 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 { - responses = {}; - status = xhr.status; - responseHeaders = xhr.getAllResponseHeaders(); - - // When requesting binary data, IE6-9 will throw an exception - // on any attempt to access responseText (#11426) - if ( typeof xhr.responseText === "string" ) { - 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 ( !s.async ) { - // if we're in sync mode we fire the callback - callback(); - } else if ( xhr.readyState === 4 ) { - // (IE6 & IE7) if it's in cache and has been - // retrieved directly we need to fire the callback - setTimeout( 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( undefined, true ); - } - } - }; - } - }); -} -var fxNow, timerId, - rfxtypes = /^(?:toggle|show|hide)$/, - rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), - rrun = /queueHooks$/, - animationPrefilters = [ defaultPrefilter ], - tweeners = { - "*": [function( prop, value ) { - var tween = this.createTween( prop, value ), - target = tween.cur(), - parts = rfxnum.exec( value ), - unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), - - // Starting value computation is required for potential unit mismatches - start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && - rfxnum.exec( jQuery.css( tween.elem, prop ) ), - scale = 1, - maxIterations = 20; - - if ( start && start[ 3 ] !== unit ) { - // Trust units reported by jQuery.css - unit = unit || start[ 3 ]; - - // Make sure we update the tween properties later on - parts = parts || []; - - // Iteratively approximate from a nonzero starting point - start = +target || 1; - - do { - // If previous iteration zeroed out, double until we get *something* - // Use a string for doubling factor so we don't accidentally see scale as unchanged below - scale = scale || ".5"; - - // Adjust and apply - start = start / scale; - jQuery.style( tween.elem, prop, start + unit ); - - // Update scale, tolerating zero or NaN from tween.cur() - // And breaking the loop if scale is unchanged or perfect, or if we've just had enough - } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); - } - - // Update tween properties - if ( parts ) { - start = tween.start = +start || +target || 0; - tween.unit = unit; - // If a +=/-= token was provided, we're doing a relative animation - tween.end = parts[ 1 ] ? - start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : - +parts[ 2 ]; - } - - return tween; - }] - }; - -// Animations created synchronously will run synchronously -function createFxNow() { - setTimeout(function() { - fxNow = undefined; - }); - return ( fxNow = jQuery.now() ); -} - -function createTween( value, prop, animation ) { - var tween, - collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), - index = 0, - length = collection.length; - for ( ; index < length; index++ ) { - if ( (tween = collection[ index ].call( animation, prop, value )) ) { - - // we're done with this property - return tween; - } - } -} - -function Animation( elem, properties, options ) { - var result, - stopped, - index = 0, - length = animationPrefilters.length, - deferred = jQuery.Deferred().always( function() { - // don't match elem in the :animated selector - delete tick.elem; - }), - tick = function() { - if ( stopped ) { - return false; - } - var currentTime = fxNow || createFxNow(), - remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), - // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) - temp = remaining / animation.duration || 0, - percent = 1 - temp, - index = 0, - length = animation.tweens.length; - - for ( ; index < length ; index++ ) { - animation.tweens[ index ].run( percent ); - } - - deferred.notifyWith( elem, [ animation, percent, remaining ]); - - if ( percent < 1 && length ) { - return remaining; - } else { - deferred.resolveWith( elem, [ animation ] ); - return false; - } - }, - animation = deferred.promise({ - elem: elem, - props: jQuery.extend( {}, properties ), - opts: jQuery.extend( true, { specialEasing: {} }, options ), - originalProperties: properties, - originalOptions: options, - startTime: fxNow || createFxNow(), - duration: options.duration, - tweens: [], - createTween: function( prop, end ) { - var tween = jQuery.Tween( elem, animation.opts, prop, end, - animation.opts.specialEasing[ prop ] || animation.opts.easing ); - animation.tweens.push( tween ); - return tween; - }, - stop: function( gotoEnd ) { - var index = 0, - // if we are going to the end, we want to run all the tweens - // otherwise we skip this part - length = gotoEnd ? animation.tweens.length : 0; - if ( stopped ) { - return this; - } - stopped = true; - for ( ; index < length ; index++ ) { - animation.tweens[ index ].run( 1 ); - } - - // resolve when we played the last frame - // otherwise, reject - if ( gotoEnd ) { - deferred.resolveWith( elem, [ animation, gotoEnd ] ); - } else { - deferred.rejectWith( elem, [ animation, gotoEnd ] ); - } - return this; - } - }), - props = animation.props; - - propFilter( props, animation.opts.specialEasing ); - - for ( ; index < length ; index++ ) { - result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); - if ( result ) { - return result; - } - } - - jQuery.map( props, createTween, animation ); - - if ( jQuery.isFunction( animation.opts.start ) ) { - animation.opts.start.call( elem, animation ); - } - - jQuery.fx.timer( - jQuery.extend( tick, { - elem: elem, - anim: animation, - queue: animation.opts.queue - }) - ); - - // attach callbacks from options - return animation.progress( animation.opts.progress ) - .done( animation.opts.done, animation.opts.complete ) - .fail( animation.opts.fail ) - .always( animation.opts.always ); -} - -function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; - - // camelCase, specialEasing and expand cssHook pass - for ( index in props ) { - name = jQuery.camelCase( index ); - easing = specialEasing[ name ]; - value = props[ index ]; - if ( jQuery.isArray( value ) ) { - easing = value[ 1 ]; - value = props[ index ] = value[ 0 ]; - } - - if ( index !== name ) { - props[ name ] = value; - delete props[ index ]; - } - - hooks = jQuery.cssHooks[ name ]; - if ( hooks && "expand" in hooks ) { - value = hooks.expand( value ); - delete props[ name ]; - - // not quite $.extend, this wont overwrite keys already present. - // also - reusing 'index' from above because we have the correct "name" - for ( index in value ) { - if ( !( index in props ) ) { - props[ index ] = value[ index ]; - specialEasing[ index ] = easing; - } - } - } else { - specialEasing[ name ] = easing; - } - } -} - -jQuery.Animation = jQuery.extend( Animation, { - - tweener: function( props, callback ) { - if ( jQuery.isFunction( props ) ) { - callback = props; - props = [ "*" ]; - } else { - props = props.split(" "); - } - - var prop, - index = 0, - length = props.length; - - for ( ; index < length ; index++ ) { - prop = props[ index ]; - tweeners[ prop ] = tweeners[ prop ] || []; - tweeners[ prop ].unshift( callback ); - } - }, - - prefilter: function( callback, prepend ) { - if ( prepend ) { - animationPrefilters.unshift( callback ); - } else { - animationPrefilters.push( callback ); - } - } -}); - -function defaultPrefilter( elem, props, opts ) { - /* jshint validthis: true */ - var prop, value, toggle, tween, hooks, oldfire, - anim = this, - orig = {}, - style = elem.style, - hidden = elem.nodeType && isHidden( elem ), - dataShow = jQuery._data( elem, "fxshow" ); - - // handle queue: false promises - if ( !opts.queue ) { - hooks = jQuery._queueHooks( elem, "fx" ); - if ( hooks.unqueued == null ) { - hooks.unqueued = 0; - oldfire = hooks.empty.fire; - hooks.empty.fire = function() { - if ( !hooks.unqueued ) { - oldfire(); - } - }; - } - hooks.unqueued++; - - anim.always(function() { - // doing this makes sure that the complete handler will be called - // before this completes - anim.always(function() { - hooks.unqueued--; - if ( !jQuery.queue( elem, "fx" ).length ) { - hooks.empty.fire(); - } - }); - }); - } - - // height/width overflow pass - if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { - // 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 - opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; - - // Set display property to inline-block for height/width - // animations on inline elements that are having width/height animated - if ( jQuery.css( elem, "display" ) === "inline" && - jQuery.css( elem, "float" ) === "none" ) { - - // inline-level elements accept inline-block; - // block-level elements need to be inline with layout - if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { - style.display = "inline-block"; - - } else { - style.zoom = 1; - } - } - } - - if ( opts.overflow ) { - style.overflow = "hidden"; - if ( !jQuery.support.shrinkWrapBlocks ) { - anim.always(function() { - style.overflow = opts.overflow[ 0 ]; - style.overflowX = opts.overflow[ 1 ]; - style.overflowY = opts.overflow[ 2 ]; - }); - } - } - - - // show/hide pass - for ( prop in props ) { - value = props[ prop ]; - if ( rfxtypes.exec( value ) ) { - delete props[ prop ]; - toggle = toggle || value === "toggle"; - if ( value === ( hidden ? "hide" : "show" ) ) { - continue; - } - orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); - } - } - - if ( !jQuery.isEmptyObject( orig ) ) { - if ( dataShow ) { - if ( "hidden" in dataShow ) { - hidden = dataShow.hidden; - } - } else { - dataShow = jQuery._data( elem, "fxshow", {} ); - } - - // store state if its toggle - enables .stop().toggle() to "reverse" - if ( toggle ) { - dataShow.hidden = !hidden; - } - if ( hidden ) { - jQuery( elem ).show(); - } else { - anim.done(function() { - jQuery( elem ).hide(); - }); - } - anim.done(function() { - var prop; - jQuery._removeData( elem, "fxshow" ); - for ( prop in orig ) { - jQuery.style( elem, prop, orig[ prop ] ); - } - }); - for ( prop in orig ) { - tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); - - if ( !( prop in dataShow ) ) { - dataShow[ prop ] = tween.start; - if ( hidden ) { - tween.end = tween.start; - tween.start = prop === "width" || prop === "height" ? 1 : 0; - } - } - } - } -} - -function Tween( elem, options, prop, end, easing ) { - return new Tween.prototype.init( elem, options, prop, end, easing ); -} -jQuery.Tween = Tween; - -Tween.prototype = { - constructor: Tween, - init: function( elem, options, prop, end, easing, unit ) { - this.elem = elem; - this.prop = prop; - this.easing = easing || "swing"; - this.options = options; - this.start = this.now = this.cur(); - this.end = end; - this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); - }, - cur: function() { - var hooks = Tween.propHooks[ this.prop ]; - - return hooks && hooks.get ? - hooks.get( this ) : - Tween.propHooks._default.get( this ); - }, - run: function( percent ) { - var eased, - hooks = Tween.propHooks[ this.prop ]; - - if ( this.options.duration ) { - this.pos = eased = jQuery.easing[ this.easing ]( - percent, this.options.duration * percent, 0, 1, this.options.duration - ); - } else { - this.pos = eased = percent; - } - this.now = ( this.end - this.start ) * eased + this.start; - - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); - } - - if ( hooks && hooks.set ) { - hooks.set( this ); - } else { - Tween.propHooks._default.set( this ); - } - return this; - } -}; - -Tween.prototype.init.prototype = Tween.prototype; - -Tween.propHooks = { - _default: { - get: function( tween ) { - var result; - - if ( tween.elem[ tween.prop ] != null && - (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { - return tween.elem[ tween.prop ]; - } - - // passing an empty string as a 3rd parameter to .css will automatically - // attempt a parseFloat and fallback to a string if the parse fails - // so, simple values such as "10px" are parsed to Float. - // complex values such as "rotate(1rad)" are returned as is. - result = jQuery.css( tween.elem, tween.prop, "" ); - // Empty strings, null, undefined and "auto" are converted to 0. - return !result || result === "auto" ? 0 : result; - }, - set: function( tween ) { - // use step hook for back compat - use cssHook if its there - use .style if its - // available and use plain properties where available - if ( jQuery.fx.step[ tween.prop ] ) { - jQuery.fx.step[ tween.prop ]( tween ); - } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { - jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); - } else { - tween.elem[ tween.prop ] = tween.now; - } - } - } -}; - -// Support: IE <=9 -// Panic based approach to setting things on disconnected nodes - -Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { - set: function( tween ) { - if ( tween.elem.nodeType && tween.elem.parentNode ) { - tween.elem[ tween.prop ] = tween.now; - } - } -}; - -jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { - var cssFn = jQuery.fn[ name ]; - jQuery.fn[ name ] = function( speed, easing, callback ) { - return speed == null || typeof speed === "boolean" ? - cssFn.apply( this, arguments ) : - this.animate( genFx( name, true ), speed, easing, callback ); - }; -}); - -jQuery.fn.extend({ - fadeTo: function( speed, to, easing, callback ) { - - // show any hidden elements after setting opacity to 0 - return this.filter( isHidden ).css( "opacity", 0 ).show() - - // animate to the value specified - .end().animate({ opacity: to }, speed, easing, callback ); - }, - animate: function( prop, speed, easing, callback ) { - var empty = jQuery.isEmptyObject( prop ), - optall = jQuery.speed( speed, easing, callback ), - doAnimation = function() { - // Operate on a copy of prop so per-property easing won't be lost - var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations, or finishing resolves immediately - if ( empty || jQuery._data( this, "finish" ) ) { - anim.stop( true ); - } - }; - doAnimation.finish = doAnimation; - - return empty || optall.queue === false ? - this.each( doAnimation ) : - this.queue( optall.queue, doAnimation ); - }, - stop: function( type, clearQueue, gotoEnd ) { - var stopQueue = function( hooks ) { - var stop = hooks.stop; - delete hooks.stop; - stop( gotoEnd ); - }; - - if ( typeof type !== "string" ) { - gotoEnd = clearQueue; - clearQueue = type; - type = undefined; - } - if ( clearQueue && type !== false ) { - this.queue( type || "fx", [] ); - } - - return this.each(function() { - var dequeue = true, - index = type != null && type + "queueHooks", - timers = jQuery.timers, - data = jQuery._data( this ); - - if ( index ) { - if ( data[ index ] && data[ index ].stop ) { - stopQueue( data[ index ] ); - } - } else { - for ( index in data ) { - if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { - stopQueue( data[ index ] ); - } - } - } - - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { - timers[ index ].anim.stop( gotoEnd ); - dequeue = false; - timers.splice( index, 1 ); - } - } - - // start the next in the queue if the last step wasn't forced - // timers currently will call their complete callbacks, which will dequeue - // but only if they were gotoEnd - if ( dequeue || !gotoEnd ) { - jQuery.dequeue( this, type ); - } - }); - }, - finish: function( type ) { - if ( type !== false ) { - type = type || "fx"; - } - return this.each(function() { - var index, - data = jQuery._data( this ), - queue = data[ type + "queue" ], - hooks = data[ type + "queueHooks" ], - timers = jQuery.timers, - length = queue ? queue.length : 0; - - // enable finishing flag on private data - data.finish = true; - - // empty the queue first - jQuery.queue( this, type, [] ); - - if ( hooks && hooks.stop ) { - hooks.stop.call( this, true ); - } - - // look for any active animations, and finish them - for ( index = timers.length; index--; ) { - if ( timers[ index ].elem === this && timers[ index ].queue === type ) { - timers[ index ].anim.stop( true ); - timers.splice( index, 1 ); - } - } - - // look for any animations in the old queue and finish them - for ( index = 0; index < length; index++ ) { - if ( queue[ index ] && queue[ index ].finish ) { - queue[ index ].finish.call( this ); - } - } - - // turn off finishing flag - delete data.finish; - }); - } -}); - -// Generate parameters to create a standard animation -function genFx( type, includeWidth ) { - var which, - attrs = { height: type }, - i = 0; - - // if we include width, step value is 1 to do all cssExpand values, - // if we don't include width, step value is 2 to skip over Left and Right - includeWidth = includeWidth? 1 : 0; - for( ; i < 4 ; i += 2 - includeWidth ) { - which = cssExpand[ i ]; - attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; - } - - if ( includeWidth ) { - attrs.opacity = attrs.width = type; - } - - return attrs; -} - -// Generate shortcuts for custom animations -jQuery.each({ - slideDown: genFx("show"), - slideUp: genFx("hide"), - slideToggle: genFx("toggle"), - 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.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; - - // normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { - opt.queue = "fx"; - } - - // Queueing - opt.old = opt.complete; - - opt.complete = function() { - if ( jQuery.isFunction( opt.old ) ) { - opt.old.call( this ); - } - - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } - }; - - return opt; -}; - -jQuery.easing = { - linear: function( p ) { - return p; - }, - swing: function( p ) { - return 0.5 - Math.cos( p*Math.PI ) / 2; - } -}; - -jQuery.timers = []; -jQuery.fx = Tween.prototype.init; -jQuery.fx.tick = function() { - var timer, - timers = jQuery.timers, - i = 0; - - fxNow = jQuery.now(); - - for ( ; i < timers.length; i++ ) { - timer = timers[ i ]; - // Checks the timer has not already been removed - if ( !timer() && timers[ i ] === timer ) { - timers.splice( i--, 1 ); - } - } - - if ( !timers.length ) { - jQuery.fx.stop(); - } - fxNow = undefined; -}; - -jQuery.fx.timer = function( timer ) { - if ( timer() && jQuery.timers.push( timer ) ) { - jQuery.fx.start(); - } -}; - -jQuery.fx.interval = 13; - -jQuery.fx.start = function() { - if ( !timerId ) { - timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); - } -}; - -jQuery.fx.stop = function() { - clearInterval( timerId ); - timerId = null; -}; - -jQuery.fx.speeds = { - slow: 600, - fast: 200, - // Default speed - _default: 400 -}; - -// Back Compat <1.8 extension point -jQuery.fx.step = {}; - -if ( jQuery.expr && jQuery.expr.filters ) { - jQuery.expr.filters.animated = function( elem ) { - return jQuery.grep(jQuery.timers, function( fn ) { - return elem === fn.elem; - }).length; - }; -} -jQuery.fn.offset = function( options ) { - if ( arguments.length ) { - return options === undefined ? - this : - this.each(function( i ) { - jQuery.offset.setOffset( this, options, i ); - }); - } - - var docElem, win, - box = { top: 0, left: 0 }, - elem = this[ 0 ], - doc = elem && elem.ownerDocument; - - if ( !doc ) { - return; - } - - docElem = doc.documentElement; - - // Make sure it's not a disconnected DOM node - if ( !jQuery.contains( docElem, elem ) ) { - return box; - } - - // If we don't have gBCR, just use 0,0 rather than error - // BlackBerry 5, iOS 3 (original iPhone) - if ( typeof elem.getBoundingClientRect !== core_strundefined ) { - box = elem.getBoundingClientRect(); - } - win = getWindow( doc ); - return { - top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ), - left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ) - }; -}; - -jQuery.offset = { - - 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; - } - - var offsetParent, offset, - parentOffset = { top: 0, left: 0 }, - elem = this[ 0 ]; - - // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent - if ( jQuery.css( elem, "position" ) === "fixed" ) { - // we assume that getBoundingClientRect is available when computed position is fixed - offset = elem.getBoundingClientRect(); - } else { - // Get *real* offsetParent - offsetParent = this.offsetParent(); - - // Get correct offsets - offset = this.offset(); - if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { - parentOffset = offsetParent.offset(); - } - - // Add offsetParent borders - parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); - parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); - } - - // Subtract parent offsets and 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 - return { - top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), - left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true) - }; - }, - - offsetParent: function() { - return this.map(function() { - var offsetParent = this.offsetParent || docElem; - while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) { - offsetParent = offsetParent.offsetParent; - } - return offsetParent || docElem; - }); - } -}); - - -// Create scrollLeft and scrollTop methods -jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { - var top = /Y/.test( prop ); - - jQuery.fn[ method ] = function( val ) { - return jQuery.access( this, function( elem, method, val ) { - var win = getWindow( elem ); - - if ( val === undefined ) { - return win ? (prop in win) ? win[ prop ] : - win.document.documentElement[ method ] : - elem[ method ]; - } - - if ( win ) { - win.scrollTo( - !top ? val : jQuery( win ).scrollLeft(), - top ? val : jQuery( win ).scrollTop() - ); - - } else { - elem[ method ] = val; - } - }, method, val, arguments.length, null ); - }; -}); - -function getWindow( elem ) { - return jQuery.isWindow( elem ) ? - elem : - elem.nodeType === 9 ? - elem.defaultView || elem.parentWindow : - false; -} -// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods -jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { - jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { - // margin is only for outerHeight, outerWidth - jQuery.fn[ funcName ] = function( margin, value ) { - var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), - extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); - - return jQuery.access( this, function( elem, type, value ) { - var doc; - - if ( jQuery.isWindow( elem ) ) { - // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there - // isn't a whole lot we can do. See pull request at this URL for discussion: - // https://github.com/jquery/jquery/pull/764 - return elem.document.documentElement[ "client" + name ]; - } - - // Get document width or height - if ( elem.nodeType === 9 ) { - doc = elem.documentElement; - - // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest - // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. - return Math.max( - elem.body[ "scroll" + name ], doc[ "scroll" + name ], - elem.body[ "offset" + name ], doc[ "offset" + name ], - doc[ "client" + name ] - ); - } - - return value === undefined ? - // Get width or height on the element, requesting but not forcing parseFloat - jQuery.css( elem, type, extra ) : - - // Set width or height on the element - jQuery.style( elem, type, value, extra ); - }, type, chainable ? margin : undefined, chainable, null ); - }; - }); -}); -// Limit scope pollution from any deprecated API -// (function() { - -// The number of elements contained in the matched element set -jQuery.fn.size = function() { - return this.length; -}; - -jQuery.fn.andSelf = jQuery.fn.addBack; - -// })(); -if ( typeof module === "object" && module && typeof module.exports === "object" ) { - // Expose jQuery as module.exports in loaders that implement the Node - // module pattern (including browserify). Do not create the global, since - // the user will be storing it themselves locally, and globals are frowned - // upon in the Node module world. - module.exports = jQuery; -} else { - // Otherwise expose jQuery to the global object as usual - window.jQuery = window.$ = jQuery; - - // Register as a named AMD module, since jQuery can be concatenated with other - // files that may use define, but not via a proper concatenation script that - // understands anonymous AMD modules. A named AMD is safest and most robust - // way to register. Lowercase jquery is used because AMD module names are - // derived from file names, and jQuery is normally delivered in a lowercase - // file name. Do this after creating the global so that if an AMD module wants - // to call noConflict to hide this version of jQuery, it will work. - if ( typeof define === "function" && define.amd ) { - define( "jquery", [], function () { return jQuery; } ); - } -} - -})( window ); diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.js deleted file mode 100644 index 51aa758be2e7711b065030a454c2685cca2b1ccf..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.js +++ /dev/null @@ -1,23 +0,0 @@ -/* NUGET: BEGIN LICENSE TEXT - * - * Microsoft grants you the right to use these script files for the sole - * purpose of either: (i) interacting through your browser with the Microsoft - * website or online service, subject to the applicable licensing or use - * terms; or (ii) using the files as included with a Microsoft product subject - * to that product's license terms. Microsoft reserves all other rights to the - * files not expressly granted by Microsoft, whether by implication, estoppel - * or otherwise. Insofar as a script file is dual licensed under GPL, - * Microsoft neither took the code under GPL nor distributes it thereunder but - * under the terms set out in this paragraph. All notices and licenses - * below are for informational purposes only. - * - * JQUERY CORE 1.10.2; Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; http://jquery.org/license - * Includes Sizzle.js; Copyright 2013 jQuery Foundation, Inc. and other contributors; http://opensource.org/licenses/MIT - * - * NUGET: END LICENSE TEXT */ -/*! jQuery v1.10.2 | (c) 2005, 2013 jQuery Foundation, Inc. | jquery.org/license -//@ sourceMappingURL=jquery-1.10.2.min.map -*/ -(function(e,t){var n,r,i=typeof t,o=e.location,a=e.document,s=a.documentElement,l=e.jQuery,u=e.$,c={},p=[],f="1.10.2",d=p.concat,h=p.push,g=p.slice,m=p.indexOf,y=c.toString,v=c.hasOwnProperty,b=f.trim,x=function(e,t){return new x.fn.init(e,t,r)},w=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=/\S+/g,C=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,k=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,E=/^[\],:{}\s]*$/,S=/(?:^|:|,)(?:\s*\[)+/g,A=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,j=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,D=/^-ms-/,L=/-([\da-z])/gi,H=function(e,t){return t.toUpperCase()},q=function(e){(a.addEventListener||"load"===e.type||"complete"===a.readyState)&&(_(),x.ready())},_=function(){a.addEventListener?(a.removeEventListener("DOMContentLoaded",q,!1),e.removeEventListener("load",q,!1)):(a.detachEvent("onreadystatechange",q),e.detachEvent("onload",q))};x.fn=x.prototype={jquery:f,constructor:x,init:function(e,n,r){var i,o;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof x?n[0]:n,x.merge(this,x.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:a,!0)),k.test(i[1])&&x.isPlainObject(n))for(i in n)x.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(o=a.getElementById(i[2]),o&&o.parentNode){if(o.id!==i[2])return r.find(e);this.length=1,this[0]=o}return this.context=a,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):x.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),x.makeArray(e,this))},selector:"",length:0,toArray:function(){return g.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=x.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return x.each(this,e,t)},ready:function(e){return x.ready.promise().done(e),this},slice:function(){return this.pushStack(g.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(x.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:h,sort:[].sort,splice:[].splice},x.fn.init.prototype=x.fn,x.extend=x.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},l=1,u=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},l=2),"object"==typeof s||x.isFunction(s)||(s={}),u===l&&(s=this,--l);u>l;l++)if(null!=(o=arguments[l]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(x.isPlainObject(r)||(n=x.isArray(r)))?(n?(n=!1,a=e&&x.isArray(e)?e:[]):a=e&&x.isPlainObject(e)?e:{},s[i]=x.extend(c,a,r)):r!==t&&(s[i]=r));return s},x.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),noConflict:function(t){return e.$===x&&(e.$=u),t&&e.jQuery===x&&(e.jQuery=l),x},isReady:!1,readyWait:1,holdReady:function(e){e?x.readyWait++:x.ready(!0)},ready:function(e){if(e===!0?!--x.readyWait:!x.isReady){if(!a.body)return setTimeout(x.ready);x.isReady=!0,e!==!0&&--x.readyWait>0||(n.resolveWith(a,[x]),x.fn.trigger&&x(a).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===x.type(e)},isArray:Array.isArray||function(e){return"array"===x.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?c[y.call(e)]||"object":typeof e},isPlainObject:function(e){var n;if(!e||"object"!==x.type(e)||e.nodeType||x.isWindow(e))return!1;try{if(e.constructor&&!v.call(e,"constructor")&&!v.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(r){return!1}if(x.support.ownLast)for(n in e)return v.call(e,n);for(n in e);return n===t||v.call(e,n)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||a;var r=k.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=x.buildFragment([e],t,i),i&&x(i).remove(),x.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=x.trim(n),n&&E.test(n.replace(A,"@").replace(j,"]").replace(S,"")))?Function("return "+n)():(x.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||x.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&x.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(D,"ms-").replace(L,H)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:b&&!b.call("\ufeff\u00a0")?function(e){return null==e?"":b.call(e)}:function(e){return null==e?"":(e+"").replace(C,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?x.merge(n,"string"==typeof e?[e]:e):h.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(m)return m.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return d.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),x.isFunction(e)?(r=g.call(arguments,2),i=function(){return e.apply(n||this,r.concat(g.call(arguments)))},i.guid=e.guid=e.guid||x.guid++,i):t},access:function(e,n,r,i,o,a,s){var l=0,u=e.length,c=null==r;if("object"===x.type(r)){o=!0;for(l in r)x.access(e,n,l,r[l],!0,a,s)}else if(i!==t&&(o=!0,x.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(x(e),n)})),n))for(;u>l;l++)n(e[l],r,s?i:i.call(e[l],l,n(e[l],r)));return o?e:c?n.call(e):u?n(e[0],r):a},now:function(){return(new Date).getTime()},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),x.ready.promise=function(t){if(!n)if(n=x.Deferred(),"complete"===a.readyState)setTimeout(x.ready);else if(a.addEventListener)a.addEventListener("DOMContentLoaded",q,!1),e.addEventListener("load",q,!1);else{a.attachEvent("onreadystatechange",q),e.attachEvent("onload",q);var r=!1;try{r=null==e.frameElement&&a.documentElement}catch(i){}r&&r.doScroll&&function o(){if(!x.isReady){try{r.doScroll("left")}catch(e){return setTimeout(o,50)}_(),x.ready()}}()}return n.promise(t)},x.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){c["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=x.type(e);return x.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=x(a),function(e,t){var n,r,i,o,a,s,l,u,c,p,f,d,h,g,m,y,v,b="sizzle"+-new Date,w=e.document,T=0,C=0,N=st(),k=st(),E=st(),S=!1,A=function(e,t){return e===t?(S=!0,0):0},j=typeof t,D=1<<31,L={}.hasOwnProperty,H=[],q=H.pop,_=H.push,M=H.push,O=H.slice,F=H.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},B="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",P="[\\x20\\t\\r\\n\\f]",R="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",W=R.replace("w","w#"),$="\\["+P+"*("+R+")"+P+"*(?:([*^$|!~]?=)"+P+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+W+")|)|)"+P+"*\\]",I=":("+R+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+$.replace(3,8)+")*)|.*)\\)|)",z=RegExp("^"+P+"+|((?:^|[^\\\\])(?:\\\\.)*)"+P+"+$","g"),X=RegExp("^"+P+"*,"+P+"*"),U=RegExp("^"+P+"*([>+~]|"+P+")"+P+"*"),V=RegExp(P+"*[+~]"),Y=RegExp("="+P+"*([^\\]'\"]*)"+P+"*\\]","g"),J=RegExp(I),G=RegExp("^"+W+"$"),Q={ID:RegExp("^#("+R+")"),CLASS:RegExp("^\\.("+R+")"),TAG:RegExp("^("+R.replace("w","w*")+")"),ATTR:RegExp("^"+$),PSEUDO:RegExp("^"+I),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+P+"*(even|odd|(([+-]|)(\\d*)n|)"+P+"*(?:([+-]|)"+P+"*(\\d+)|))"+P+"*\\)|)","i"),bool:RegExp("^(?:"+B+")$","i"),needsContext:RegExp("^"+P+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+P+"*((?:-\\d)?\\d*)"+P+"*\\)|)(?=[^-]|$)","i")},K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,et=/^(?:input|select|textarea|button)$/i,tt=/^h\d$/i,nt=/'|\\/g,rt=RegExp("\\\\([\\da-f]{1,6}"+P+"?|("+P+")|.)","ig"),it=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:0>r?String.fromCharCode(r+65536):String.fromCharCode(55296|r>>10,56320|1023&r)};try{M.apply(H=O.call(w.childNodes),w.childNodes),H[w.childNodes.length].nodeType}catch(ot){M={apply:H.length?function(e,t){_.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function at(e,t,n,i){var o,a,s,l,u,c,d,m,y,x;if((t?t.ownerDocument||t:w)!==f&&p(t),t=t||f,n=n||[],!e||"string"!=typeof e)return n;if(1!==(l=t.nodeType)&&9!==l)return[];if(h&&!i){if(o=Z.exec(e))if(s=o[1]){if(9===l){if(a=t.getElementById(s),!a||!a.parentNode)return n;if(a.id===s)return n.push(a),n}else if(t.ownerDocument&&(a=t.ownerDocument.getElementById(s))&&v(t,a)&&a.id===s)return n.push(a),n}else{if(o[2])return M.apply(n,t.getElementsByTagName(e)),n;if((s=o[3])&&r.getElementsByClassName&&t.getElementsByClassName)return M.apply(n,t.getElementsByClassName(s)),n}if(r.qsa&&(!g||!g.test(e))){if(m=d=b,y=t,x=9===l&&e,1===l&&"object"!==t.nodeName.toLowerCase()){c=mt(e),(d=t.getAttribute("id"))?m=d.replace(nt,"\\$&"):t.setAttribute("id",m),m="[id='"+m+"'] ",u=c.length;while(u--)c[u]=m+yt(c[u]);y=V.test(e)&&t.parentNode||t,x=c.join(",")}if(x)try{return M.apply(n,y.querySelectorAll(x)),n}catch(T){}finally{d||t.removeAttribute("id")}}}return kt(e.replace(z,"$1"),t,n,i)}function st(){var e=[];function t(n,r){return e.push(n+=" ")>o.cacheLength&&delete t[e.shift()],t[n]=r}return t}function lt(e){return e[b]=!0,e}function ut(e){var t=f.createElement("div");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function ct(e,t){var n=e.split("|"),r=e.length;while(r--)o.attrHandle[n[r]]=t}function pt(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||D)-(~e.sourceIndex||D);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function ft(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function dt(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ht(e){return lt(function(t){return t=+t,lt(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}s=at.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},r=at.support={},p=at.setDocument=function(e){var n=e?e.ownerDocument||e:w,i=n.defaultView;return n!==f&&9===n.nodeType&&n.documentElement?(f=n,d=n.documentElement,h=!s(n),i&&i.attachEvent&&i!==i.top&&i.attachEvent("onbeforeunload",function(){p()}),r.attributes=ut(function(e){return e.className="i",!e.getAttribute("className")}),r.getElementsByTagName=ut(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),r.getElementsByClassName=ut(function(e){return e.innerHTML="<div class='a'></div><div class='a i'></div>",e.firstChild.className="i",2===e.getElementsByClassName("i").length}),r.getById=ut(function(e){return d.appendChild(e).id=b,!n.getElementsByName||!n.getElementsByName(b).length}),r.getById?(o.find.ID=function(e,t){if(typeof t.getElementById!==j&&h){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){return e.getAttribute("id")===t}}):(delete o.find.ID,o.filter.ID=function(e){var t=e.replace(rt,it);return function(e){var n=typeof e.getAttributeNode!==j&&e.getAttributeNode("id");return n&&n.value===t}}),o.find.TAG=r.getElementsByTagName?function(e,n){return typeof n.getElementsByTagName!==j?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},o.find.CLASS=r.getElementsByClassName&&function(e,n){return typeof n.getElementsByClassName!==j&&h?n.getElementsByClassName(e):t},m=[],g=[],(r.qsa=K.test(n.querySelectorAll))&&(ut(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||g.push("\\["+P+"*(?:value|"+B+")"),e.querySelectorAll(":checked").length||g.push(":checked")}),ut(function(e){var t=n.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("t",""),e.querySelectorAll("[t^='']").length&&g.push("[*^$]="+P+"*(?:''|\"\")"),e.querySelectorAll(":enabled").length||g.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),g.push(",.*:")})),(r.matchesSelector=K.test(y=d.webkitMatchesSelector||d.mozMatchesSelector||d.oMatchesSelector||d.msMatchesSelector))&&ut(function(e){r.disconnectedMatch=y.call(e,"div"),y.call(e,"[s!='']:x"),m.push("!=",I)}),g=g.length&&RegExp(g.join("|")),m=m.length&&RegExp(m.join("|")),v=K.test(d.contains)||d.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},A=d.compareDocumentPosition?function(e,t){if(e===t)return S=!0,0;var i=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t);return i?1&i||!r.sortDetached&&t.compareDocumentPosition(e)===i?e===n||v(w,e)?-1:t===n||v(w,t)?1:c?F.call(c,e)-F.call(c,t):0:4&i?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return S=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:c?F.call(c,e)-F.call(c,t):0;if(o===a)return pt(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?pt(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},n):f},at.matches=function(e,t){return at(e,null,null,t)},at.matchesSelector=function(e,t){if((e.ownerDocument||e)!==f&&p(e),t=t.replace(Y,"='$1']"),!(!r.matchesSelector||!h||m&&m.test(t)||g&&g.test(t)))try{var n=y.call(e,t);if(n||r.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(i){}return at(t,f,null,[e]).length>0},at.contains=function(e,t){return(e.ownerDocument||e)!==f&&p(e),v(e,t)},at.attr=function(e,n){(e.ownerDocument||e)!==f&&p(e);var i=o.attrHandle[n.toLowerCase()],a=i&&L.call(o.attrHandle,n.toLowerCase())?i(e,n,!h):t;return a===t?r.attributes||!h?e.getAttribute(n):(a=e.getAttributeNode(n))&&a.specified?a.value:null:a},at.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},at.uniqueSort=function(e){var t,n=[],i=0,o=0;if(S=!r.detectDuplicates,c=!r.sortStable&&e.slice(0),e.sort(A),S){while(t=e[o++])t===e[o]&&(i=n.push(o));while(i--)e.splice(n[i],1)}return e},a=at.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=a(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=a(t);return n},o=at.selectors={cacheLength:50,createPseudo:lt,match:Q,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(rt,it),e[3]=(e[4]||e[5]||"").replace(rt,it),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||at.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&at.error(e[0]),e},PSEUDO:function(e){var n,r=!e[5]&&e[2];return Q.CHILD.test(e[0])?null:(e[3]&&e[4]!==t?e[2]=e[4]:r&&J.test(r)&&(n=mt(r,!0))&&(n=r.indexOf(")",r.length-n)-r.length)&&(e[0]=e[0].slice(0,n),e[2]=r.slice(0,n)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(rt,it).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=N[e+" "];return t||(t=RegExp("(^|"+P+")"+e+"("+P+"|$)"))&&N(e,function(e){return t.test("string"==typeof e.className&&e.className||typeof e.getAttribute!==j&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=at.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,l){var u,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!l&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[b]||(m[b]={}),u=c[e]||[],d=u[0]===T&&u[1],f=u[0]===T&&u[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[T,d,f];break}}else if(v&&(u=(t[b]||(t[b]={}))[e])&&u[0]===T)f=u[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[b]||(p[b]={}))[e]=[T,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=o.pseudos[e]||o.setFilters[e.toLowerCase()]||at.error("unsupported pseudo: "+e);return r[b]?r(t):r.length>1?(n=[e,e,"",t],o.setFilters.hasOwnProperty(e.toLowerCase())?lt(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=F.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:lt(function(e){var t=[],n=[],r=l(e.replace(z,"$1"));return r[b]?lt(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:lt(function(e){return function(t){return at(e,t).length>0}}),contains:lt(function(e){return function(t){return(t.textContent||t.innerText||a(t)).indexOf(e)>-1}}),lang:lt(function(e){return G.test(e||"")||at.error("unsupported lang: "+e),e=e.replace(rt,it).toLowerCase(),function(t){var n;do if(n=h?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===d},focus:function(e){return e===f.activeElement&&(!f.hasFocus||f.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!o.pseudos.empty(e)},header:function(e){return tt.test(e.nodeName)},input:function(e){return et.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:ht(function(){return[0]}),last:ht(function(e,t){return[t-1]}),eq:ht(function(e,t,n){return[0>n?n+t:n]}),even:ht(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:ht(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:ht(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:ht(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}},o.pseudos.nth=o.pseudos.eq;for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})o.pseudos[n]=ft(n);for(n in{submit:!0,reset:!0})o.pseudos[n]=dt(n);function gt(){}gt.prototype=o.filters=o.pseudos,o.setFilters=new gt;function mt(e,t){var n,r,i,a,s,l,u,c=k[e+" "];if(c)return t?0:c.slice(0);s=e,l=[],u=o.preFilter;while(s){(!n||(r=X.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),l.push(i=[])),n=!1,(r=U.exec(s))&&(n=r.shift(),i.push({value:n,type:r[0].replace(z," ")}),s=s.slice(n.length));for(a in o.filter)!(r=Q[a].exec(s))||u[a]&&!(r=u[a](r))||(n=r.shift(),i.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?at.error(e):k(e,l).slice(0)}function yt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function vt(e,t,n){var r=t.dir,o=n&&"parentNode"===r,a=C++;return t.first?function(t,n,i){while(t=t[r])if(1===t.nodeType||o)return e(t,n,i)}:function(t,n,s){var l,u,c,p=T+" "+a;if(s){while(t=t[r])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[r])if(1===t.nodeType||o)if(c=t[b]||(t[b]={}),(u=c[r])&&u[0]===p){if((l=u[1])===!0||l===i)return l===!0}else if(u=c[r]=[p],u[1]=e(t,n,s)||i,u[1]===!0)return!0}}function bt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function xt(e,t,n,r,i){var o,a=[],s=0,l=e.length,u=null!=t;for(;l>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),u&&t.push(s));return a}function wt(e,t,n,r,i,o){return r&&!r[b]&&(r=wt(r)),i&&!i[b]&&(i=wt(i,o)),lt(function(o,a,s,l){var u,c,p,f=[],d=[],h=a.length,g=o||Nt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:xt(g,f,e,s,l),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,l),r){u=xt(y,d),r(u,[],s,l),c=u.length;while(c--)(p=u[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){u=[],c=y.length;while(c--)(p=y[c])&&u.push(m[c]=p);i(null,y=[],u,l)}c=y.length;while(c--)(p=y[c])&&(u=i?F.call(o,p):f[c])>-1&&(o[u]=!(a[u]=p))}}else y=xt(y===a?y.splice(h,y.length):y),i?i(null,a,y,l):M.apply(a,y)})}function Tt(e){var t,n,r,i=e.length,a=o.relative[e[0].type],s=a||o.relative[" "],l=a?1:0,c=vt(function(e){return e===t},s,!0),p=vt(function(e){return F.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==u)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;i>l;l++)if(n=o.relative[e[l].type])f=[vt(bt(f),n)];else{if(n=o.filter[e[l].type].apply(null,e[l].matches),n[b]){for(r=++l;i>r;r++)if(o.relative[e[r].type])break;return wt(l>1&&bt(f),l>1&&yt(e.slice(0,l-1).concat({value:" "===e[l-2].type?"*":""})).replace(z,"$1"),n,r>l&&Tt(e.slice(l,r)),i>r&&Tt(e=e.slice(r)),i>r&&yt(e))}f.push(n)}return bt(f)}function Ct(e,t){var n=0,r=t.length>0,a=e.length>0,s=function(s,l,c,p,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,C=u,N=s||a&&o.find.TAG("*",d&&l.parentNode||l),k=T+=null==C?1:Math.random()||.1;for(w&&(u=l!==f&&l,i=n);null!=(h=N[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,l,c)){p.push(h);break}w&&(T=k,i=++n)}r&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,r&&b!==v){g=0;while(m=t[g++])m(x,y,l,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=q.call(p));y=xt(y)}M.apply(p,y),w&&!s&&y.length>0&&v+t.length>1&&at.uniqueSort(p)}return w&&(T=k,u=C),x};return r?lt(s):s}l=at.compile=function(e,t){var n,r=[],i=[],o=E[e+" "];if(!o){t||(t=mt(e)),n=t.length;while(n--)o=Tt(t[n]),o[b]?r.push(o):i.push(o);o=E(e,Ct(i,r))}return o};function Nt(e,t,n){var r=0,i=t.length;for(;i>r;r++)at(e,t[r],n);return n}function kt(e,t,n,i){var a,s,u,c,p,f=mt(e);if(!i&&1===f.length){if(s=f[0]=f[0].slice(0),s.length>2&&"ID"===(u=s[0]).type&&r.getById&&9===t.nodeType&&h&&o.relative[s[1].type]){if(t=(o.find.ID(u.matches[0].replace(rt,it),t)||[])[0],!t)return n;e=e.slice(s.shift().value.length)}a=Q.needsContext.test(e)?0:s.length;while(a--){if(u=s[a],o.relative[c=u.type])break;if((p=o.find[c])&&(i=p(u.matches[0].replace(rt,it),V.test(s[0].type)&&t.parentNode||t))){if(s.splice(a,1),e=i.length&&yt(s),!e)return M.apply(n,i),n;break}}}return l(e,f)(i,t,!h,n,V.test(e)),n}r.sortStable=b.split("").sort(A).join("")===b,r.detectDuplicates=S,p(),r.sortDetached=ut(function(e){return 1&e.compareDocumentPosition(f.createElement("div"))}),ut(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||ct("type|href|height|width",function(e,n,r){return r?t:e.getAttribute(n,"type"===n.toLowerCase()?1:2)}),r.attributes&&ut(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||ct("value",function(e,n,r){return r||"input"!==e.nodeName.toLowerCase()?t:e.defaultValue}),ut(function(e){return null==e.getAttribute("disabled")})||ct(B,function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&i.specified?i.value:e[n]===!0?n.toLowerCase():null}),x.find=at,x.expr=at.selectors,x.expr[":"]=x.expr.pseudos,x.unique=at.uniqueSort,x.text=at.getText,x.isXMLDoc=at.isXML,x.contains=at.contains}(e);var O={};function F(e){var t=O[e]={};return x.each(e.match(T)||[],function(e,n){t[n]=!0}),t}x.Callbacks=function(e){e="string"==typeof e?O[e]||F(e):x.extend({},e);var n,r,i,o,a,s,l=[],u=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=l.length,n=!0;l&&o>a;a++)if(l[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,l&&(u?u.length&&c(u.shift()):r?l=[]:p.disable())},p={add:function(){if(l){var t=l.length;(function i(t){x.each(t,function(t,n){var r=x.type(n);"function"===r?e.unique&&p.has(n)||l.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=l.length:r&&(s=t,c(r))}return this},remove:function(){return l&&x.each(arguments,function(e,t){var r;while((r=x.inArray(t,l,r))>-1)l.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?x.inArray(e,l)>-1:!(!l||!l.length)},empty:function(){return l=[],o=0,this},disable:function(){return l=u=r=t,this},disabled:function(){return!l},lock:function(){return u=t,r||p.disable(),this},locked:function(){return!u},fireWith:function(e,t){return!l||i&&!u||(t=t||[],t=[e,t.slice?t.slice():t],n?u.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},x.extend({Deferred:function(e){var t=[["resolve","done",x.Callbacks("once memory"),"resolved"],["reject","fail",x.Callbacks("once memory"),"rejected"],["notify","progress",x.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return x.Deferred(function(n){x.each(t,function(t,o){var a=o[0],s=x.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&x.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?x.extend(e,r):r}},i={};return r.pipe=r.then,x.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=g.call(arguments),r=n.length,i=1!==r||e&&x.isFunction(e.promise)?r:0,o=1===i?e:x.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?g.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,l,u;if(r>1)for(s=Array(r),l=Array(r),u=Array(r);r>t;t++)n[t]&&x.isFunction(n[t].promise)?n[t].promise().done(a(t,u,n)).fail(o.reject).progress(a(t,l,s)):--i;return i||o.resolveWith(u,n),o.promise()}}),x.support=function(t){var n,r,o,s,l,u,c,p,f,d=a.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav></:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",o=d.getElementsByTagName("td"),o[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===o[0].offsetHeight,o[0].style.display="",o[1].style.display="none",t.reliableHiddenOffsets=p&&0===o[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",x.swap(l,null!=l.style.zoom?{zoom:1}:{},function(){t.boxSizing=4===d.offsetWidth}),e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(a.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(l.style.zoom=1)),l.removeChild(n),n=d=o=r=null)}),n=s=l=u=r=o=null,t -}({});var B=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;function R(e,n,r,i){if(x.acceptData(e)){var o,a,s=x.expando,l=e.nodeType,u=l?x.cache:e,c=l?e[s]:e[s]&&s;if(c&&u[c]&&(i||u[c].data)||r!==t||"string"!=typeof n)return c||(c=l?e[s]=p.pop()||x.guid++:s),u[c]||(u[c]=l?{}:{toJSON:x.noop}),("object"==typeof n||"function"==typeof n)&&(i?u[c]=x.extend(u[c],n):u[c].data=x.extend(u[c].data,n)),a=u[c],i||(a.data||(a.data={}),a=a.data),r!==t&&(a[x.camelCase(n)]=r),"string"==typeof n?(o=a[n],null==o&&(o=a[x.camelCase(n)])):o=a,o}}function W(e,t,n){if(x.acceptData(e)){var r,i,o=e.nodeType,a=o?x.cache:e,s=o?e[x.expando]:x.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){x.isArray(t)?t=t.concat(x.map(t,x.camelCase)):t in r?t=[t]:(t=x.camelCase(t),t=t in r?[t]:t.split(" ")),i=t.length;while(i--)delete r[t[i]];if(n?!I(r):!x.isEmptyObject(r))return}(n||(delete a[s].data,I(a[s])))&&(o?x.cleanData([e],!0):x.support.deleteExpando||a!=a.window?delete a[s]:a[s]=null)}}}x.extend({cache:{},noData:{applet:!0,embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(e){return e=e.nodeType?x.cache[e[x.expando]]:e[x.expando],!!e&&!I(e)},data:function(e,t,n){return R(e,t,n)},removeData:function(e,t){return W(e,t)},_data:function(e,t,n){return R(e,t,n,!0)},_removeData:function(e,t){return W(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&x.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),x.fn.extend({data:function(e,n){var r,i,o=null,a=0,s=this[0];if(e===t){if(this.length&&(o=x.data(s),1===s.nodeType&&!x._data(s,"parsedAttrs"))){for(r=s.attributes;r.length>a;a++)i=r[a].name,0===i.indexOf("data-")&&(i=x.camelCase(i.slice(5)),$(s,i,o[i]));x._data(s,"parsedAttrs",!0)}return o}return"object"==typeof e?this.each(function(){x.data(this,e)}):arguments.length>1?this.each(function(){x.data(this,e,n)}):s?$(s,e,x.data(s,e)):null},removeData:function(e){return this.each(function(){x.removeData(this,e)})}});function $(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(P,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:B.test(r)?x.parseJSON(r):r}catch(o){}x.data(e,n,r)}else r=t}return r}function I(e){var t;for(t in e)if(("data"!==t||!x.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}x.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=x._data(e,n),r&&(!i||x.isArray(r)?i=x._data(e,n,x.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=x.queue(e,t),r=n.length,i=n.shift(),o=x._queueHooks(e,t),a=function(){x.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return x._data(e,n)||x._data(e,n,{empty:x.Callbacks("once memory").add(function(){x._removeData(e,t+"queue"),x._removeData(e,n)})})}}),x.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?x.queue(this[0],e):n===t?this:this.each(function(){var t=x.queue(this,e,n);x._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&x.dequeue(this,e)})},dequeue:function(e){return this.each(function(){x.dequeue(this,e)})},delay:function(e,t){return e=x.fx?x.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=x.Deferred(),a=this,s=this.length,l=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=x._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(l));return l(),o.promise(n)}});var z,X,U=/[\t\r\n\f]/g,V=/\r/g,Y=/^(?:input|select|textarea|button|object)$/i,J=/^(?:a|area)$/i,G=/^(?:checked|selected)$/i,Q=x.support.getSetAttribute,K=x.support.input;x.fn.extend({attr:function(e,t){return x.access(this,x.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){x.removeAttr(this,e)})},prop:function(e,t){return x.access(this,x.prop,e,t,arguments.length>1)},removeProp:function(e){return e=x.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,l="string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).addClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=x.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,l=0===arguments.length||"string"==typeof e&&e;if(x.isFunction(e))return this.each(function(t){x(this).removeClass(e.call(this,t,this.className))});if(l)for(t=(e||"").match(T)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(U," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?x.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):x.isFunction(e)?this.each(function(n){x(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var t,r=0,o=x(this),a=e.match(T)||[];while(t=a[r++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else(n===i||"boolean"===n)&&(this.className&&x._data(this,"__className__",this.className),this.className=this.className||e===!1?"":x._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(U," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=x.isFunction(e),this.each(function(n){var o;1===this.nodeType&&(o=i?e.call(this,n,x(this).val()):e,null==o?o="":"number"==typeof o?o+="":x.isArray(o)&&(o=x.map(o,function(e){return null==e?"":e+""})),r=x.valHooks[this.type]||x.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=x.valHooks[o.type]||x.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(V,""):null==n?"":n)}}}),x.extend({valHooks:{option:{get:function(e){var t=x.find.attr(e,"value");return null!=t?t:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,l=0>i?s:o?i:0;for(;s>l;l++)if(n=r[l],!(!n.selected&&l!==i||(x.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&x.nodeName(n.parentNode,"optgroup"))){if(t=x(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n,r,i=e.options,o=x.makeArray(t),a=i.length;while(a--)r=i[a],(r.selected=x.inArray(x(r).val(),o)>=0)&&(n=!0);return n||(e.selectedIndex=-1),o}}},attr:function(e,n,r){var o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return typeof e.getAttribute===i?x.prop(e,n,r):(1===s&&x.isXMLDoc(e)||(n=n.toLowerCase(),o=x.attrHooks[n]||(x.expr.match.bool.test(n)?X:z)),r===t?o&&"get"in o&&null!==(a=o.get(e,n))?a:(a=x.find.attr(e,n),null==a?t:a):null!==r?o&&"set"in o&&(a=o.set(e,r,n))!==t?a:(e.setAttribute(n,r+""),r):(x.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(T);if(o&&1===e.nodeType)while(n=o[i++])r=x.propFix[n]||n,x.expr.match.bool.test(n)?K&&Q||!G.test(n)?e[r]=!1:e[x.camelCase("default-"+n)]=e[r]=!1:x.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!x.support.radioValue&&"radio"===t&&x.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{"for":"htmlFor","class":"className"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!x.isXMLDoc(e),a&&(n=x.propFix[n]||n,o=x.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var t=x.find.attr(e,"tabindex");return t?parseInt(t,10):Y.test(e.nodeName)||J.test(e.nodeName)&&e.href?0:-1}}}}),X={set:function(e,t,n){return t===!1?x.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&x.propFix[n]||n,n):e[x.camelCase("default-"+n)]=e[n]=!0,n}},x.each(x.expr.match.bool.source.match(/\w+/g),function(e,n){var r=x.expr.attrHandle[n]||x.find.attr;x.expr.attrHandle[n]=K&&Q||!G.test(n)?function(e,n,i){var o=x.expr.attrHandle[n],a=i?t:(x.expr.attrHandle[n]=t)!=r(e,n,i)?n.toLowerCase():null;return x.expr.attrHandle[n]=o,a}:function(e,n,r){return r?t:e[x.camelCase("default-"+n)]?n.toLowerCase():null}}),K&&Q||(x.attrHooks.value={set:function(e,n,r){return x.nodeName(e,"input")?(e.defaultValue=n,t):z&&z.set(e,n,r)}}),Q||(z={set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},x.expr.attrHandle.id=x.expr.attrHandle.name=x.expr.attrHandle.coords=function(e,n,r){var i;return r?t:(i=e.getAttributeNode(n))&&""!==i.value?i.value:null},x.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&r.specified?r.value:t},set:z.set},x.attrHooks.contenteditable={set:function(e,t,n){z.set(e,""===t?!1:t,n)}},x.each(["width","height"],function(e,n){x.attrHooks[n]={set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}}})),x.support.hrefNormalized||x.each(["href","src"],function(e,t){x.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),x.support.style||(x.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),x.support.optSelected||(x.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}}),x.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){x.propFix[this.toLowerCase()]=this}),x.support.enctype||(x.propFix.enctype="encoding"),x.each(["radio","checkbox"],function(){x.valHooks[this]={set:function(e,n){return x.isArray(n)?e.checked=x.inArray(x(e).val(),n)>=0:t}},x.support.checkOn||(x.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}function at(){try{return a.activeElement}catch(e){}}x.event={global:{},add:function(e,n,r,o,a){var s,l,u,c,p,f,d,h,g,m,y,v=x._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=x.guid++),(l=v.events)||(l=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof x===i||e&&x.event.triggered===e.type?t:x.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(T)||[""],u=n.length;while(u--)s=rt.exec(n[u])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),g&&(p=x.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=x.event.special[g]||{},d=x.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&x.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=l[g])||(h=l[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),x.event.global[g]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,l,u,c,p,f,d,h,g,m=x.hasData(e)&&x._data(e);if(m&&(c=m.events)){t=(t||"").match(T)||[""],u=t.length;while(u--)if(s=rt.exec(t[u])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=x.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),l=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));l&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||x.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)x.event.remove(e,d+t[u],n,r,!0);x.isEmptyObject(c)&&(delete m.handle,x._removeData(e,"events"))}},trigger:function(n,r,i,o){var s,l,u,c,p,f,d,h=[i||a],g=v.call(n,"type")?n.type:n,m=v.call(n,"namespace")?n.namespace.split("."):[];if(u=f=i=i||a,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+x.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),l=0>g.indexOf(":")&&"on"+g,n=n[x.expando]?n:new x.Event(g,"object"==typeof n&&n),n.isTrigger=o?2:3,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:x.makeArray(r,[n]),p=x.event.special[g]||{},o||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!o&&!p.noBubble&&!x.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(u=u.parentNode);u;u=u.parentNode)h.push(u),f=u;f===(i.ownerDocument||a)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((u=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(x._data(u,"events")||{})[n.type]&&x._data(u,"handle"),s&&s.apply(u,r),s=l&&u[l],s&&x.acceptData(u)&&s.apply&&s.apply(u,r)===!1&&n.preventDefault();if(n.type=g,!o&&!n.isDefaultPrevented()&&(!p._default||p._default.apply(h.pop(),r)===!1)&&x.acceptData(i)&&l&&i[g]&&!x.isWindow(i)){f=i[l],f&&(i[l]=null),x.event.triggered=g;try{i[g]()}catch(y){}x.event.triggered=t,f&&(i[l]=f)}return n.result}},dispatch:function(e){e=x.event.fix(e);var n,r,i,o,a,s=[],l=g.call(arguments),u=(x._data(this,"events")||{})[e.type]||[],c=x.event.special[e.type]||{};if(l[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=x.event.handlers.call(this,e,u),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((x.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,l),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],l=n.delegateCount,u=e.target;if(l&&u.nodeType&&(!e.button||"click"!==e.type))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||"click"!==e.type)){for(o=[],a=0;l>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?x(r,this).index(u)>=0:x.find(r,this,null,[u]).length),o[r]&&o.push(i);o.length&&s.push({elem:u,handlers:o})}return n.length>l&&s.push({elem:this,handlers:n.slice(l)}),s},fix:function(e){if(e[x.expando])return e;var t,n,r,i=e.type,o=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new x.Event(o),t=r.length;while(t--)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||a),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,o):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,o,s=n.button,l=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||a,o=i.documentElement,r=i.body,e.pageX=n.clientX+(o&&o.scrollLeft||r&&r.scrollLeft||0)-(o&&o.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(o&&o.scrollTop||r&&r.scrollTop||0)-(o&&o.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&l&&(e.relatedTarget=l===e.target?n.toElement:l),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==at()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===at()&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},click:{trigger:function(){return x.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t},_default:function(e){return x.nodeName(e.target,"a")}},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=x.extend(new x.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?x.event.trigger(i,null,t):x.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},x.removeEvent=a.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},x.Event=function(e,n){return this instanceof x.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&x.extend(this,n),this.timeStamp=e&&e.timeStamp||x.now(),this[x.expando]=!0,t):new x.Event(e,n)},x.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},x.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){x.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return(!i||i!==r&&!x.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),x.support.submitBubbles||(x.event.special.submit={setup:function(){return x.nodeName(this,"form")?!1:(x.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=x.nodeName(n,"input")||x.nodeName(n,"button")?n.form:t;r&&!x._data(r,"submitBubbles")&&(x.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),x._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&x.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return x.nodeName(this,"form")?!1:(x.event.remove(this,"._submit"),t)}}),x.support.changeBubbles||(x.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(x.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),x.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),x.event.simulate("change",this,e,!0)})),!1):(x.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!x._data(t,"changeBubbles")&&(x.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||x.event.simulate("change",this.parentNode,e,!0)}),x._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return x.event.remove(this,"._change"),!Z.test(this.nodeName)}}),x.support.focusinBubbles||x.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){x.event.simulate(t,e.target,x.event.fix(e),!0)};x.event.special[t]={setup:function(){0===n++&&a.addEventListener(e,r,!0)},teardown:function(){0===--n&&a.removeEventListener(e,r,!0)}}}),x.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return x().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=x.guid++)),this.each(function(){x.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,x(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){x.event.remove(this,e,r,n)})},trigger:function(e,t){return this.each(function(){x.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?x.event.trigger(e,n,r,!0):t}});var st=/^.[^:#\[\.,]*$/,lt=/^(?:parents|prev(?:Until|All))/,ut=x.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};x.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if("string"!=typeof e)return this.pushStack(x(e).filter(function(){for(t=0;i>t;t++)if(x.contains(r[t],this))return!0}));for(t=0;i>t;t++)x.find(e,r[t],n);return n=this.pushStack(i>1?x.unique(n):n),n.selector=this.selector?this.selector+" "+e:e,n},has:function(e){var t,n=x(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(x.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e||[],!0))},filter:function(e){return this.pushStack(ft(this,e||[],!1))},is:function(e){return!!ft(this,"string"==typeof e&&ut.test(e)?x(e):e||[],!1).length},closest:function(e,t){var n,r=0,i=this.length,o=[],a=ut.test(e)||"string"!=typeof e?x(e,t||this.context):0;for(;i>r;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(11>n.nodeType&&(a?a.index(n)>-1:1===n.nodeType&&x.find.matchesSelector(n,e))){n=o.push(n);break}return this.pushStack(o.length>1?x.unique(o):o)},index:function(e){return e?"string"==typeof e?x.inArray(this[0],x(e)):x.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?x(e,t):x.makeArray(e&&e.nodeType?[e]:e),r=x.merge(this.get(),n);return this.pushStack(x.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}x.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return x.dir(e,"parentNode")},parentsUntil:function(e,t,n){return x.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return x.dir(e,"nextSibling")},prevAll:function(e){return x.dir(e,"previousSibling")},nextUntil:function(e,t,n){return x.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return x.dir(e,"previousSibling",n)},siblings:function(e){return x.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return x.sibling(e.firstChild)},contents:function(e){return x.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:x.merge([],e.childNodes)}},function(e,t){x.fn[e]=function(n,r){var i=x.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=x.filter(r,i)),this.length>1&&(ct[e]||(i=x.unique(i)),lt.test(e)&&(i=i.reverse())),this.pushStack(i)}}),x.extend({filter:function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?x.find.matchesSelector(r,e)?[r]:[]:x.find.matches(e,x.grep(t,function(e){return 1===e.nodeType}))},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!x(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(x.isFunction(t))return x.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return x.grep(e,function(e){return e===t!==n});if("string"==typeof t){if(st.test(t))return x.filter(t,e,n);t=x.filter(t,e)}return x.grep(e,function(e){return x.inArray(e,t)>=0!==n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Ct=/^(?:checkbox|radio)$/i,Nt=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:x.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(a),Dt=jt.appendChild(a.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,x.fn.extend({text:function(e){return x.access(this,function(e){return e===t?x.text(this):this.empty().append((this[0]&&this[0].ownerDocument||a).createTextNode(e))},null,e,arguments.length)},append:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.appendChild(e)}})},prepend:function(){return this.domManip(arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Lt(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=e?x.filter(e,this):this,i=0;for(;null!=(n=r[i]);i++)t||1!==n.nodeType||x.cleanData(Ft(n)),n.parentNode&&(t&&x.contains(n.ownerDocument,n)&&_t(Ft(n,"script")),n.parentNode.removeChild(n));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&x.cleanData(Ft(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&x.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return x.clone(this,e,t)})},html:function(e){return x.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!x.support.htmlSerialize&&mt.test(e)||!x.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(x.cleanData(Ft(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=x.map(this,function(e){return[e.nextSibling,e.parentNode]}),t=0;return this.domManip(arguments,function(n){var r=e[t++],i=e[t++];i&&(r&&r.parentNode!==i&&(r=this.nextSibling),x(this).remove(),i.insertBefore(n,r))},!0),t?this:this.remove()},detach:function(e){return this.remove(e,!0)},domManip:function(e,t,n){e=d.apply([],e);var r,i,o,a,s,l,u=0,c=this.length,p=this,f=c-1,h=e[0],g=x.isFunction(h);if(g||!(1>=c||"string"!=typeof h||x.support.checkClone)&&Nt.test(h))return this.each(function(r){var i=p.eq(r);g&&(e[0]=h.call(this,r,i.html())),i.domManip(e,t,n)});if(c&&(l=x.buildFragment(e,this[0].ownerDocument,!1,!n&&this),r=l.firstChild,1===l.childNodes.length&&(l=r),r)){for(a=x.map(Ft(l,"script"),Ht),o=a.length;c>u;u++)i=l,u!==f&&(i=x.clone(i,!0,!0),o&&x.merge(a,Ft(i,"script"))),t.call(this[u],i,u);if(o)for(s=a[a.length-1].ownerDocument,x.map(a,qt),u=0;o>u;u++)i=a[u],kt.test(i.type||"")&&!x._data(i,"globalEval")&&x.contains(s,i)&&(i.src?x._evalUrl(i.src):x.globalEval((i.text||i.textContent||i.innerHTML||"").replace(St,"")));l=r=null}return this}});function Lt(e,t){return x.nodeName(e,"table")&&x.nodeName(1===t.nodeType?t:t.firstChild,"tr")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function Ht(e){return e.type=(null!==x.find.attr(e,"type"))+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function _t(e,t){var n,r=0;for(;null!=(n=e[r]);r++)x._data(n,"globalEval",!t||x._data(t[r],"globalEval"))}function Mt(e,t){if(1===t.nodeType&&x.hasData(e)){var n,r,i,o=x._data(e),a=x._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)x.event.add(t,n,s[n][r])}a.data&&(a.data=x.extend({},a.data))}}function Ot(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!x.support.noCloneEvent&&t[x.expando]){i=x._data(t);for(r in i.events)x.removeEvent(t,r,i.handle);t.removeAttribute(x.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),x.support.html5Clone&&e.innerHTML&&!x.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Ct.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}x.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){x.fn[e]=function(e){var n,r=0,i=[],o=x(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),x(o[r])[t](n),h.apply(i,n.get());return this.pushStack(i)}});function Ft(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||x.nodeName(o,n)?s.push(o):x.merge(s,Ft(o,n));return n===t||n&&x.nodeName(e,n)?x.merge([e],s):s}function Bt(e){Ct.test(e.type)&&(e.defaultChecked=e.checked)}x.extend({clone:function(e,t,n){var r,i,o,a,s,l=x.contains(e.ownerDocument,e);if(x.support.html5Clone||x.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(x.support.noCloneEvent&&x.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||x.isXMLDoc(e)))for(r=Ft(o),s=Ft(e),a=0;null!=(i=s[a]);++a)r[a]&&Ot(i,r[a]);if(t)if(n)for(s=s||Ft(e),r=r||Ft(o),a=0;null!=(i=s[a]);a++)Mt(i,r[a]);else Mt(e,o);return r=Ft(o,"script"),r.length>0&&_t(r,!l&&Ft(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,l,u,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===x.type(o))x.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),l=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[l]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!x.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!x.support.tbody){o="table"!==l||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)x.nodeName(u=o.childNodes[i],"tbody")&&!u.childNodes.length&&o.removeChild(u)}x.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),x.support.appendChecked||x.grep(Ft(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===x.inArray(o,r))&&(a=x.contains(o.ownerDocument,o),s=Ft(f.appendChild(o),"script"),a&&_t(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,l=x.expando,u=x.cache,c=x.support.deleteExpando,f=x.event.special;for(;null!=(n=e[s]);s++)if((t||x.acceptData(n))&&(o=n[l],a=o&&u[o])){if(a.events)for(r in a.events)f[r]?x.event.remove(n,r):x.removeEvent(n,r,a.handle); -u[o]&&(delete u[o],c?delete n[l]:typeof n.removeAttribute!==i?n.removeAttribute(l):n[l]=null,p.push(o))}},_evalUrl:function(e){return x.ajax({url:e,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})}}),x.fn.extend({wrapAll:function(e){if(x.isFunction(e))return this.each(function(t){x(this).wrapAll(e.call(this,t))});if(this[0]){var t=x(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return x.isFunction(e)?this.each(function(t){x(this).wrapInner(e.call(this,t))}):this.each(function(){var t=x(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=x.isFunction(e);return this.each(function(n){x(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){x.nodeName(this,"body")||x(this).replaceWith(this.childNodes)}).end()}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+w+")(.*)$","i"),Yt=RegExp("^("+w+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+w+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===x.css(e,"display")||!x.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=x._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=x._data(r,"olddisplay",ln(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&x._data(r,"olddisplay",i?n:x.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}x.fn.extend({css:function(e,n){return x.access(this,function(e,n,r){var i,o,a={},s=0;if(x.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=x.css(e,n[s],!1,o);return a}return r!==t?x.style(e,n,r):x.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){nn(this)?x(this).show():x(this).hide()})}}),x.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":x.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,l=x.camelCase(n),u=e.style;if(n=x.cssProps[l]||(x.cssProps[l]=tn(u,l)),s=x.cssHooks[n]||x.cssHooks[l],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:u[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(x.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||x.cssNumber[l]||(r+="px"),x.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(u[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{u[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,l=x.camelCase(n);return n=x.cssProps[l]||(x.cssProps[l]=tn(e.style,l)),s=x.cssHooks[n]||x.cssHooks[l],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||x.isNumeric(o)?o||0:a):a}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s.getPropertyValue(n)||s[n]:t,u=e.style;return s&&(""!==l||x.contains(e.ownerDocument,e)||(l=x.style(e,n)),Yt.test(l)&&Ut.test(n)&&(i=u.width,o=u.minWidth,a=u.maxWidth,u.minWidth=u.maxWidth=u.width=l,l=s.width,u.width=i,u.minWidth=o,u.maxWidth=a)),l}):a.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),l=s?s[n]:t,u=e.style;return null==l&&u&&u[n]&&(l=u[n]),Yt.test(l)&&!zt.test(n)&&(i=u.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),u.left="fontSize"===n?"1em":l,l=u.pixelLeft+"px",u.left=i,a&&(o.left=a)),""===l?"auto":l});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=x.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=x.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=x.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=x.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=x.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(x.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function ln(e){var t=a,n=Gt[e];return n||(n=un(e,t),"none"!==n&&n||(Pt=(Pt||x("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=un(e,t),Pt.detach()),Gt[e]=n),n}function un(e,t){var n=x(t.createElement(e)).appendTo(t.body),r=x.css(n[0],"display");return n.remove(),r}x.each(["height","width"],function(e,n){x.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(x.css(e,"display"))?x.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,x.support.boxSizing&&"border-box"===x.css(e,"boxSizing",!1,i),i):0)}}}),x.support.opacity||(x.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=x.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===x.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),x(function(){x.support.reliableMarginRight||(x.cssHooks.marginRight={get:function(e,n){return n?x.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!x.support.pixelPosition&&x.fn.position&&x.each(["top","left"],function(e,n){x.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?x(e).position()[n]+"px":r):t}}})}),x.expr&&x.expr.filters&&(x.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!x.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||x.css(e,"display"))},x.expr.filters.visible=function(e){return!x.expr.filters.hidden(e)}),x.each({margin:"",padding:"",border:"Width"},function(e,t){x.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(x.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;x.fn.extend({serialize:function(){return x.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=x.prop(this,"elements");return e?x.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!x(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Ct.test(e))}).map(function(e,t){var n=x(this).val();return null==n?null:x.isArray(n)?x.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),x.param=function(e,n){var r,i=[],o=function(e,t){t=x.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=x.ajaxSettings&&x.ajaxSettings.traditional),x.isArray(e)||e.jquery&&!x.isPlainObject(e))x.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(x.isArray(t))x.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==x.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}x.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 contextmenu".split(" "),function(e,t){x.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),x.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}});var mn,yn,vn=x.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Cn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Nn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=x.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=o.href}catch(Ln){yn=a.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(T)||[];if(x.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(l){var u;return o[l]=!0,x.each(e[l]||[],function(e,l){var c=l(n,r,i);return"string"!=typeof c||a||o[c]?a?!(u=c):t:(n.dataTypes.unshift(c),s(c),!1)}),u}return s(n.dataTypes[0])||!o["*"]&&s("*")}function _n(e,n){var r,i,o=x.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&x.extend(!0,e,r),e}x.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,l=e.indexOf(" ");return l>=0&&(i=e.slice(l,e.length),e=e.slice(0,l)),x.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&x.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?x("<div>").append(x.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},x.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){x.fn[t]=function(e){return this.on(t,e)}}),x.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Cn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":x.parseJSON,"text xml":x.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?_n(_n(e,x.ajaxSettings),t):_n(x.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,l,u,c,p=x.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?x(f):x.event,h=x.Deferred(),g=x.Callbacks("once memory"),m=p.statusCode||{},y={},v={},b=0,w="canceled",C={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return b||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>b)for(t in e)m[t]=[m[t],e[t]];else C.always(e[C.status]);return this},abort:function(e){var t=e||w;return u&&u.abort(t),k(0,t),this}};if(h.promise(C).complete=g.add,C.success=C.done,C.error=C.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=x.trim(p.dataType||"*").toLowerCase().match(T)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?"80":"443"))===(mn[3]||("http:"===mn[1]?"80":"443")))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=x.param(p.data,p.traditional)),qn(An,p,n,C),2===b)return C;l=p.global,l&&0===x.active++&&x.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Nn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(x.lastModified[o]&&C.setRequestHeader("If-Modified-Since",x.lastModified[o]),x.etag[o]&&C.setRequestHeader("If-None-Match",x.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&C.setRequestHeader("Content-Type",p.contentType),C.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)C.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,C,p)===!1||2===b))return C.abort();w="abort";for(i in{success:1,error:1,complete:1})C[i](p[i]);if(u=qn(jn,p,n,C)){C.readyState=1,l&&d.trigger("ajaxSend",[C,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){C.abort("timeout")},p.timeout));try{b=1,u.send(y,k)}catch(N){if(!(2>b))throw N;k(-1,N)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,N=n;2!==b&&(b=2,s&&clearTimeout(s),u=t,a=i||"",C.readyState=e>0?4:0,c=e>=200&&300>e||304===e,r&&(w=Mn(p,C,r)),w=On(p,w,C,c),c?(p.ifModified&&(T=C.getResponseHeader("Last-Modified"),T&&(x.lastModified[o]=T),T=C.getResponseHeader("etag"),T&&(x.etag[o]=T)),204===e||"HEAD"===p.type?N="nocontent":304===e?N="notmodified":(N=w.state,y=w.data,v=w.error,c=!v)):(v=N,(e||!N)&&(N="error",0>e&&(e=0))),C.status=e,C.statusText=(n||N)+"",c?h.resolveWith(f,[y,N,C]):h.rejectWith(f,[C,N,v]),C.statusCode(m),m=t,l&&d.trigger(c?"ajaxSuccess":"ajaxError",[C,p,c?y:v]),g.fireWith(f,[C,N]),l&&(d.trigger("ajaxComplete",[C,p]),--x.active||x.event.trigger("ajaxStop")))}return C},getJSON:function(e,t,n){return x.get(e,t,n,"json")},getScript:function(e,n){return x.get(e,t,n,"script")}}),x.each(["get","post"],function(e,n){x[n]=function(e,r,i,o){return x.isFunction(r)&&(o=o||i,i=r,r=t),x.ajax({url:e,type:n,dataType:o,data:r,success:i})}});function Mn(e,n,r){var i,o,a,s,l=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in l)if(l[s]&&l[s].test(o)){u.unshift(s);break}if(u[0]in r)a=u[0];else{for(s in r){if(!u[0]||e.converters[s+" "+u[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==u[0]&&u.unshift(a),r[a]):t}function On(e,t,n,r){var i,o,a,s,l,u={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)u[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(a=u[l+" "+o]||u["* "+o],!a)for(i in u)if(s=i.split(" "),s[1]===o&&(a=u[l+" "+s[0]]||u["* "+s[0]])){a===!0?a=u[i]:u[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(p){return{state:"parsererror",error:a?p:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}x.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return x.globalEval(e),e}}}),x.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),x.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=a.head||x("head")[0]||a.documentElement;return{send:function(t,i){n=a.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var Fn=[],Bn=/(=)\?(?=&|$)|\?\?/;x.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Fn.pop()||x.expando+"_"+vn++;return this[e]=!0,e}}),x.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,l=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return l||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=x.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,l?n[l]=n[l].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||x.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,Fn.push(o)),s&&x.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}x.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=x.ajaxSettings.xhr(),x.support.cors=!!Rn&&"withCredentials"in Rn,Rn=x.support.ajax=!!Rn,Rn&&x.ajaxTransport(function(n){if(!n.crossDomain||x.support.cors){var r;return{send:function(i,o){var a,s,l=n.xhr();if(n.username?l.open(n.type,n.url,n.async,n.username,n.password):l.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)l[s]=n.xhrFields[s];n.mimeType&&l.overrideMimeType&&l.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)l.setRequestHeader(s,i[s])}catch(u){}l.send(n.hasContent&&n.data||null),r=function(e,i){var s,u,c,p;try{if(r&&(i||4===l.readyState))if(r=t,a&&(l.onreadystatechange=x.noop,$n&&delete Pn[a]),i)4!==l.readyState&&l.abort();else{p={},s=l.status,u=l.getAllResponseHeaders(),"string"==typeof l.responseText&&(p.text=l.responseText);try{c=l.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,u)},n.async?4===l.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},x(e).unload($n)),Pn[a]=r),l.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+w+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n=this.createTween(e,t),r=n.cur(),i=Yn.exec(t),o=i&&i[3]||(x.cssNumber[e]?"":"px"),a=(x.cssNumber[e]||"px"!==o&&+r)&&Yn.exec(x.css(n.elem,e)),s=1,l=20;if(a&&a[3]!==o){o=o||a[3],i=i||[],a=+r||1;do s=s||".5",a/=s,x.style(n.elem,e,a+o);while(s!==(s=n.cur()/r)&&1!==s&&--l)}return i&&(a=n.start=+a||+r||0,n.unit=o,n.end=i[1]?a+(i[1]+1)*i[2]:+i[2]),n}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=x.now()}function Zn(e,t,n){var r,i=(Qn[t]||[]).concat(Qn["*"]),o=0,a=i.length;for(;a>o;o++)if(r=i[o].call(n,t,e))return r}function er(e,t,n){var r,i,o=0,a=Gn.length,s=x.Deferred().always(function(){delete l.elem}),l=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,u.startTime+u.duration-t),r=n/u.duration||0,o=1-r,a=0,l=u.tweens.length;for(;l>a;a++)u.tweens[a].run(o);return s.notifyWith(e,[u,o,n]),1>o&&l?n:(s.resolveWith(e,[u]),!1)},u=s.promise({elem:e,props:x.extend({},t),opts:x.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=x.Tween(e,u.opts,t,n,u.opts.specialEasing[t]||u.opts.easing);return u.tweens.push(r),r},stop:function(t){var n=0,r=t?u.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)u.tweens[n].run(1);return t?s.resolveWith(e,[u,t]):s.rejectWith(e,[u,t]),this}}),c=u.props;for(tr(c,u.opts.specialEasing);a>o;o++)if(r=Gn[o].call(u,e,c,u.opts))return r;return x.map(c,Zn,u),x.isFunction(u.opts.start)&&u.opts.start.call(e,u),x.fx.timer(x.extend(l,{elem:e,anim:u,queue:u.opts.queue})),u.progress(u.opts.progress).done(u.opts.done,u.opts.complete).fail(u.opts.fail).always(u.opts.always)}function tr(e,t){var n,r,i,o,a;for(n in e)if(r=x.camelCase(n),i=t[r],o=e[n],x.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=x.cssHooks[r],a&&"expand"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}x.Animation=x.extend(er,{tweener:function(e,t){x.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,l,u=this,c={},p=e.style,f=e.nodeType&&nn(e),d=x._data(e,"fxshow");n.queue||(s=x._queueHooks(e,"fx"),null==s.unqueued&&(s.unqueued=0,l=s.empty.fire,s.empty.fire=function(){s.unqueued||l()}),s.unqueued++,u.always(function(){u.always(function(){s.unqueued--,x.queue(e,"fx").length||s.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],"inline"===x.css(e,"display")&&"none"===x.css(e,"float")&&(x.support.inlineBlockNeedsLayout&&"inline"!==ln(e.nodeName)?p.zoom=1:p.display="inline-block")),n.overflow&&(p.overflow="hidden",x.support.shrinkWrapBlocks||u.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],Vn.exec(i)){if(delete t[r],o=o||"toggle"===i,i===(f?"hide":"show"))continue;c[r]=d&&d[r]||x.style(e,r)}if(!x.isEmptyObject(c)){d?"hidden"in d&&(f=d.hidden):d=x._data(e,"fxshow",{}),o&&(d.hidden=!f),f?x(e).show():u.done(function(){x(e).hide()}),u.done(function(){var t;x._removeData(e,"fxshow");for(t in c)x.style(e,t,c[t])});for(r in c)a=Zn(f?d[r]:0,r,u),r in d||(d[r]=a.start,f&&(a.end=a.start,a.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}x.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(x.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?x.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=x.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){x.fx.step[e.prop]?x.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[x.cssProps[e.prop]]||x.cssHooks[e.prop])?x.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},x.each(["toggle","show","hide"],function(e,t){var n=x.fn[t];x.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),x.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=x.isEmptyObject(e),o=x.speed(t,n,r),a=function(){var t=er(this,x.extend({},e),o);(i||x._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=x.timers,a=x._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&x.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=x._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=x.timers,a=r?r.length:0;for(n.finish=!0,x.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}x.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){x.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),x.speed=function(e,t,n){var r=e&&"object"==typeof e?x.extend({},e):{complete:n||!n&&t||x.isFunction(e)&&e,duration:e,easing:n&&t||t&&!x.isFunction(t)&&t};return r.duration=x.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in x.fx.speeds?x.fx.speeds[r.duration]:x.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){x.isFunction(r.old)&&r.old.call(this),r.queue&&x.dequeue(this,r.queue)},r},x.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},x.timers=[],x.fx=rr.prototype.init,x.fx.tick=function(){var e,n=x.timers,r=0;for(Xn=x.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||x.fx.stop(),Xn=t},x.fx.timer=function(e){e()&&x.timers.push(e)&&x.fx.start()},x.fx.interval=13,x.fx.start=function(){Un||(Un=setInterval(x.fx.tick,x.fx.interval))},x.fx.stop=function(){clearInterval(Un),Un=null},x.fx.speeds={slow:600,fast:200,_default:400},x.fx.step={},x.expr&&x.expr.filters&&(x.expr.filters.animated=function(e){return x.grep(x.timers,function(t){return e===t.elem}).length}),x.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){x.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,x.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},x.offset={setOffset:function(e,t,n){var r=x.css(e,"position");"static"===r&&(e.style.position="relative");var i=x(e),o=i.offset(),a=x.css(e,"top"),s=x.css(e,"left"),l=("absolute"===r||"fixed"===r)&&x.inArray("auto",[a,s])>-1,u={},c={},p,f;l?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),x.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(u.top=t.top-o.top+p),null!=t.left&&(u.left=t.left-o.left+f),"using"in t?t.using.call(e,u):i.css(u)}},x.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===x.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),x.nodeName(e[0],"html")||(n=e.offset()),n.top+=x.css(e[0],"borderTopWidth",!0),n.left+=x.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-x.css(r,"marginTop",!0),left:t.left-n.left-x.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||s;while(e&&!x.nodeName(e,"html")&&"static"===x.css(e,"position"))e=e.offsetParent;return e||s})}}),x.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);x.fn[e]=function(i){return x.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?x(a).scrollLeft():o,r?o:x(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return x.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}x.each({Height:"height",Width:"width"},function(e,n){x.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){x.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return x.access(this,function(n,r,i){var o;return x.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?x.css(n,r,s):x.style(n,r,i,s)},n,a?i:t,a,null)}})}),x.fn.size=function(){return this.length},x.fn.andSelf=x.fn.addBack,"object"==typeof module&&module&&"object"==typeof module.exports?module.exports=x:(e.jQuery=e.$=x,"function"==typeof define&&define.amd&&define("jquery",[],function(){return x}))})(window); diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.map b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.map deleted file mode 100644 index 4dc4920bb828e8bfb5f7efc8f4c074af9e2784ab..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery-1.10.2.min.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"jquery-1.10.2.min.js","sources":["jquery-1.10.2.js"],"names":["window","undefined","readyList","rootjQuery","core_strundefined","location","document","docElem","documentElement","_jQuery","jQuery","_$","$","class2type","core_deletedIds","core_version","core_concat","concat","core_push","push","core_slice","slice","core_indexOf","indexOf","core_toString","toString","core_hasOwn","hasOwnProperty","core_trim","trim","selector","context","fn","init","core_pnum","source","core_rnotwhite","rtrim","rquickExpr","rsingleTag","rvalidchars","rvalidbraces","rvalidescape","rvalidtokens","rmsPrefix","rdashAlpha","fcamelCase","all","letter","toUpperCase","completed","event","addEventListener","type","readyState","detach","ready","removeEventListener","detachEvent","prototype","jquery","constructor","match","elem","this","charAt","length","exec","find","merge","parseHTML","nodeType","ownerDocument","test","isPlainObject","isFunction","attr","getElementById","parentNode","id","makeArray","toArray","call","get","num","pushStack","elems","ret","prevObject","each","callback","args","promise","done","apply","arguments","first","eq","last","i","len","j","map","end","sort","splice","extend","src","copyIsArray","copy","name","options","clone","target","deep","isArray","expando","Math","random","replace","noConflict","isReady","readyWait","holdReady","hold","wait","body","setTimeout","resolveWith","trigger","off","obj","Array","isWindow","isNumeric","isNaN","parseFloat","isFinite","String","key","e","support","ownLast","isEmptyObject","error","msg","Error","data","keepScripts","parsed","scripts","createElement","buildFragment","remove","childNodes","parseJSON","JSON","parse","Function","parseXML","xml","tmp","DOMParser","parseFromString","ActiveXObject","async","loadXML","getElementsByTagName","noop","globalEval","execScript","camelCase","string","nodeName","toLowerCase","value","isArraylike","text","arr","results","Object","inArray","max","second","l","grep","inv","retVal","arg","guid","proxy","access","chainable","emptyGet","raw","bulk","now","Date","getTime","swap","old","style","Deferred","attachEvent","top","frameElement","doScroll","doScrollCheck","split","cachedruns","Expr","getText","isXML","compile","outermostContext","sortInput","setDocument","documentIsHTML","rbuggyQSA","rbuggyMatches","matches","contains","preferredDoc","dirruns","classCache","createCache","tokenCache","compilerCache","hasDuplicate","sortOrder","a","b","strundefined","MAX_NEGATIVE","hasOwn","pop","push_native","booleans","whitespace","characterEncoding","identifier","attributes","pseudos","RegExp","rcomma","rcombinators","rsibling","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rnative","rinputs","rheader","rescape","runescape","funescape","_","escaped","escapedWhitespace","high","fromCharCode","els","Sizzle","seed","m","groups","nid","newContext","newSelector","getElementsByClassName","qsa","tokenize","getAttribute","setAttribute","toSelector","join","querySelectorAll","qsaError","removeAttribute","select","keys","cache","cacheLength","shift","markFunction","assert","div","removeChild","addHandle","attrs","handler","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","node","doc","parent","defaultView","className","appendChild","createComment","innerHTML","firstChild","getById","getElementsByName","filter","attrId","getAttributeNode","tag","input","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","val","specified","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","nodeValue","selectors","createPseudo","relative",">","dir"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","simple","forward","ofType","outerCache","nodeIndex","start","useCache","lastChild","pseudo","setFilters","idx","matched","not","matcher","unmatched","has","innerText","lang","elemLang","hash","root","focus","activeElement","hasFocus","href","tabIndex","enabled","disabled","checked","selected","selectedIndex","empty","header","button","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","filters","parseOnly","tokens","soFar","preFilters","cached","addCombinator","combinator","base","checkNonElements","doneName","dirkey","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","matcherFromGroupMatchers","elementMatchers","setMatchers","matcherCachedRuns","bySet","byElement","superMatcher","expandContext","setMatched","matchedCount","outermost","contextBackup","dirrunsUnique","group","contexts","token","div1","defaultValue","unique","isXMLDoc","optionsCache","createOptions","object","flag","Callbacks","firing","memory","fired","firingLength","firingIndex","firingStart","list","stack","once","fire","stopOnFalse","self","disable","add","index","lock","locked","fireWith","func","tuples","state","always","deferred","fail","then","fns","newDefer","tuple","action","returned","resolve","reject","progress","notify","pipe","stateString","when","subordinate","resolveValues","remaining","updateFunc","values","progressValues","notifyWith","progressContexts","resolveContexts","fragment","opt","eventName","isSupported","cssText","getSetAttribute","leadingWhitespace","tbody","htmlSerialize","hrefNormalized","opacity","cssFloat","checkOn","optSelected","enctype","html5Clone","cloneNode","outerHTML","inlineBlockNeedsLayout","shrinkWrapBlocks","pixelPosition","deleteExpando","noCloneEvent","reliableMarginRight","boxSizingReliable","noCloneChecked","optDisabled","radioValue","createDocumentFragment","appendChecked","checkClone","click","change","focusin","backgroundClip","clearCloneStyle","container","marginDiv","tds","divReset","offsetHeight","display","reliableHiddenOffsets","zoom","boxSizing","offsetWidth","getComputedStyle","width","marginRight","rbrace","rmultiDash","internalData","pvt","acceptData","thisCache","internalKey","isNode","toJSON","internalRemoveData","isEmptyDataObject","cleanData","noData","applet","embed","hasData","removeData","_data","_removeData","dataAttr","queue","dequeue","startLength","hooks","_queueHooks","next","stop","setter","delay","time","fx","speeds","timeout","clearTimeout","clearQueue","count","defer","nodeHook","boolHook","rclass","rreturn","rfocusable","rclickable","ruseDefault","getSetInput","removeAttr","prop","removeProp","propFix","addClass","classes","clazz","proceed","removeClass","toggleClass","stateVal","classNames","hasClass","valHooks","set","option","one","optionSet","nType","attrHooks","propName","attrNames","for","class","notxml","propHooks","tabindex","parseInt","getter","setAttributeNode","createAttribute","coords","contenteditable","rformElems","rkeyEvent","rmouseEvent","rfocusMorph","rtypenamespace","returnTrue","returnFalse","safeActiveElement","err","global","types","events","t","handleObjIn","special","eventHandle","handleObj","handlers","namespaces","origType","elemData","handle","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","onlyHandlers","ontype","bubbleType","eventPath","Event","isTrigger","namespace_re","noBubble","parentWindow","isPropagationStopped","preventDefault","isDefaultPrevented","_default","fix","handlerQueue","delegateTarget","preDispatch","currentTarget","isImmediatePropagationStopped","stopPropagation","postDispatch","sel","originalEvent","fixHook","fixHooks","mouseHooks","keyHooks","props","srcElement","metaKey","original","which","charCode","keyCode","eventDoc","fromElement","pageX","clientX","scrollLeft","clientLeft","pageY","clientY","scrollTop","clientTop","relatedTarget","toElement","load","blur","beforeunload","returnValue","simulate","bubble","isSimulated","defaultPrevented","getPreventDefault","timeStamp","cancelBubble","stopImmediatePropagation","mouseenter","mouseleave","orig","related","submitBubbles","form","_submit_bubble","changeBubbles","propertyName","_just_changed","focusinBubbles","attaches","on","origFn","triggerHandler","isSimple","rparentsprev","rneedsContext","guaranteedUnique","children","contents","prev","targets","winnow","is","closest","pos","prevAll","addBack","sibling","parents","parentsUntil","until","nextAll","nextUntil","prevUntil","siblings","contentDocument","contentWindow","reverse","n","r","qualifier","createSafeFragment","nodeNames","safeFrag","rinlinejQuery","rnoshimcache","rleadingWhitespace","rxhtmlTag","rtagName","rtbody","rhtml","rnoInnerhtml","manipulation_rcheckableType","rchecked","rscriptType","rscriptTypeMasked","rcleanScript","wrapMap","legend","area","param","thead","tr","col","td","safeFragment","fragmentDiv","optgroup","tfoot","colgroup","caption","th","append","createTextNode","domManip","manipulationTarget","prepend","insertBefore","before","after","keepData","getAll","setGlobalEval","dataAndEvents","deepDataAndEvents","html","replaceWith","allowIntersection","hasScripts","iNoClone","disableScript","restoreScript","_evalUrl","content","refElements","cloneCopyEvent","dest","oldData","curData","fixCloneNodeIssues","defaultChecked","defaultSelected","appendTo","prependTo","insertAfter","replaceAll","insert","found","fixDefaultChecked","destElements","srcElements","inPage","selection","wrap","safe","nodes","url","ajax","dataType","throws","wrapAll","wrapInner","unwrap","iframe","getStyles","curCSS","ralpha","ropacity","rposition","rdisplayswap","rmargin","rnumsplit","rnumnonpx","rrelNum","elemdisplay","BODY","cssShow","position","visibility","cssNormalTransform","letterSpacing","fontWeight","cssExpand","cssPrefixes","vendorPropName","capName","origName","isHidden","el","css","showHide","show","hidden","css_defaultDisplay","styles","hide","toggle","cssHooks","computed","cssNumber","columnCount","fillOpacity","lineHeight","order","orphans","widows","zIndex","cssProps","float","extra","_computed","minWidth","maxWidth","getPropertyValue","currentStyle","left","rs","rsLeft","runtimeStyle","pixelLeft","setPositiveNumber","subtract","augmentWidthOrHeight","isBorderBox","getWidthOrHeight","valueIsBorderBox","actualDisplay","write","close","$1","visible","margin","padding","border","prefix","suffix","expand","expanded","parts","r20","rbracket","rCRLF","rsubmitterTypes","rsubmittable","serialize","serializeArray","traditional","s","encodeURIComponent","ajaxSettings","buildParams","v","hover","fnOver","fnOut","bind","unbind","delegate","undelegate","ajaxLocParts","ajaxLocation","ajax_nonce","ajax_rquery","rhash","rts","rheaders","rlocalProtocol","rnoContent","rprotocol","rurl","_load","prefilters","transports","allTypes","addToPrefiltersOrTransports","structure","dataTypeExpression","dataTypes","inspectPrefiltersOrTransports","originalOptions","jqXHR","inspected","seekingTransport","inspect","prefilterOrFactory","dataTypeOrTransport","ajaxExtend","flatOptions","params","response","responseText","complete","status","active","lastModified","etag","isLocal","processData","contentType","accepts","*","json","responseFields","converters","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","cacheURL","responseHeadersString","timeoutTimer","fireGlobals","transport","responseHeaders","callbackContext","globalEventContext","completeDeferred","statusCode","requestHeaders","requestHeadersNames","strAbort","getResponseHeader","getAllResponseHeaders","setRequestHeader","lname","overrideMimeType","mimeType","code","abort","statusText","finalText","success","method","crossDomain","hasContent","ifModified","headers","beforeSend","send","nativeStatusText","responses","isSuccess","modified","ajaxHandleResponses","ajaxConvert","rejectWith","getJSON","getScript","firstDataType","ct","finalDataType","conv2","current","conv","dataFilter","script","text script","head","scriptCharset","charset","onload","onreadystatechange","isAbort","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","xhrCallbacks","xhrSupported","xhrId","xhrOnUnloadAbort","createStandardXHR","XMLHttpRequest","createActiveXHR","xhr","cors","username","open","xhrFields","firefoxAccessException","unload","fxNow","timerId","rfxtypes","rfxnum","rrun","animationPrefilters","defaultPrefilter","tweeners","tween","createTween","unit","scale","maxIterations","createFxNow","animation","collection","Animation","properties","stopped","tick","currentTime","startTime","duration","percent","tweens","run","opts","specialEasing","originalProperties","Tween","easing","gotoEnd","propFilter","timer","anim","tweener","prefilter","oldfire","dataShow","unqueued","overflow","overflowX","overflowY","eased","step","cssFn","speed","animate","genFx","fadeTo","to","optall","doAnimation","finish","stopQueue","timers","includeWidth","height","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","linear","p","swing","cos","PI","interval","setInterval","clearInterval","slow","fast","animated","offset","setOffset","win","box","getBoundingClientRect","getWindow","pageYOffset","pageXOffset","curElem","curOffset","curCSSTop","curCSSLeft","calculatePosition","curPosition","curTop","curLeft","using","offsetParent","parentOffset","scrollTo","Height","Width","defaultExtra","funcName","size","andSelf","module","exports","define","amd"],"mappings":"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"} \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.js deleted file mode 100644 index a92aecf7cc85aa34a96475ec9d6f977a5702d779..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.js +++ /dev/null @@ -1,2928 +0,0 @@ -/* jquery.signalR.core.js */ -/*global window:false */ -/*! - * ASP.NET SignalR JavaScript Library v2.2.0 - * http://signalr.net/ - * - * Copyright (C) Microsoft Corporation. All rights reserved. - * - */ - -/// <reference path="Scripts/jquery-1.6.4.js" /> -/// <reference path="jquery.signalR.version.js" /> -(function ($, window, undefined) { - - var resources = { - nojQuery: "jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file.", - noTransportOnInit: "No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.", - errorOnNegotiate: "Error during negotiation request.", - stoppedWhileLoading: "The connection was stopped during page load.", - stoppedWhileNegotiating: "The connection was stopped during the negotiate request.", - errorParsingNegotiateResponse: "Error parsing negotiate response.", - errorDuringStartRequest: "Error during start request. Stopping the connection.", - stoppedDuringStartRequest: "The connection was stopped during the start request.", - errorParsingStartResponse: "Error parsing start response: '{0}'. Stopping the connection.", - invalidStartResponse: "Invalid start response: '{0}'. Stopping the connection.", - protocolIncompatible: "You are using a version of the client that isn't compatible with the server. Client version {0}, server version {1}.", - sendFailed: "Send failed.", - parseFailed: "Failed at parsing response: {0}", - longPollFailed: "Long polling request failed.", - eventSourceFailedToConnect: "EventSource failed to connect.", - eventSourceError: "Error raised by EventSource", - webSocketClosed: "WebSocket closed.", - pingServerFailedInvalidResponse: "Invalid ping response when pinging server: '{0}'.", - pingServerFailed: "Failed to ping server.", - pingServerFailedStatusCode: "Failed to ping server. Server responded with status code {0}, stopping the connection.", - pingServerFailedParse: "Failed to parse ping server response, stopping the connection.", - noConnectionTransport: "Connection is in an invalid state, there is no transport active.", - webSocketsInvalidState: "The Web Socket transport is in an invalid state, transitioning into reconnecting.", - reconnectTimeout: "Couldn't reconnect within the configured timeout of {0} ms, disconnecting.", - reconnectWindowTimeout: "The client has been inactive since {0} and it has exceeded the inactivity timeout of {1} ms. Stopping the connection." - }; - - if (typeof ($) !== "function") { - // no jQuery! - throw new Error(resources.nojQuery); - } - - var signalR, - _connection, - _pageLoaded = (window.document.readyState === "complete"), - _pageWindow = $(window), - _negotiateAbortText = "__Negotiate Aborted__", - events = { - onStart: "onStart", - onStarting: "onStarting", - onReceived: "onReceived", - onError: "onError", - onConnectionSlow: "onConnectionSlow", - onReconnecting: "onReconnecting", - onReconnect: "onReconnect", - onStateChanged: "onStateChanged", - onDisconnect: "onDisconnect" - }, - ajaxDefaults = { - processData: true, - timeout: null, - async: true, - global: false, - cache: false - }, - log = function (msg, logging) { - if (logging === false) { - return; - } - var m; - if (typeof (window.console) === "undefined") { - return; - } - m = "[" + new Date().toTimeString() + "] SignalR: " + msg; - if (window.console.debug) { - window.console.debug(m); - } else if (window.console.log) { - window.console.log(m); - } - }, - - changeState = function (connection, expectedState, newState) { - if (expectedState === connection.state) { - connection.state = newState; - - $(connection).triggerHandler(events.onStateChanged, [{ oldState: expectedState, newState: newState }]); - return true; - } - - return false; - }, - - isDisconnecting = function (connection) { - return connection.state === signalR.connectionState.disconnected; - }, - - supportsKeepAlive = function (connection) { - return connection._.keepAliveData.activated && - connection.transport.supportsKeepAlive(connection); - }, - - configureStopReconnectingTimeout = function (connection) { - var stopReconnectingTimeout, - onReconnectTimeout; - - // Check if this connection has already been configured to stop reconnecting after a specified timeout. - // Without this check if a connection is stopped then started events will be bound multiple times. - if (!connection._.configuredStopReconnectingTimeout) { - onReconnectTimeout = function (connection) { - var message = signalR._.format(signalR.resources.reconnectTimeout, connection.disconnectTimeout); - connection.log(message); - $(connection).triggerHandler(events.onError, [signalR._.error(message, /* source */ "TimeoutException")]); - connection.stop(/* async */ false, /* notifyServer */ false); - }; - - connection.reconnecting(function () { - var connection = this; - - // Guard against state changing in a previous user defined even handler - if (connection.state === signalR.connectionState.reconnecting) { - stopReconnectingTimeout = window.setTimeout(function () { onReconnectTimeout(connection); }, connection.disconnectTimeout); - } - }); - - connection.stateChanged(function (data) { - if (data.oldState === signalR.connectionState.reconnecting) { - // Clear the pending reconnect timeout check - window.clearTimeout(stopReconnectingTimeout); - } - }); - - connection._.configuredStopReconnectingTimeout = true; - } - }; - - signalR = function (url, qs, logging) { - /// <summary>Creates a new SignalR connection for the given url</summary> - /// <param name="url" type="String">The URL of the long polling endpoint</param> - /// <param name="qs" type="Object"> - /// [Optional] Custom querystring parameters to add to the connection URL. - /// If an object, every non-function member will be added to the querystring. - /// If a string, it's added to the QS as specified. - /// </param> - /// <param name="logging" type="Boolean"> - /// [Optional] A flag indicating whether connection logging is enabled to the browser - /// console/log. Defaults to false. - /// </param> - - return new signalR.fn.init(url, qs, logging); - }; - - signalR._ = { - defaultContentType: "application/x-www-form-urlencoded; charset=UTF-8", - - ieVersion: (function () { - var version, - matches; - - if (window.navigator.appName === 'Microsoft Internet Explorer') { - // Check if the user agent has the pattern "MSIE (one or more numbers).(one or more numbers)"; - matches = /MSIE ([0-9]+\.[0-9]+)/.exec(window.navigator.userAgent); - - if (matches) { - version = window.parseFloat(matches[1]); - } - } - - // undefined value means not IE - return version; - })(), - - error: function (message, source, context) { - var e = new Error(message); - e.source = source; - - if (typeof context !== "undefined") { - e.context = context; - } - - return e; - }, - - transportError: function (message, transport, source, context) { - var e = this.error(message, source, context); - e.transport = transport ? transport.name : undefined; - return e; - }, - - format: function () { - /// <summary>Usage: format("Hi {0}, you are {1}!", "Foo", 100) </summary> - var s = arguments[0]; - for (var i = 0; i < arguments.length - 1; i++) { - s = s.replace("{" + i + "}", arguments[i + 1]); - } - return s; - }, - - firefoxMajorVersion: function (userAgent) { - // Firefox user agents: http://useragentstring.com/pages/Firefox/ - var matches = userAgent.match(/Firefox\/(\d+)/); - if (!matches || !matches.length || matches.length < 2) { - return 0; - } - return parseInt(matches[1], 10 /* radix */); - }, - - configurePingInterval: function (connection) { - var config = connection._.config, - onFail = function (error) { - $(connection).triggerHandler(events.onError, [error]); - }; - - if (config && !connection._.pingIntervalId && config.pingInterval) { - connection._.pingIntervalId = window.setInterval(function () { - signalR.transports._logic.pingServer(connection).fail(onFail); - }, config.pingInterval); - } - } - }; - - signalR.events = events; - - signalR.resources = resources; - - signalR.ajaxDefaults = ajaxDefaults; - - signalR.changeState = changeState; - - signalR.isDisconnecting = isDisconnecting; - - signalR.connectionState = { - connecting: 0, - connected: 1, - reconnecting: 2, - disconnected: 4 - }; - - signalR.hub = { - start: function () { - // This will get replaced with the real hub connection start method when hubs is referenced correctly - throw new Error("SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/js'></script>."); - } - }; - - _pageWindow.load(function () { _pageLoaded = true; }); - - function validateTransport(requestedTransport, connection) { - /// <summary>Validates the requested transport by cross checking it with the pre-defined signalR.transports</summary> - /// <param name="requestedTransport" type="Object">The designated transports that the user has specified.</param> - /// <param name="connection" type="signalR">The connection that will be using the requested transports. Used for logging purposes.</param> - /// <returns type="Object" /> - - if ($.isArray(requestedTransport)) { - // Go through transport array and remove an "invalid" tranports - for (var i = requestedTransport.length - 1; i >= 0; i--) { - var transport = requestedTransport[i]; - if ($.type(transport) !== "string" || !signalR.transports[transport]) { - connection.log("Invalid transport: " + transport + ", removing it from the transports list."); - requestedTransport.splice(i, 1); - } - } - - // Verify we still have transports left, if we dont then we have invalid transports - if (requestedTransport.length === 0) { - connection.log("No transports remain within the specified transport array."); - requestedTransport = null; - } - } else if (!signalR.transports[requestedTransport] && requestedTransport !== "auto") { - connection.log("Invalid transport: " + requestedTransport.toString() + "."); - requestedTransport = null; - } else if (requestedTransport === "auto" && signalR._.ieVersion <= 8) { - // If we're doing an auto transport and we're IE8 then force longPolling, #1764 - return ["longPolling"]; - - } - - return requestedTransport; - } - - function getDefaultPort(protocol) { - if (protocol === "http:") { - return 80; - } else if (protocol === "https:") { - return 443; - } - } - - function addDefaultPort(protocol, url) { - // Remove ports from url. We have to check if there's a / or end of line - // following the port in order to avoid removing ports such as 8080. - if (url.match(/:\d+$/)) { - return url; - } else { - return url + ":" + getDefaultPort(protocol); - } - } - - function ConnectingMessageBuffer(connection, drainCallback) { - var that = this, - buffer = []; - - that.tryBuffer = function (message) { - if (connection.state === $.signalR.connectionState.connecting) { - buffer.push(message); - - return true; - } - - return false; - }; - - that.drain = function () { - // Ensure that the connection is connected when we drain (do not want to drain while a connection is not active) - if (connection.state === $.signalR.connectionState.connected) { - while (buffer.length > 0) { - drainCallback(buffer.shift()); - } - } - }; - - that.clear = function () { - buffer = []; - }; - } - - signalR.fn = signalR.prototype = { - init: function (url, qs, logging) { - var $connection = $(this); - - this.url = url; - this.qs = qs; - this.lastError = null; - this._ = { - keepAliveData: {}, - connectingMessageBuffer: new ConnectingMessageBuffer(this, function (message) { - $connection.triggerHandler(events.onReceived, [message]); - }), - lastMessageAt: new Date().getTime(), - lastActiveAt: new Date().getTime(), - beatInterval: 5000, // Default value, will only be overridden if keep alive is enabled, - beatHandle: null, - totalTransportConnectTimeout: 0 // This will be the sum of the TransportConnectTimeout sent in response to negotiate and connection.transportConnectTimeout - }; - if (typeof (logging) === "boolean") { - this.logging = logging; - } - }, - - _parseResponse: function (response) { - var that = this; - - if (!response) { - return response; - } else if (typeof response === "string") { - return that.json.parse(response); - } else { - return response; - } - }, - - _originalJson: window.JSON, - - json: window.JSON, - - isCrossDomain: function (url, against) { - /// <summary>Checks if url is cross domain</summary> - /// <param name="url" type="String">The base URL</param> - /// <param name="against" type="Object"> - /// An optional argument to compare the URL against, if not specified it will be set to window.location. - /// If specified it must contain a protocol and a host property. - /// </param> - var link; - - url = $.trim(url); - - against = against || window.location; - - if (url.indexOf("http") !== 0) { - return false; - } - - // Create an anchor tag. - link = window.document.createElement("a"); - link.href = url; - - // When checking for cross domain we have to special case port 80 because the window.location will remove the - return link.protocol + addDefaultPort(link.protocol, link.host) !== against.protocol + addDefaultPort(against.protocol, against.host); - }, - - ajaxDataType: "text", - - contentType: "application/json; charset=UTF-8", - - logging: false, - - state: signalR.connectionState.disconnected, - - clientProtocol: "1.5", - - reconnectDelay: 2000, - - transportConnectTimeout: 0, - - disconnectTimeout: 30000, // This should be set by the server in response to the negotiate request (30s default) - - reconnectWindow: 30000, // This should be set by the server in response to the negotiate request - - keepAliveWarnAt: 2 / 3, // Warn user of slow connection if we breach the X% mark of the keep alive timeout - - start: function (options, callback) { - /// <summary>Starts the connection</summary> - /// <param name="options" type="Object">Options map</param> - /// <param name="callback" type="Function">A callback function to execute when the connection has started</param> - var connection = this, - config = { - pingInterval: 300000, - waitForPageLoad: true, - transport: "auto", - jsonp: false - }, - initialize, - deferred = connection._deferral || $.Deferred(), // Check to see if there is a pre-existing deferral that's being built on, if so we want to keep using it - parser = window.document.createElement("a"); - - connection.lastError = null; - - // Persist the deferral so that if start is called multiple times the same deferral is used. - connection._deferral = deferred; - - if (!connection.json) { - // no JSON! - throw new Error("SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8."); - } - - if ($.type(options) === "function") { - // Support calling with single callback parameter - callback = options; - } else if ($.type(options) === "object") { - $.extend(config, options); - if ($.type(config.callback) === "function") { - callback = config.callback; - } - } - - config.transport = validateTransport(config.transport, connection); - - // If the transport is invalid throw an error and abort start - if (!config.transport) { - throw new Error("SignalR: Invalid transport(s) specified, aborting start."); - } - - connection._.config = config; - - // Check to see if start is being called prior to page load - // If waitForPageLoad is true we then want to re-direct function call to the window load event - if (!_pageLoaded && config.waitForPageLoad === true) { - connection._.deferredStartHandler = function () { - connection.start(options, callback); - }; - _pageWindow.bind("load", connection._.deferredStartHandler); - - return deferred.promise(); - } - - // If we're already connecting just return the same deferral as the original connection start - if (connection.state === signalR.connectionState.connecting) { - return deferred.promise(); - } else if (changeState(connection, - signalR.connectionState.disconnected, - signalR.connectionState.connecting) === false) { - // We're not connecting so try and transition into connecting. - // If we fail to transition then we're either in connected or reconnecting. - - deferred.resolve(connection); - return deferred.promise(); - } - - configureStopReconnectingTimeout(connection); - - // Resolve the full url - parser.href = connection.url; - if (!parser.protocol || parser.protocol === ":") { - connection.protocol = window.document.location.protocol; - connection.host = parser.host || window.document.location.host; - } else { - connection.protocol = parser.protocol; - connection.host = parser.host; - } - - connection.baseUrl = connection.protocol + "//" + connection.host; - - // Set the websocket protocol - connection.wsProtocol = connection.protocol === "https:" ? "wss://" : "ws://"; - - // If jsonp with no/auto transport is specified, then set the transport to long polling - // since that is the only transport for which jsonp really makes sense. - // Some developers might actually choose to specify jsonp for same origin requests - // as demonstrated by Issue #623. - if (config.transport === "auto" && config.jsonp === true) { - config.transport = "longPolling"; - } - - // If the url is protocol relative, prepend the current windows protocol to the url. - if (connection.url.indexOf("//") === 0) { - connection.url = window.location.protocol + connection.url; - connection.log("Protocol relative URL detected, normalizing it to '" + connection.url + "'."); - } - - if (this.isCrossDomain(connection.url)) { - connection.log("Auto detected cross domain url."); - - if (config.transport === "auto") { - // TODO: Support XDM with foreverFrame - config.transport = ["webSockets", "serverSentEvents", "longPolling"]; - } - - if (typeof (config.withCredentials) === "undefined") { - config.withCredentials = true; - } - - // Determine if jsonp is the only choice for negotiation, ajaxSend and ajaxAbort. - // i.e. if the browser doesn't supports CORS - // If it is, ignore any preference to the contrary, and switch to jsonp. - if (!config.jsonp) { - config.jsonp = !$.support.cors; - - if (config.jsonp) { - connection.log("Using jsonp because this browser doesn't support CORS."); - } - } - - connection.contentType = signalR._.defaultContentType; - } - - connection.withCredentials = config.withCredentials; - - connection.ajaxDataType = config.jsonp ? "jsonp" : "text"; - - $(connection).bind(events.onStart, function (e, data) { - if ($.type(callback) === "function") { - callback.call(connection); - } - deferred.resolve(connection); - }); - - connection._.initHandler = signalR.transports._logic.initHandler(connection); - - initialize = function (transports, index) { - var noTransportError = signalR._.error(resources.noTransportOnInit); - - index = index || 0; - if (index >= transports.length) { - if (index === 0) { - connection.log("No transports supported by the server were selected."); - } else if (index === 1) { - connection.log("No fallback transports were selected."); - } else { - connection.log("Fallback transports exhausted."); - } - - // No transport initialized successfully - $(connection).triggerHandler(events.onError, [noTransportError]); - deferred.reject(noTransportError); - // Stop the connection if it has connected and move it into the disconnected state - connection.stop(); - return; - } - - // The connection was aborted - if (connection.state === signalR.connectionState.disconnected) { - return; - } - - var transportName = transports[index], - transport = signalR.transports[transportName], - onFallback = function () { - initialize(transports, index + 1); - }; - - connection.transport = transport; - - try { - connection._.initHandler.start(transport, function () { // success - // Firefox 11+ doesn't allow sync XHR withCredentials: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#withCredentials - var isFirefox11OrGreater = signalR._.firefoxMajorVersion(window.navigator.userAgent) >= 11, - asyncAbort = !!connection.withCredentials && isFirefox11OrGreater; - - connection.log("The start request succeeded. Transitioning to the connected state."); - - if (supportsKeepAlive(connection)) { - signalR.transports._logic.monitorKeepAlive(connection); - } - - signalR.transports._logic.startHeartbeat(connection); - - // Used to ensure low activity clients maintain their authentication. - // Must be configured once a transport has been decided to perform valid ping requests. - signalR._.configurePingInterval(connection); - - if (!changeState(connection, - signalR.connectionState.connecting, - signalR.connectionState.connected)) { - connection.log("WARNING! The connection was not in the connecting state."); - } - - // Drain any incoming buffered messages (messages that came in prior to connect) - connection._.connectingMessageBuffer.drain(); - - $(connection).triggerHandler(events.onStart); - - // wire the stop handler for when the user leaves the page - _pageWindow.bind("unload", function () { - connection.log("Window unloading, stopping the connection."); - - connection.stop(asyncAbort); - }); - - if (isFirefox11OrGreater) { - // Firefox does not fire cross-domain XHRs in the normal unload handler on tab close. - // #2400 - _pageWindow.bind("beforeunload", function () { - // If connection.stop() runs runs in beforeunload and fails, it will also fail - // in unload unless connection.stop() runs after a timeout. - window.setTimeout(function () { - connection.stop(asyncAbort); - }, 0); - }); - } - }, onFallback); - } - catch (error) { - connection.log(transport.name + " transport threw '" + error.message + "' when attempting to start."); - onFallback(); - } - }; - - var url = connection.url + "/negotiate", - onFailed = function (error, connection) { - var err = signalR._.error(resources.errorOnNegotiate, error, connection._.negotiateRequest); - - $(connection).triggerHandler(events.onError, err); - deferred.reject(err); - // Stop the connection if negotiate failed - connection.stop(); - }; - - $(connection).triggerHandler(events.onStarting); - - url = signalR.transports._logic.prepareQueryString(connection, url); - - connection.log("Negotiating with '" + url + "'."); - - // Save the ajax negotiate request object so we can abort it if stop is called while the request is in flight. - connection._.negotiateRequest = signalR.transports._logic.ajax(connection, { - url: url, - error: function (error, statusText) { - // We don't want to cause any errors if we're aborting our own negotiate request. - if (statusText !== _negotiateAbortText) { - onFailed(error, connection); - } else { - // This rejection will noop if the deferred has already been resolved or rejected. - deferred.reject(signalR._.error(resources.stoppedWhileNegotiating, null /* error */, connection._.negotiateRequest)); - } - }, - success: function (result) { - var res, - keepAliveData, - protocolError, - transports = [], - supportedTransports = []; - - try { - res = connection._parseResponse(result); - } catch (error) { - onFailed(signalR._.error(resources.errorParsingNegotiateResponse, error), connection); - return; - } - - keepAliveData = connection._.keepAliveData; - connection.appRelativeUrl = res.Url; - connection.id = res.ConnectionId; - connection.token = res.ConnectionToken; - connection.webSocketServerUrl = res.WebSocketServerUrl; - - // The long poll timeout is the ConnectionTimeout plus 10 seconds - connection._.pollTimeout = res.ConnectionTimeout * 1000 + 10000; // in ms - - // Once the server has labeled the PersistentConnection as Disconnected, we should stop attempting to reconnect - // after res.DisconnectTimeout seconds. - connection.disconnectTimeout = res.DisconnectTimeout * 1000; // in ms - - // Add the TransportConnectTimeout from the response to the transportConnectTimeout from the client to calculate the total timeout - connection._.totalTransportConnectTimeout = connection.transportConnectTimeout + res.TransportConnectTimeout * 1000; - - // If we have a keep alive - if (res.KeepAliveTimeout) { - // Register the keep alive data as activated - keepAliveData.activated = true; - - // Timeout to designate when to force the connection into reconnecting converted to milliseconds - keepAliveData.timeout = res.KeepAliveTimeout * 1000; - - // Timeout to designate when to warn the developer that the connection may be dead or is not responding. - keepAliveData.timeoutWarning = keepAliveData.timeout * connection.keepAliveWarnAt; - - // Instantiate the frequency in which we check the keep alive. It must be short in order to not miss/pick up any changes - connection._.beatInterval = (keepAliveData.timeout - keepAliveData.timeoutWarning) / 3; - } else { - keepAliveData.activated = false; - } - - connection.reconnectWindow = connection.disconnectTimeout + (keepAliveData.timeout || 0); - - if (!res.ProtocolVersion || res.ProtocolVersion !== connection.clientProtocol) { - protocolError = signalR._.error(signalR._.format(resources.protocolIncompatible, connection.clientProtocol, res.ProtocolVersion)); - $(connection).triggerHandler(events.onError, [protocolError]); - deferred.reject(protocolError); - - return; - } - - $.each(signalR.transports, function (key) { - if ((key.indexOf("_") === 0) || (key === "webSockets" && !res.TryWebSockets)) { - return true; - } - supportedTransports.push(key); - }); - - if ($.isArray(config.transport)) { - $.each(config.transport, function (_, transport) { - if ($.inArray(transport, supportedTransports) >= 0) { - transports.push(transport); - } - }); - } else if (config.transport === "auto") { - transports = supportedTransports; - } else if ($.inArray(config.transport, supportedTransports) >= 0) { - transports.push(config.transport); - } - - initialize(transports); - } - }); - - return deferred.promise(); - }, - - starting: function (callback) { - /// <summary>Adds a callback that will be invoked before anything is sent over the connection</summary> - /// <param name="callback" type="Function">A callback function to execute before the connection is fully instantiated.</param> - /// <returns type="signalR" /> - var connection = this; - $(connection).bind(events.onStarting, function (e, data) { - callback.call(connection); - }); - return connection; - }, - - send: function (data) { - /// <summary>Sends data over the connection</summary> - /// <param name="data" type="String">The data to send over the connection</param> - /// <returns type="signalR" /> - var connection = this; - - if (connection.state === signalR.connectionState.disconnected) { - // Connection hasn't been started yet - throw new Error("SignalR: Connection must be started before data can be sent. Call .start() before .send()"); - } - - if (connection.state === signalR.connectionState.connecting) { - // Connection hasn't been started yet - throw new Error("SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started."); - } - - connection.transport.send(connection, data); - // REVIEW: Should we return deferred here? - return connection; - }, - - received: function (callback) { - /// <summary>Adds a callback that will be invoked after anything is received over the connection</summary> - /// <param name="callback" type="Function">A callback function to execute when any data is received on the connection</param> - /// <returns type="signalR" /> - var connection = this; - $(connection).bind(events.onReceived, function (e, data) { - callback.call(connection, data); - }); - return connection; - }, - - stateChanged: function (callback) { - /// <summary>Adds a callback that will be invoked when the connection state changes</summary> - /// <param name="callback" type="Function">A callback function to execute when the connection state changes</param> - /// <returns type="signalR" /> - var connection = this; - $(connection).bind(events.onStateChanged, function (e, data) { - callback.call(connection, data); - }); - return connection; - }, - - error: function (callback) { - /// <summary>Adds a callback that will be invoked after an error occurs with the connection</summary> - /// <param name="callback" type="Function">A callback function to execute when an error occurs on the connection</param> - /// <returns type="signalR" /> - var connection = this; - $(connection).bind(events.onError, function (e, errorData, sendData) { - connection.lastError = errorData; - // In practice 'errorData' is the SignalR built error object. - // In practice 'sendData' is undefined for all error events except those triggered by - // 'ajaxSend' and 'webSockets.send'.'sendData' is the original send payload. - callback.call(connection, errorData, sendData); - }); - return connection; - }, - - disconnected: function (callback) { - /// <summary>Adds a callback that will be invoked when the client disconnects</summary> - /// <param name="callback" type="Function">A callback function to execute when the connection is broken</param> - /// <returns type="signalR" /> - var connection = this; - $(connection).bind(events.onDisconnect, function (e, data) { - callback.call(connection); - }); - return connection; - }, - - connectionSlow: function (callback) { - /// <summary>Adds a callback that will be invoked when the client detects a slow connection</summary> - /// <param name="callback" type="Function">A callback function to execute when the connection is slow</param> - /// <returns type="signalR" /> - var connection = this; - $(connection).bind(events.onConnectionSlow, function (e, data) { - callback.call(connection); - }); - - return connection; - }, - - reconnecting: function (callback) { - /// <summary>Adds a callback that will be invoked when the underlying transport begins reconnecting</summary> - /// <param name="callback" type="Function">A callback function to execute when the connection enters a reconnecting state</param> - /// <returns type="signalR" /> - var connection = this; - $(connection).bind(events.onReconnecting, function (e, data) { - callback.call(connection); - }); - return connection; - }, - - reconnected: function (callback) { - /// <summary>Adds a callback that will be invoked when the underlying transport reconnects</summary> - /// <param name="callback" type="Function">A callback function to execute when the connection is restored</param> - /// <returns type="signalR" /> - var connection = this; - $(connection).bind(events.onReconnect, function (e, data) { - callback.call(connection); - }); - return connection; - }, - - stop: function (async, notifyServer) { - /// <summary>Stops listening</summary> - /// <param name="async" type="Boolean">Whether or not to asynchronously abort the connection</param> - /// <param name="notifyServer" type="Boolean">Whether we want to notify the server that we are aborting the connection</param> - /// <returns type="signalR" /> - var connection = this, - // Save deferral because this is always cleaned up - deferral = connection._deferral; - - // Verify that we've bound a load event. - if (connection._.deferredStartHandler) { - // Unbind the event. - _pageWindow.unbind("load", connection._.deferredStartHandler); - } - - // Always clean up private non-timeout based state. - delete connection._.config; - delete connection._.deferredStartHandler; - - // This needs to be checked despite the connection state because a connection start can be deferred until page load. - // If we've deferred the start due to a page load we need to unbind the "onLoad" -> start event. - if (!_pageLoaded && (!connection._.config || connection._.config.waitForPageLoad === true)) { - connection.log("Stopping connection prior to negotiate."); - - // If we have a deferral we should reject it - if (deferral) { - deferral.reject(signalR._.error(resources.stoppedWhileLoading)); - } - - // Short-circuit because the start has not been fully started. - return; - } - - if (connection.state === signalR.connectionState.disconnected) { - return; - } - - connection.log("Stopping connection."); - - changeState(connection, connection.state, signalR.connectionState.disconnected); - - // Clear this no matter what - window.clearTimeout(connection._.beatHandle); - window.clearInterval(connection._.pingIntervalId); - - if (connection.transport) { - connection.transport.stop(connection); - - if (notifyServer !== false) { - connection.transport.abort(connection, async); - } - - if (supportsKeepAlive(connection)) { - signalR.transports._logic.stopMonitoringKeepAlive(connection); - } - - connection.transport = null; - } - - if (connection._.negotiateRequest) { - // If the negotiation request has already completed this will noop. - connection._.negotiateRequest.abort(_negotiateAbortText); - delete connection._.negotiateRequest; - } - - // Ensure that initHandler.stop() is called before connection._deferral is deleted - if (connection._.initHandler) { - connection._.initHandler.stop(); - } - - // Trigger the disconnect event - $(connection).triggerHandler(events.onDisconnect); - - delete connection._deferral; - delete connection.messageId; - delete connection.groupsToken; - delete connection.id; - delete connection._.pingIntervalId; - delete connection._.lastMessageAt; - delete connection._.lastActiveAt; - - // Clear out our message buffer - connection._.connectingMessageBuffer.clear(); - - return connection; - }, - - log: function (msg) { - log(msg, this.logging); - } - }; - - signalR.fn.init.prototype = signalR.fn; - - signalR.noConflict = function () { - /// <summary>Reinstates the original value of $.connection and returns the signalR object for manual assignment</summary> - /// <returns type="signalR" /> - if ($.connection === signalR) { - $.connection = _connection; - } - return signalR; - }; - - if ($.connection) { - _connection = $.connection; - } - - $.connection = $.signalR = signalR; - -}(window.jQuery, window)); -/* jquery.signalR.transports.common.js */ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information. - -/*global window:false */ -/// <reference path="jquery.signalR.core.js" /> - -(function ($, window, undefined) { - - var signalR = $.signalR, - events = $.signalR.events, - changeState = $.signalR.changeState, - startAbortText = "__Start Aborted__", - transportLogic; - - signalR.transports = {}; - - function beat(connection) { - if (connection._.keepAliveData.monitoring) { - checkIfAlive(connection); - } - - // Ensure that we successfully marked active before continuing the heartbeat. - if (transportLogic.markActive(connection)) { - connection._.beatHandle = window.setTimeout(function () { - beat(connection); - }, connection._.beatInterval); - } - } - - function checkIfAlive(connection) { - var keepAliveData = connection._.keepAliveData, - timeElapsed; - - // Only check if we're connected - if (connection.state === signalR.connectionState.connected) { - timeElapsed = new Date().getTime() - connection._.lastMessageAt; - - // Check if the keep alive has completely timed out - if (timeElapsed >= keepAliveData.timeout) { - connection.log("Keep alive timed out. Notifying transport that connection has been lost."); - - // Notify transport that the connection has been lost - connection.transport.lostConnection(connection); - } else if (timeElapsed >= keepAliveData.timeoutWarning) { - // This is to assure that the user only gets a single warning - if (!keepAliveData.userNotified) { - connection.log("Keep alive has been missed, connection may be dead/slow."); - $(connection).triggerHandler(events.onConnectionSlow); - keepAliveData.userNotified = true; - } - } else { - keepAliveData.userNotified = false; - } - } - } - - function getAjaxUrl(connection, path) { - var url = connection.url + path; - - if (connection.transport) { - url += "?transport=" + connection.transport.name; - } - - return transportLogic.prepareQueryString(connection, url); - } - - function InitHandler(connection) { - this.connection = connection; - - this.startRequested = false; - this.startCompleted = false; - this.connectionStopped = false; - } - - InitHandler.prototype = { - start: function (transport, onSuccess, onFallback) { - var that = this, - connection = that.connection, - failCalled = false; - - if (that.startRequested || that.connectionStopped) { - connection.log("WARNING! " + transport.name + " transport cannot be started. Initialization ongoing or completed."); - return; - } - - connection.log(transport.name + " transport starting."); - - that.transportTimeoutHandle = window.setTimeout(function () { - if (!failCalled) { - failCalled = true; - connection.log(transport.name + " transport timed out when trying to connect."); - that.transportFailed(transport, undefined, onFallback); - } - }, connection._.totalTransportConnectTimeout); - - transport.start(connection, function () { - if (!failCalled) { - that.initReceived(transport, onSuccess); - } - }, function (error) { - // Don't allow the same transport to cause onFallback to be called twice - if (!failCalled) { - failCalled = true; - that.transportFailed(transport, error, onFallback); - } - - // Returns true if the transport should stop; - // false if it should attempt to reconnect - return !that.startCompleted || that.connectionStopped; - }); - }, - - stop: function () { - this.connectionStopped = true; - window.clearTimeout(this.transportTimeoutHandle); - signalR.transports._logic.tryAbortStartRequest(this.connection); - }, - - initReceived: function (transport, onSuccess) { - var that = this, - connection = that.connection; - - if (that.startRequested) { - connection.log("WARNING! The client received multiple init messages."); - return; - } - - if (that.connectionStopped) { - return; - } - - that.startRequested = true; - window.clearTimeout(that.transportTimeoutHandle); - - connection.log(transport.name + " transport connected. Initiating start request."); - signalR.transports._logic.ajaxStart(connection, function () { - that.startCompleted = true; - onSuccess(); - }); - }, - - transportFailed: function (transport, error, onFallback) { - var connection = this.connection, - deferred = connection._deferral, - wrappedError; - - if (this.connectionStopped) { - return; - } - - window.clearTimeout(this.transportTimeoutHandle); - - if (!this.startRequested) { - transport.stop(connection); - - connection.log(transport.name + " transport failed to connect. Attempting to fall back."); - onFallback(); - } else if (!this.startCompleted) { - // Do not attempt to fall back if a start request is ongoing during a transport failure. - // Instead, trigger an error and stop the connection. - wrappedError = signalR._.error(signalR.resources.errorDuringStartRequest, error); - - connection.log(transport.name + " transport failed during the start request. Stopping the connection."); - $(connection).triggerHandler(events.onError, [wrappedError]); - if (deferred) { - deferred.reject(wrappedError); - } - - connection.stop(); - } else { - // The start request has completed, but the connection has not stopped. - // No need to do anything here. The transport should attempt its normal reconnect logic. - } - } - }; - - transportLogic = signalR.transports._logic = { - ajax: function (connection, options) { - return $.ajax( - $.extend(/*deep copy*/ true, {}, $.signalR.ajaxDefaults, { - type: "GET", - data: {}, - xhrFields: { withCredentials: connection.withCredentials }, - contentType: connection.contentType, - dataType: connection.ajaxDataType - }, options)); - }, - - pingServer: function (connection) { - /// <summary>Pings the server</summary> - /// <param name="connection" type="signalr">Connection associated with the server ping</param> - /// <returns type="signalR" /> - var url, - xhr, - deferral = $.Deferred(); - - if (connection.transport) { - url = connection.url + "/ping"; - - url = transportLogic.addQs(url, connection.qs); - - xhr = transportLogic.ajax(connection, { - url: url, - success: function (result) { - var data; - - try { - data = connection._parseResponse(result); - } - catch (error) { - deferral.reject( - signalR._.transportError( - signalR.resources.pingServerFailedParse, - connection.transport, - error, - xhr - ) - ); - connection.stop(); - return; - } - - if (data.Response === "pong") { - deferral.resolve(); - } - else { - deferral.reject( - signalR._.transportError( - signalR._.format(signalR.resources.pingServerFailedInvalidResponse, result), - connection.transport, - null /* error */, - xhr - ) - ); - } - }, - error: function (error) { - if (error.status === 401 || error.status === 403) { - deferral.reject( - signalR._.transportError( - signalR._.format(signalR.resources.pingServerFailedStatusCode, error.status), - connection.transport, - error, - xhr - ) - ); - connection.stop(); - } - else { - deferral.reject( - signalR._.transportError( - signalR.resources.pingServerFailed, - connection.transport, - error, - xhr - ) - ); - } - } - }); - } - else { - deferral.reject( - signalR._.transportError( - signalR.resources.noConnectionTransport, - connection.transport - ) - ); - } - - return deferral.promise(); - }, - - prepareQueryString: function (connection, url) { - var preparedUrl; - - // Use addQs to start since it handles the ?/& prefix for us - preparedUrl = transportLogic.addQs(url, "clientProtocol=" + connection.clientProtocol); - - // Add the user-specified query string params if any - preparedUrl = transportLogic.addQs(preparedUrl, connection.qs); - - if (connection.token) { - preparedUrl += "&connectionToken=" + window.encodeURIComponent(connection.token); - } - - if (connection.data) { - preparedUrl += "&connectionData=" + window.encodeURIComponent(connection.data); - } - - return preparedUrl; - }, - - addQs: function (url, qs) { - var appender = url.indexOf("?") !== -1 ? "&" : "?", - firstChar; - - if (!qs) { - return url; - } - - if (typeof (qs) === "object") { - return url + appender + $.param(qs); - } - - if (typeof (qs) === "string") { - firstChar = qs.charAt(0); - - if (firstChar === "?" || firstChar === "&") { - appender = ""; - } - - return url + appender + qs; - } - - throw new Error("Query string property must be either a string or object."); - }, - - // BUG #2953: The url needs to be same otherwise it will cause a memory leak - getUrl: function (connection, transport, reconnecting, poll, ajaxPost) { - /// <summary>Gets the url for making a GET based connect request</summary> - var baseUrl = transport === "webSockets" ? "" : connection.baseUrl, - url = baseUrl + connection.appRelativeUrl, - qs = "transport=" + transport; - - if (!ajaxPost && connection.groupsToken) { - qs += "&groupsToken=" + window.encodeURIComponent(connection.groupsToken); - } - - if (!reconnecting) { - url += "/connect"; - } else { - if (poll) { - // longPolling transport specific - url += "/poll"; - } else { - url += "/reconnect"; - } - - if (!ajaxPost && connection.messageId) { - qs += "&messageId=" + window.encodeURIComponent(connection.messageId); - } - } - url += "?" + qs; - url = transportLogic.prepareQueryString(connection, url); - - if (!ajaxPost) { - url += "&tid=" + Math.floor(Math.random() * 11); - } - - return url; - }, - - maximizePersistentResponse: function (minPersistentResponse) { - return { - MessageId: minPersistentResponse.C, - Messages: minPersistentResponse.M, - Initialized: typeof (minPersistentResponse.S) !== "undefined" ? true : false, - ShouldReconnect: typeof (minPersistentResponse.T) !== "undefined" ? true : false, - LongPollDelay: minPersistentResponse.L, - GroupsToken: minPersistentResponse.G - }; - }, - - updateGroups: function (connection, groupsToken) { - if (groupsToken) { - connection.groupsToken = groupsToken; - } - }, - - stringifySend: function (connection, message) { - if (typeof (message) === "string" || typeof (message) === "undefined" || message === null) { - return message; - } - return connection.json.stringify(message); - }, - - ajaxSend: function (connection, data) { - var payload = transportLogic.stringifySend(connection, data), - url = getAjaxUrl(connection, "/send"), - xhr, - onFail = function (error, connection) { - $(connection).triggerHandler(events.onError, [signalR._.transportError(signalR.resources.sendFailed, connection.transport, error, xhr), data]); - }; - - - xhr = transportLogic.ajax(connection, { - url: url, - type: connection.ajaxDataType === "jsonp" ? "GET" : "POST", - contentType: signalR._.defaultContentType, - data: { - data: payload - }, - success: function (result) { - var res; - - if (result) { - try { - res = connection._parseResponse(result); - } - catch (error) { - onFail(error, connection); - connection.stop(); - return; - } - - transportLogic.triggerReceived(connection, res); - } - }, - error: function (error, textStatus) { - if (textStatus === "abort" || textStatus === "parsererror") { - // The parsererror happens for sends that don't return any data, and hence - // don't write the jsonp callback to the response. This is harder to fix on the server - // so just hack around it on the client for now. - return; - } - - onFail(error, connection); - } - }); - - return xhr; - }, - - ajaxAbort: function (connection, async) { - if (typeof (connection.transport) === "undefined") { - return; - } - - // Async by default unless explicitly overidden - async = typeof async === "undefined" ? true : async; - - var url = getAjaxUrl(connection, "/abort"); - - transportLogic.ajax(connection, { - url: url, - async: async, - timeout: 1000, - type: "POST" - }); - - connection.log("Fired ajax abort async = " + async + "."); - }, - - ajaxStart: function (connection, onSuccess) { - var rejectDeferred = function (error) { - var deferred = connection._deferral; - if (deferred) { - deferred.reject(error); - } - }, - triggerStartError = function (error) { - connection.log("The start request failed. Stopping the connection."); - $(connection).triggerHandler(events.onError, [error]); - rejectDeferred(error); - connection.stop(); - }; - - connection._.startRequest = transportLogic.ajax(connection, { - url: getAjaxUrl(connection, "/start"), - success: function (result, statusText, xhr) { - var data; - - try { - data = connection._parseResponse(result); - } catch (error) { - triggerStartError(signalR._.error( - signalR._.format(signalR.resources.errorParsingStartResponse, result), - error, xhr)); - return; - } - - if (data.Response === "started") { - onSuccess(); - } else { - triggerStartError(signalR._.error( - signalR._.format(signalR.resources.invalidStartResponse, result), - null /* error */, xhr)); - } - }, - error: function (xhr, statusText, error) { - if (statusText !== startAbortText) { - triggerStartError(signalR._.error( - signalR.resources.errorDuringStartRequest, - error, xhr)); - } else { - // Stop has been called, no need to trigger the error handler - // or stop the connection again with onStartError - connection.log("The start request aborted because connection.stop() was called."); - rejectDeferred(signalR._.error( - signalR.resources.stoppedDuringStartRequest, - null /* error */, xhr)); - } - } - }); - }, - - tryAbortStartRequest: function (connection) { - if (connection._.startRequest) { - // If the start request has already completed this will noop. - connection._.startRequest.abort(startAbortText); - delete connection._.startRequest; - } - }, - - tryInitialize: function (persistentResponse, onInitialized) { - if (persistentResponse.Initialized) { - onInitialized(); - } - }, - - triggerReceived: function (connection, data) { - if (!connection._.connectingMessageBuffer.tryBuffer(data)) { - $(connection).triggerHandler(events.onReceived, [data]); - } - }, - - processMessages: function (connection, minData, onInitialized) { - var data; - - // Update the last message time stamp - transportLogic.markLastMessage(connection); - - if (minData) { - data = transportLogic.maximizePersistentResponse(minData); - - transportLogic.updateGroups(connection, data.GroupsToken); - - if (data.MessageId) { - connection.messageId = data.MessageId; - } - - if (data.Messages) { - $.each(data.Messages, function (index, message) { - transportLogic.triggerReceived(connection, message); - }); - - transportLogic.tryInitialize(data, onInitialized); - } - } - }, - - monitorKeepAlive: function (connection) { - var keepAliveData = connection._.keepAliveData; - - // If we haven't initiated the keep alive timeouts then we need to - if (!keepAliveData.monitoring) { - keepAliveData.monitoring = true; - - transportLogic.markLastMessage(connection); - - // Save the function so we can unbind it on stop - connection._.keepAliveData.reconnectKeepAliveUpdate = function () { - // Mark a new message so that keep alive doesn't time out connections - transportLogic.markLastMessage(connection); - }; - - // Update Keep alive on reconnect - $(connection).bind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate); - - connection.log("Now monitoring keep alive with a warning timeout of " + keepAliveData.timeoutWarning + ", keep alive timeout of " + keepAliveData.timeout + " and disconnecting timeout of " + connection.disconnectTimeout); - } else { - connection.log("Tried to monitor keep alive but it's already being monitored."); - } - }, - - stopMonitoringKeepAlive: function (connection) { - var keepAliveData = connection._.keepAliveData; - - // Only attempt to stop the keep alive monitoring if its being monitored - if (keepAliveData.monitoring) { - // Stop monitoring - keepAliveData.monitoring = false; - - // Remove the updateKeepAlive function from the reconnect event - $(connection).unbind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate); - - // Clear all the keep alive data - connection._.keepAliveData = {}; - connection.log("Stopping the monitoring of the keep alive."); - } - }, - - startHeartbeat: function (connection) { - connection._.lastActiveAt = new Date().getTime(); - beat(connection); - }, - - markLastMessage: function (connection) { - connection._.lastMessageAt = new Date().getTime(); - }, - - markActive: function (connection) { - if (transportLogic.verifyLastActive(connection)) { - connection._.lastActiveAt = new Date().getTime(); - return true; - } - - return false; - }, - - isConnectedOrReconnecting: function (connection) { - return connection.state === signalR.connectionState.connected || - connection.state === signalR.connectionState.reconnecting; - }, - - ensureReconnectingState: function (connection) { - if (changeState(connection, - signalR.connectionState.connected, - signalR.connectionState.reconnecting) === true) { - $(connection).triggerHandler(events.onReconnecting); - } - return connection.state === signalR.connectionState.reconnecting; - }, - - clearReconnectTimeout: function (connection) { - if (connection && connection._.reconnectTimeout) { - window.clearTimeout(connection._.reconnectTimeout); - delete connection._.reconnectTimeout; - } - }, - - verifyLastActive: function (connection) { - if (new Date().getTime() - connection._.lastActiveAt >= connection.reconnectWindow) { - var message = signalR._.format(signalR.resources.reconnectWindowTimeout, new Date(connection._.lastActiveAt), connection.reconnectWindow); - connection.log(message); - $(connection).triggerHandler(events.onError, [signalR._.error(message, /* source */ "TimeoutException")]); - connection.stop(/* async */ false, /* notifyServer */ false); - return false; - } - - return true; - }, - - reconnect: function (connection, transportName) { - var transport = signalR.transports[transportName]; - - // We should only set a reconnectTimeout if we are currently connected - // and a reconnectTimeout isn't already set. - if (transportLogic.isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) { - // Need to verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration. - if (!transportLogic.verifyLastActive(connection)) { - return; - } - - connection._.reconnectTimeout = window.setTimeout(function () { - if (!transportLogic.verifyLastActive(connection)) { - return; - } - - transport.stop(connection); - - if (transportLogic.ensureReconnectingState(connection)) { - connection.log(transportName + " reconnecting."); - transport.start(connection); - } - }, connection.reconnectDelay); - } - }, - - handleParseFailure: function (connection, result, error, onFailed, context) { - var wrappedError = signalR._.transportError( - signalR._.format(signalR.resources.parseFailed, result), - connection.transport, - error, - context); - - // If we're in the initialization phase trigger onFailed, otherwise stop the connection. - if (onFailed && onFailed(wrappedError)) { - connection.log("Failed to parse server response while attempting to connect."); - } else { - $(connection).triggerHandler(events.onError, [wrappedError]); - connection.stop(); - } - }, - - initHandler: function (connection) { - return new InitHandler(connection); - }, - - foreverFrame: { - count: 0, - connections: {} - } - }; - -}(window.jQuery, window)); -/* jquery.signalR.transports.webSockets.js */ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information. - -/*global window:false */ -/// <reference path="jquery.signalR.transports.common.js" /> - -(function ($, window, undefined) { - - var signalR = $.signalR, - events = $.signalR.events, - changeState = $.signalR.changeState, - transportLogic = signalR.transports._logic; - - signalR.transports.webSockets = { - name: "webSockets", - - supportsKeepAlive: function () { - return true; - }, - - send: function (connection, data) { - var payload = transportLogic.stringifySend(connection, data); - - try { - connection.socket.send(payload); - } catch (ex) { - $(connection).triggerHandler(events.onError, - [signalR._.transportError( - signalR.resources.webSocketsInvalidState, - connection.transport, - ex, - connection.socket - ), - data]); - } - }, - - start: function (connection, onSuccess, onFailed) { - var url, - opened = false, - that = this, - reconnecting = !onSuccess, - $connection = $(connection); - - if (!window.WebSocket) { - onFailed(); - return; - } - - if (!connection.socket) { - if (connection.webSocketServerUrl) { - url = connection.webSocketServerUrl; - } else { - url = connection.wsProtocol + connection.host; - } - - url += transportLogic.getUrl(connection, this.name, reconnecting); - - connection.log("Connecting to websocket endpoint '" + url + "'."); - connection.socket = new window.WebSocket(url); - - connection.socket.onopen = function () { - opened = true; - connection.log("Websocket opened."); - - transportLogic.clearReconnectTimeout(connection); - - if (changeState(connection, - signalR.connectionState.reconnecting, - signalR.connectionState.connected) === true) { - $connection.triggerHandler(events.onReconnect); - } - }; - - connection.socket.onclose = function (event) { - var error; - - // Only handle a socket close if the close is from the current socket. - // Sometimes on disconnect the server will push down an onclose event - // to an expired socket. - - if (this === connection.socket) { - if (opened && typeof event.wasClean !== "undefined" && event.wasClean === false) { - // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but - // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers. - error = signalR._.transportError( - signalR.resources.webSocketClosed, - connection.transport, - event); - - connection.log("Unclean disconnect from websocket: " + (event.reason || "[no reason given].")); - } else { - connection.log("Websocket closed."); - } - - if (!onFailed || !onFailed(error)) { - if (error) { - $(connection).triggerHandler(events.onError, [error]); - } - - that.reconnect(connection); - } - } - }; - - connection.socket.onmessage = function (event) { - var data; - - try { - data = connection._parseResponse(event.data); - } - catch (error) { - transportLogic.handleParseFailure(connection, event.data, error, onFailed, event); - return; - } - - if (data) { - // data.M is PersistentResponse.Messages - if ($.isEmptyObject(data) || data.M) { - transportLogic.processMessages(connection, data, onSuccess); - } else { - // For websockets we need to trigger onReceived - // for callbacks to outgoing hub calls. - transportLogic.triggerReceived(connection, data); - } - } - }; - } - }, - - reconnect: function (connection) { - transportLogic.reconnect(connection, this.name); - }, - - lostConnection: function (connection) { - this.reconnect(connection); - }, - - stop: function (connection) { - // Don't trigger a reconnect after stopping - transportLogic.clearReconnectTimeout(connection); - - if (connection.socket) { - connection.log("Closing the Websocket."); - connection.socket.close(); - connection.socket = null; - } - }, - - abort: function (connection, async) { - transportLogic.ajaxAbort(connection, async); - } - }; - -}(window.jQuery, window)); -/* jquery.signalR.transports.serverSentEvents.js */ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information. - -/*global window:false */ -/// <reference path="jquery.signalR.transports.common.js" /> - -(function ($, window, undefined) { - - var signalR = $.signalR, - events = $.signalR.events, - changeState = $.signalR.changeState, - transportLogic = signalR.transports._logic, - clearReconnectAttemptTimeout = function (connection) { - window.clearTimeout(connection._.reconnectAttemptTimeoutHandle); - delete connection._.reconnectAttemptTimeoutHandle; - }; - - signalR.transports.serverSentEvents = { - name: "serverSentEvents", - - supportsKeepAlive: function () { - return true; - }, - - timeOut: 3000, - - start: function (connection, onSuccess, onFailed) { - var that = this, - opened = false, - $connection = $(connection), - reconnecting = !onSuccess, - url; - - if (connection.eventSource) { - connection.log("The connection already has an event source. Stopping it."); - connection.stop(); - } - - if (!window.EventSource) { - if (onFailed) { - connection.log("This browser doesn't support SSE."); - onFailed(); - } - return; - } - - url = transportLogic.getUrl(connection, this.name, reconnecting); - - try { - connection.log("Attempting to connect to SSE endpoint '" + url + "'."); - connection.eventSource = new window.EventSource(url, { withCredentials: connection.withCredentials }); - } - catch (e) { - connection.log("EventSource failed trying to connect with error " + e.Message + "."); - if (onFailed) { - // The connection failed, call the failed callback - onFailed(); - } else { - $connection.triggerHandler(events.onError, [signalR._.transportError(signalR.resources.eventSourceFailedToConnect, connection.transport, e)]); - if (reconnecting) { - // If we were reconnecting, rather than doing initial connect, then try reconnect again - that.reconnect(connection); - } - } - return; - } - - if (reconnecting) { - connection._.reconnectAttemptTimeoutHandle = window.setTimeout(function () { - if (opened === false) { - // If we're reconnecting and the event source is attempting to connect, - // don't keep retrying. This causes duplicate connections to spawn. - if (connection.eventSource.readyState !== window.EventSource.OPEN) { - // If we were reconnecting, rather than doing initial connect, then try reconnect again - that.reconnect(connection); - } - } - }, - that.timeOut); - } - - connection.eventSource.addEventListener("open", function (e) { - connection.log("EventSource connected."); - - clearReconnectAttemptTimeout(connection); - transportLogic.clearReconnectTimeout(connection); - - if (opened === false) { - opened = true; - - if (changeState(connection, - signalR.connectionState.reconnecting, - signalR.connectionState.connected) === true) { - $connection.triggerHandler(events.onReconnect); - } - } - }, false); - - connection.eventSource.addEventListener("message", function (e) { - var res; - - // process messages - if (e.data === "initialized") { - return; - } - - try { - res = connection._parseResponse(e.data); - } - catch (error) { - transportLogic.handleParseFailure(connection, e.data, error, onFailed, e); - return; - } - - transportLogic.processMessages(connection, res, onSuccess); - }, false); - - connection.eventSource.addEventListener("error", function (e) { - var error = signalR._.transportError( - signalR.resources.eventSourceError, - connection.transport, - e); - - // Only handle an error if the error is from the current Event Source. - // Sometimes on disconnect the server will push down an error event - // to an expired Event Source. - if (this !== connection.eventSource) { - return; - } - - if (onFailed && onFailed(error)) { - return; - } - - connection.log("EventSource readyState: " + connection.eventSource.readyState + "."); - - if (e.eventPhase === window.EventSource.CLOSED) { - // We don't use the EventSource's native reconnect function as it - // doesn't allow us to change the URL when reconnecting. We need - // to change the URL to not include the /connect suffix, and pass - // the last message id we received. - connection.log("EventSource reconnecting due to the server connection ending."); - that.reconnect(connection); - } else { - // connection error - connection.log("EventSource error."); - $connection.triggerHandler(events.onError, [error]); - } - }, false); - }, - - reconnect: function (connection) { - transportLogic.reconnect(connection, this.name); - }, - - lostConnection: function (connection) { - this.reconnect(connection); - }, - - send: function (connection, data) { - transportLogic.ajaxSend(connection, data); - }, - - stop: function (connection) { - // Don't trigger a reconnect after stopping - clearReconnectAttemptTimeout(connection); - transportLogic.clearReconnectTimeout(connection); - - if (connection && connection.eventSource) { - connection.log("EventSource calling close()."); - connection.eventSource.close(); - connection.eventSource = null; - delete connection.eventSource; - } - }, - - abort: function (connection, async) { - transportLogic.ajaxAbort(connection, async); - } - }; - -}(window.jQuery, window)); -/* jquery.signalR.transports.foreverFrame.js */ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information. - -/*global window:false */ -/// <reference path="jquery.signalR.transports.common.js" /> - -(function ($, window, undefined) { - - var signalR = $.signalR, - events = $.signalR.events, - changeState = $.signalR.changeState, - transportLogic = signalR.transports._logic, - createFrame = function () { - var frame = window.document.createElement("iframe"); - frame.setAttribute("style", "position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;"); - return frame; - }, - // Used to prevent infinite loading icon spins in older versions of ie - // We build this object inside a closure so we don't pollute the rest of - // the foreverFrame transport with unnecessary functions/utilities. - loadPreventer = (function () { - var loadingFixIntervalId = null, - loadingFixInterval = 1000, - attachedTo = 0; - - return { - prevent: function () { - // Prevent additional iframe removal procedures from newer browsers - if (signalR._.ieVersion <= 8) { - // We only ever want to set the interval one time, so on the first attachedTo - if (attachedTo === 0) { - // Create and destroy iframe every 3 seconds to prevent loading icon, super hacky - loadingFixIntervalId = window.setInterval(function () { - var tempFrame = createFrame(); - - window.document.body.appendChild(tempFrame); - window.document.body.removeChild(tempFrame); - - tempFrame = null; - }, loadingFixInterval); - } - - attachedTo++; - } - }, - cancel: function () { - // Only clear the interval if there's only one more object that the loadPreventer is attachedTo - if (attachedTo === 1) { - window.clearInterval(loadingFixIntervalId); - } - - if (attachedTo > 0) { - attachedTo--; - } - } - }; - })(); - - signalR.transports.foreverFrame = { - name: "foreverFrame", - - supportsKeepAlive: function () { - return true; - }, - - // Added as a value here so we can create tests to verify functionality - iframeClearThreshold: 50, - - start: function (connection, onSuccess, onFailed) { - var that = this, - frameId = (transportLogic.foreverFrame.count += 1), - url, - frame = createFrame(), - frameLoadHandler = function () { - connection.log("Forever frame iframe finished loading and is no longer receiving messages."); - if (!onFailed || !onFailed()) { - that.reconnect(connection); - } - }; - - if (window.EventSource) { - // If the browser supports SSE, don't use Forever Frame - if (onFailed) { - connection.log("Forever Frame is not supported by SignalR on browsers with SSE support."); - onFailed(); - } - return; - } - - frame.setAttribute("data-signalr-connection-id", connection.id); - - // Start preventing loading icon - // This will only perform work if the loadPreventer is not attached to another connection. - loadPreventer.prevent(); - - // Build the url - url = transportLogic.getUrl(connection, this.name); - url += "&frameId=" + frameId; - - // add frame to the document prior to setting URL to avoid caching issues. - window.document.documentElement.appendChild(frame); - - connection.log("Binding to iframe's load event."); - - if (frame.addEventListener) { - frame.addEventListener("load", frameLoadHandler, false); - } else if (frame.attachEvent) { - frame.attachEvent("onload", frameLoadHandler); - } - - frame.src = url; - transportLogic.foreverFrame.connections[frameId] = connection; - - connection.frame = frame; - connection.frameId = frameId; - - if (onSuccess) { - connection.onSuccess = function () { - connection.log("Iframe transport started."); - onSuccess(); - }; - } - }, - - reconnect: function (connection) { - var that = this; - - // Need to verify connection state and verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration. - if (transportLogic.isConnectedOrReconnecting(connection) && transportLogic.verifyLastActive(connection)) { - window.setTimeout(function () { - // Verify that we're ok to reconnect. - if (!transportLogic.verifyLastActive(connection)) { - return; - } - - if (connection.frame && transportLogic.ensureReconnectingState(connection)) { - var frame = connection.frame, - src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId; - connection.log("Updating iframe src to '" + src + "'."); - frame.src = src; - } - }, connection.reconnectDelay); - } - }, - - lostConnection: function (connection) { - this.reconnect(connection); - }, - - send: function (connection, data) { - transportLogic.ajaxSend(connection, data); - }, - - receive: function (connection, data) { - var cw, - body, - response; - - if (connection.json !== connection._originalJson) { - // If there's a custom JSON parser configured then serialize the object - // using the original (browser) JSON parser and then deserialize it using - // the custom parser (connection._parseResponse does that). This is so we - // can easily send the response from the server as "raw" JSON but still - // support custom JSON deserialization in the browser. - data = connection._originalJson.stringify(data); - } - - response = connection._parseResponse(data); - - transportLogic.processMessages(connection, response, connection.onSuccess); - - // Protect against connection stopping from a callback trigger within the processMessages above. - if (connection.state === $.signalR.connectionState.connected) { - // Delete the script & div elements - connection.frameMessageCount = (connection.frameMessageCount || 0) + 1; - if (connection.frameMessageCount > signalR.transports.foreverFrame.iframeClearThreshold) { - connection.frameMessageCount = 0; - cw = connection.frame.contentWindow || connection.frame.contentDocument; - if (cw && cw.document && cw.document.body) { - body = cw.document.body; - - // Remove all the child elements from the iframe's body to conserver memory - while (body.firstChild) { - body.removeChild(body.firstChild); - } - } - } - } - }, - - stop: function (connection) { - var cw = null; - - // Stop attempting to prevent loading icon - loadPreventer.cancel(); - - if (connection.frame) { - if (connection.frame.stop) { - connection.frame.stop(); - } else { - try { - cw = connection.frame.contentWindow || connection.frame.contentDocument; - if (cw.document && cw.document.execCommand) { - cw.document.execCommand("Stop"); - } - } - catch (e) { - connection.log("Error occured when stopping foreverFrame transport. Message = " + e.message + "."); - } - } - - // Ensure the iframe is where we left it - if (connection.frame.parentNode === window.document.body) { - window.document.body.removeChild(connection.frame); - } - - delete transportLogic.foreverFrame.connections[connection.frameId]; - connection.frame = null; - connection.frameId = null; - delete connection.frame; - delete connection.frameId; - delete connection.onSuccess; - delete connection.frameMessageCount; - connection.log("Stopping forever frame."); - } - }, - - abort: function (connection, async) { - transportLogic.ajaxAbort(connection, async); - }, - - getConnection: function (id) { - return transportLogic.foreverFrame.connections[id]; - }, - - started: function (connection) { - if (changeState(connection, - signalR.connectionState.reconnecting, - signalR.connectionState.connected) === true) { - - $(connection).triggerHandler(events.onReconnect); - } - } - }; - -}(window.jQuery, window)); -/* jquery.signalR.transports.longPolling.js */ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information. - -/*global window:false */ -/// <reference path="jquery.signalR.transports.common.js" /> - -(function ($, window, undefined) { - - var signalR = $.signalR, - events = $.signalR.events, - changeState = $.signalR.changeState, - isDisconnecting = $.signalR.isDisconnecting, - transportLogic = signalR.transports._logic; - - signalR.transports.longPolling = { - name: "longPolling", - - supportsKeepAlive: function () { - return false; - }, - - reconnectDelay: 3000, - - start: function (connection, onSuccess, onFailed) { - /// <summary>Starts the long polling connection</summary> - /// <param name="connection" type="signalR">The SignalR connection to start</param> - var that = this, - fireConnect = function () { - fireConnect = $.noop; - - connection.log("LongPolling connected."); - onSuccess(); - }, - tryFailConnect = function (error) { - if (onFailed(error)) { - connection.log("LongPolling failed to connect."); - return true; - } - - return false; - }, - privateData = connection._, - reconnectErrors = 0, - fireReconnected = function (instance) { - window.clearTimeout(privateData.reconnectTimeoutId); - privateData.reconnectTimeoutId = null; - - if (changeState(instance, - signalR.connectionState.reconnecting, - signalR.connectionState.connected) === true) { - // Successfully reconnected! - instance.log("Raising the reconnect event"); - $(instance).triggerHandler(events.onReconnect); - } - }, - // 1 hour - maxFireReconnectedTimeout = 3600000; - - if (connection.pollXhr) { - connection.log("Polling xhr requests already exists, aborting."); - connection.stop(); - } - - connection.messageId = null; - - privateData.reconnectTimeoutId = null; - - privateData.pollTimeoutId = window.setTimeout(function () { - (function poll(instance, raiseReconnect) { - var messageId = instance.messageId, - connect = (messageId === null), - reconnecting = !connect, - polling = !raiseReconnect, - url = transportLogic.getUrl(instance, that.name, reconnecting, polling, true /* use Post for longPolling */), - postData = {}; - - if (instance.messageId) { - postData.messageId = instance.messageId; - } - - if (instance.groupsToken) { - postData.groupsToken = instance.groupsToken; - } - - // If we've disconnected during the time we've tried to re-instantiate the poll then stop. - if (isDisconnecting(instance) === true) { - return; - } - - connection.log("Opening long polling request to '" + url + "'."); - instance.pollXhr = transportLogic.ajax(connection, { - xhrFields: { - onprogress: function () { - transportLogic.markLastMessage(connection); - } - }, - url: url, - type: "POST", - contentType: signalR._.defaultContentType, - data: postData, - timeout: connection._.pollTimeout, - success: function (result) { - var minData, - delay = 0, - data, - shouldReconnect; - - connection.log("Long poll complete."); - - // Reset our reconnect errors so if we transition into a reconnecting state again we trigger - // reconnected quickly - reconnectErrors = 0; - - try { - // Remove any keep-alives from the beginning of the result - minData = connection._parseResponse(result); - } - catch (error) { - transportLogic.handleParseFailure(instance, result, error, tryFailConnect, instance.pollXhr); - return; - } - - // If there's currently a timeout to trigger reconnect, fire it now before processing messages - if (privateData.reconnectTimeoutId !== null) { - fireReconnected(instance); - } - - if (minData) { - data = transportLogic.maximizePersistentResponse(minData); - } - - transportLogic.processMessages(instance, minData, fireConnect); - - if (data && - $.type(data.LongPollDelay) === "number") { - delay = data.LongPollDelay; - } - - if (isDisconnecting(instance) === true) { - return; - } - - shouldReconnect = data && data.ShouldReconnect; - if (shouldReconnect) { - // Transition into the reconnecting state - // If this fails then that means that the user transitioned the connection into a invalid state in processMessages. - if (!transportLogic.ensureReconnectingState(instance)) { - return; - } - } - - // We never want to pass a raiseReconnect flag after a successful poll. This is handled via the error function - if (delay > 0) { - privateData.pollTimeoutId = window.setTimeout(function () { - poll(instance, shouldReconnect); - }, delay); - } else { - poll(instance, shouldReconnect); - } - }, - - error: function (data, textStatus) { - var error = signalR._.transportError(signalR.resources.longPollFailed, connection.transport, data, instance.pollXhr); - - // Stop trying to trigger reconnect, connection is in an error state - // If we're not in the reconnect state this will noop - window.clearTimeout(privateData.reconnectTimeoutId); - privateData.reconnectTimeoutId = null; - - if (textStatus === "abort") { - connection.log("Aborted xhr request."); - return; - } - - if (!tryFailConnect(error)) { - - // Increment our reconnect errors, we assume all errors to be reconnect errors - // In the case that it's our first error this will cause Reconnect to be fired - // after 1 second due to reconnectErrors being = 1. - reconnectErrors++; - - if (connection.state !== signalR.connectionState.reconnecting) { - connection.log("An error occurred using longPolling. Status = " + textStatus + ". Response = " + data.responseText + "."); - $(instance).triggerHandler(events.onError, [error]); - } - - // We check the state here to verify that we're not in an invalid state prior to verifying Reconnect. - // If we're not in connected or reconnecting then the next ensureReconnectingState check will fail and will return. - // Therefore we don't want to change that failure code path. - if ((connection.state === signalR.connectionState.connected || - connection.state === signalR.connectionState.reconnecting) && - !transportLogic.verifyLastActive(connection)) { - return; - } - - // Transition into the reconnecting state - // If this fails then that means that the user transitioned the connection into the disconnected or connecting state within the above error handler trigger. - if (!transportLogic.ensureReconnectingState(instance)) { - return; - } - - // Call poll with the raiseReconnect flag as true after the reconnect delay - privateData.pollTimeoutId = window.setTimeout(function () { - poll(instance, true); - }, that.reconnectDelay); - } - } - }); - - // This will only ever pass after an error has occured via the poll ajax procedure. - if (reconnecting && raiseReconnect === true) { - // We wait to reconnect depending on how many times we've failed to reconnect. - // This is essentially a heuristic that will exponentially increase in wait time before - // triggering reconnected. This depends on the "error" handler of Poll to cancel this - // timeout if it triggers before the Reconnected event fires. - // The Math.min at the end is to ensure that the reconnect timeout does not overflow. - privateData.reconnectTimeoutId = window.setTimeout(function () { fireReconnected(instance); }, Math.min(1000 * (Math.pow(2, reconnectErrors) - 1), maxFireReconnectedTimeout)); - } - }(connection)); - }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab - }, - - lostConnection: function (connection) { - if (connection.pollXhr) { - connection.pollXhr.abort("lostConnection"); - } - }, - - send: function (connection, data) { - transportLogic.ajaxSend(connection, data); - }, - - stop: function (connection) { - /// <summary>Stops the long polling connection</summary> - /// <param name="connection" type="signalR">The SignalR connection to stop</param> - - window.clearTimeout(connection._.pollTimeoutId); - window.clearTimeout(connection._.reconnectTimeoutId); - - delete connection._.pollTimeoutId; - delete connection._.reconnectTimeoutId; - - if (connection.pollXhr) { - connection.pollXhr.abort(); - connection.pollXhr = null; - delete connection.pollXhr; - } - }, - - abort: function (connection, async) { - transportLogic.ajaxAbort(connection, async); - } - }; - -}(window.jQuery, window)); -/* jquery.signalR.hubs.js */ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information. - -/*global window:false */ -/// <reference path="jquery.signalR.core.js" /> - -(function ($, window, undefined) { - - var eventNamespace = ".hubProxy", - signalR = $.signalR; - - function makeEventName(event) { - return event + eventNamespace; - } - - // Equivalent to Array.prototype.map - function map(arr, fun, thisp) { - var i, - length = arr.length, - result = []; - for (i = 0; i < length; i += 1) { - if (arr.hasOwnProperty(i)) { - result[i] = fun.call(thisp, arr[i], i, arr); - } - } - return result; - } - - function getArgValue(a) { - return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a); - } - - function hasMembers(obj) { - for (var key in obj) { - // If we have any properties in our callback map then we have callbacks and can exit the loop via return - if (obj.hasOwnProperty(key)) { - return true; - } - } - - return false; - } - - function clearInvocationCallbacks(connection, error) { - /// <param name="connection" type="hubConnection" /> - var callbacks = connection._.invocationCallbacks, - callback; - - if (hasMembers(callbacks)) { - connection.log("Clearing hub invocation callbacks with error: " + error + "."); - } - - // Reset the callback cache now as we have a local var referencing it - connection._.invocationCallbackId = 0; - delete connection._.invocationCallbacks; - connection._.invocationCallbacks = {}; - - // Loop over the callbacks and invoke them. - // We do this using a local var reference and *after* we've cleared the cache - // so that if a fail callback itself tries to invoke another method we don't - // end up with its callback in the list we're looping over. - for (var callbackId in callbacks) { - callback = callbacks[callbackId]; - callback.method.call(callback.scope, { E: error }); - } - } - - // hubProxy - function hubProxy(hubConnection, hubName) { - /// <summary> - /// Creates a new proxy object for the given hub connection that can be used to invoke - /// methods on server hubs and handle client method invocation requests from the server. - /// </summary> - return new hubProxy.fn.init(hubConnection, hubName); - } - - hubProxy.fn = hubProxy.prototype = { - init: function (connection, hubName) { - this.state = {}; - this.connection = connection; - this.hubName = hubName; - this._ = { - callbackMap: {} - }; - }, - - constructor: hubProxy, - - hasSubscriptions: function () { - return hasMembers(this._.callbackMap); - }, - - on: function (eventName, callback) { - /// <summary>Wires up a callback to be invoked when a invocation request is received from the server hub.</summary> - /// <param name="eventName" type="String">The name of the hub event to register the callback for.</param> - /// <param name="callback" type="Function">The callback to be invoked.</param> - var that = this, - callbackMap = that._.callbackMap; - - // Normalize the event name to lowercase - eventName = eventName.toLowerCase(); - - // If there is not an event registered for this callback yet we want to create its event space in the callback map. - if (!callbackMap[eventName]) { - callbackMap[eventName] = {}; - } - - // Map the callback to our encompassed function - callbackMap[eventName][callback] = function (e, data) { - callback.apply(that, data); - }; - - $(that).bind(makeEventName(eventName), callbackMap[eventName][callback]); - - return that; - }, - - off: function (eventName, callback) { - /// <summary>Removes the callback invocation request from the server hub for the given event name.</summary> - /// <param name="eventName" type="String">The name of the hub event to unregister the callback for.</param> - /// <param name="callback" type="Function">The callback to be invoked.</param> - var that = this, - callbackMap = that._.callbackMap, - callbackSpace; - - // Normalize the event name to lowercase - eventName = eventName.toLowerCase(); - - callbackSpace = callbackMap[eventName]; - - // Verify that there is an event space to unbind - if (callbackSpace) { - // Only unbind if there's an event bound with eventName and a callback with the specified callback - if (callbackSpace[callback]) { - $(that).unbind(makeEventName(eventName), callbackSpace[callback]); - - // Remove the callback from the callback map - delete callbackSpace[callback]; - - // Check if there are any members left on the event, if not we need to destroy it. - if (!hasMembers(callbackSpace)) { - delete callbackMap[eventName]; - } - } else if (!callback) { // Check if we're removing the whole event and we didn't error because of an invalid callback - $(that).unbind(makeEventName(eventName)); - - delete callbackMap[eventName]; - } - } - - return that; - }, - - invoke: function (methodName) { - /// <summary>Invokes a server hub method with the given arguments.</summary> - /// <param name="methodName" type="String">The name of the server hub method.</param> - - var that = this, - connection = that.connection, - args = $.makeArray(arguments).slice(1), - argValues = map(args, getArgValue), - data = { H: that.hubName, M: methodName, A: argValues, I: connection._.invocationCallbackId }, - d = $.Deferred(), - callback = function (minResult) { - var result = that._maximizeHubResponse(minResult), - source, - error; - - // Update the hub state - $.extend(that.state, result.State); - - if (result.Progress) { - if (d.notifyWith) { - // Progress is only supported in jQuery 1.7+ - d.notifyWith(that, [result.Progress.Data]); - } else if(!connection._.progressjQueryVersionLogged) { - connection.log("A hub method invocation progress update was received but the version of jQuery in use (" + $.prototype.jquery + ") does not support progress updates. Upgrade to jQuery 1.7+ to receive progress notifications."); - connection._.progressjQueryVersionLogged = true; - } - } else if (result.Error) { - // Server hub method threw an exception, log it & reject the deferred - if (result.StackTrace) { - connection.log(result.Error + "\n" + result.StackTrace + "."); - } - - // result.ErrorData is only set if a HubException was thrown - source = result.IsHubException ? "HubException" : "Exception"; - error = signalR._.error(result.Error, source); - error.data = result.ErrorData; - - connection.log(that.hubName + "." + methodName + " failed to execute. Error: " + error.message); - d.rejectWith(that, [error]); - } else { - // Server invocation succeeded, resolve the deferred - connection.log("Invoked " + that.hubName + "." + methodName); - d.resolveWith(that, [result.Result]); - } - }; - - connection._.invocationCallbacks[connection._.invocationCallbackId.toString()] = { scope: that, method: callback }; - connection._.invocationCallbackId += 1; - - if (!$.isEmptyObject(that.state)) { - data.S = that.state; - } - - connection.log("Invoking " + that.hubName + "." + methodName); - connection.send(data); - - return d.promise(); - }, - - _maximizeHubResponse: function (minHubResponse) { - return { - State: minHubResponse.S, - Result: minHubResponse.R, - Progress: minHubResponse.P ? { - Id: minHubResponse.P.I, - Data: minHubResponse.P.D - } : null, - Id: minHubResponse.I, - IsHubException: minHubResponse.H, - Error: minHubResponse.E, - StackTrace: minHubResponse.T, - ErrorData: minHubResponse.D - }; - } - }; - - hubProxy.fn.init.prototype = hubProxy.fn; - - // hubConnection - function hubConnection(url, options) { - /// <summary>Creates a new hub connection.</summary> - /// <param name="url" type="String">[Optional] The hub route url, defaults to "/signalr".</param> - /// <param name="options" type="Object">[Optional] Settings to use when creating the hubConnection.</param> - var settings = { - qs: null, - logging: false, - useDefaultPath: true - }; - - $.extend(settings, options); - - if (!url || settings.useDefaultPath) { - url = (url || "") + "/signalr"; - } - return new hubConnection.fn.init(url, settings); - } - - hubConnection.fn = hubConnection.prototype = $.connection(); - - hubConnection.fn.init = function (url, options) { - var settings = { - qs: null, - logging: false, - useDefaultPath: true - }, - connection = this; - - $.extend(settings, options); - - // Call the base constructor - $.signalR.fn.init.call(connection, url, settings.qs, settings.logging); - - // Object to store hub proxies for this connection - connection.proxies = {}; - - connection._.invocationCallbackId = 0; - connection._.invocationCallbacks = {}; - - // Wire up the received handler - connection.received(function (minData) { - var data, proxy, dataCallbackId, callback, hubName, eventName; - if (!minData) { - return; - } - - // We have to handle progress updates first in order to ensure old clients that receive - // progress updates enter the return value branch and then no-op when they can't find - // the callback in the map (because the minData.I value will not be a valid callback ID) - if (typeof (minData.P) !== "undefined") { - // Process progress notification - dataCallbackId = minData.P.I.toString(); - callback = connection._.invocationCallbacks[dataCallbackId]; - if (callback) { - callback.method.call(callback.scope, minData); - } - } else if (typeof (minData.I) !== "undefined") { - // We received the return value from a server method invocation, look up callback by id and call it - dataCallbackId = minData.I.toString(); - callback = connection._.invocationCallbacks[dataCallbackId]; - if (callback) { - // Delete the callback from the proxy - connection._.invocationCallbacks[dataCallbackId] = null; - delete connection._.invocationCallbacks[dataCallbackId]; - - // Invoke the callback - callback.method.call(callback.scope, minData); - } - } else { - data = this._maximizeClientHubInvocation(minData); - - // We received a client invocation request, i.e. broadcast from server hub - connection.log("Triggering client hub event '" + data.Method + "' on hub '" + data.Hub + "'."); - - // Normalize the names to lowercase - hubName = data.Hub.toLowerCase(); - eventName = data.Method.toLowerCase(); - - // Trigger the local invocation event - proxy = this.proxies[hubName]; - - // Update the hub state - $.extend(proxy.state, data.State); - $(proxy).triggerHandler(makeEventName(eventName), [data.Args]); - } - }); - - connection.error(function (errData, origData) { - var callbackId, callback; - - if (!origData) { - // No original data passed so this is not a send error - return; - } - - callbackId = origData.I; - callback = connection._.invocationCallbacks[callbackId]; - - // Verify that there is a callback bound (could have been cleared) - if (callback) { - // Delete the callback - connection._.invocationCallbacks[callbackId] = null; - delete connection._.invocationCallbacks[callbackId]; - - // Invoke the callback with an error to reject the promise - callback.method.call(callback.scope, { E: errData }); - } - }); - - connection.reconnecting(function () { - if (connection.transport && connection.transport.name === "webSockets") { - clearInvocationCallbacks(connection, "Connection started reconnecting before invocation result was received."); - } - }); - - connection.disconnected(function () { - clearInvocationCallbacks(connection, "Connection was disconnected before invocation result was received."); - }); - }; - - hubConnection.fn._maximizeClientHubInvocation = function (minClientHubInvocation) { - return { - Hub: minClientHubInvocation.H, - Method: minClientHubInvocation.M, - Args: minClientHubInvocation.A, - State: minClientHubInvocation.S - }; - }; - - hubConnection.fn._registerSubscribedHubs = function () { - /// <summary> - /// Sets the starting event to loop through the known hubs and register any new hubs - /// that have been added to the proxy. - /// </summary> - var connection = this; - - if (!connection._subscribedToHubs) { - connection._subscribedToHubs = true; - connection.starting(function () { - // Set the connection's data object with all the hub proxies with active subscriptions. - // These proxies will receive notifications from the server. - var subscribedHubs = []; - - $.each(connection.proxies, function (key) { - if (this.hasSubscriptions()) { - subscribedHubs.push({ name: key }); - connection.log("Client subscribed to hub '" + key + "'."); - } - }); - - if (subscribedHubs.length === 0) { - connection.log("No hubs have been subscribed to. The client will not receive data from hubs. To fix, declare at least one client side function prior to connection start for each hub you wish to subscribe to."); - } - - connection.data = connection.json.stringify(subscribedHubs); - }); - } - }; - - hubConnection.fn.createHubProxy = function (hubName) { - /// <summary> - /// Creates a new proxy object for the given hub connection that can be used to invoke - /// methods on server hubs and handle client method invocation requests from the server. - /// </summary> - /// <param name="hubName" type="String"> - /// The name of the hub on the server to create the proxy for. - /// </param> - - // Normalize the name to lowercase - hubName = hubName.toLowerCase(); - - var proxy = this.proxies[hubName]; - if (!proxy) { - proxy = hubProxy(this, hubName); - this.proxies[hubName] = proxy; - } - - this._registerSubscribedHubs(); - - return proxy; - }; - - hubConnection.fn.init.prototype = hubConnection.fn; - - $.hubConnection = hubConnection; - -}(window.jQuery, window)); -/* jquery.signalR.version.js */ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information. - -/*global window:false */ -/// <reference path="jquery.signalR.core.js" /> -(function ($, undefined) { - $.signalR.version = "2.2.0"; -}(window.jQuery)); diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.min.js b/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.min.js deleted file mode 100644 index 70bbc0b045e0f4d63e779a0d120db99d9d59c51e..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Scripts/jquery.signalR-2.2.0.min.js +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * ASP.NET SignalR JavaScript Library v2.2.0 - * http://signalr.net/ - * - * Copyright (C) Microsoft Corporation. All rights reserved. - * - */ -(function(n,t,i){function w(t,i){var u,f;if(n.isArray(t)){for(u=t.length-1;u>=0;u--)f=t[u],n.type(f)==="string"&&r.transports[f]||(i.log("Invalid transport: "+f+", removing it from the transports list."),t.splice(u,1));t.length===0&&(i.log("No transports remain within the specified transport array."),t=null)}else if(r.transports[t]||t==="auto"){if(t==="auto"&&r._.ieVersion<=8)return["longPolling"]}else i.log("Invalid transport: "+t.toString()+"."),t=null;return t}function b(n){return n==="http:"?80:n==="https:"?443:void 0}function a(n,t){return t.match(/:\d+$/)?t:t+":"+b(n)}function k(t,i){var u=this,r=[];u.tryBuffer=function(i){return t.state===n.signalR.connectionState.connecting?(r.push(i),!0):!1};u.drain=function(){if(t.state===n.signalR.connectionState.connected)while(r.length>0)i(r.shift())};u.clear=function(){r=[]}}var f={nojQuery:"jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file.",noTransportOnInit:"No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.",errorOnNegotiate:"Error during negotiation request.",stoppedWhileLoading:"The connection was stopped during page load.",stoppedWhileNegotiating:"The connection was stopped during the negotiate request.",errorParsingNegotiateResponse:"Error parsing negotiate response.",errorDuringStartRequest:"Error during start request. Stopping the connection.",stoppedDuringStartRequest:"The connection was stopped during the start request.",errorParsingStartResponse:"Error parsing start response: '{0}'. Stopping the connection.",invalidStartResponse:"Invalid start response: '{0}'. Stopping the connection.",protocolIncompatible:"You are using a version of the client that isn't compatible with the server. Client version {0}, server version {1}.",sendFailed:"Send failed.",parseFailed:"Failed at parsing response: {0}",longPollFailed:"Long polling request failed.",eventSourceFailedToConnect:"EventSource failed to connect.",eventSourceError:"Error raised by EventSource",webSocketClosed:"WebSocket closed.",pingServerFailedInvalidResponse:"Invalid ping response when pinging server: '{0}'.",pingServerFailed:"Failed to ping server.",pingServerFailedStatusCode:"Failed to ping server. Server responded with status code {0}, stopping the connection.",pingServerFailedParse:"Failed to parse ping server response, stopping the connection.",noConnectionTransport:"Connection is in an invalid state, there is no transport active.",webSocketsInvalidState:"The Web Socket transport is in an invalid state, transitioning into reconnecting.",reconnectTimeout:"Couldn't reconnect within the configured timeout of {0} ms, disconnecting.",reconnectWindowTimeout:"The client has been inactive since {0} and it has exceeded the inactivity timeout of {1} ms. Stopping the connection."};if(typeof n!="function")throw new Error(f.nojQuery);var r,h,s=t.document.readyState==="complete",e=n(t),c="__Negotiate Aborted__",u={onStart:"onStart",onStarting:"onStarting",onReceived:"onReceived",onError:"onError",onConnectionSlow:"onConnectionSlow",onReconnecting:"onReconnecting",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},v=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},o=function(t,i,r){return i===t.state?(t.state=r,n(t).triggerHandler(u.onStateChanged,[{oldState:i,newState:r}]),!0):!1},y=function(n){return n.state===r.connectionState.disconnected},l=function(n){return n._.keepAliveData.activated&&n.transport.supportsKeepAlive(n)},p=function(i){var f,e;i._.configuredStopReconnectingTimeout||(e=function(t){var i=r._.format(r.resources.reconnectTimeout,t.disconnectTimeout);t.log(i);n(t).triggerHandler(u.onError,[r._.error(i,"TimeoutException")]);t.stop(!1,!1)},i.reconnecting(function(){var n=this;n.state===r.connectionState.reconnecting&&(f=t.setTimeout(function(){e(n)},n.disconnectTimeout))}),i.stateChanged(function(n){n.oldState===r.connectionState.reconnecting&&t.clearTimeout(f)}),i._.configuredStopReconnectingTimeout=!0)};r=function(n,t,i){return new r.fn.init(n,t,i)};r._={defaultContentType:"application/x-www-form-urlencoded; charset=UTF-8",ieVersion:function(){var i,n;return t.navigator.appName==="Microsoft Internet Explorer"&&(n=/MSIE ([0-9]+\.[0-9]+)/.exec(t.navigator.userAgent),n&&(i=t.parseFloat(n[1]))),i}(),error:function(n,t,i){var r=new Error(n);return r.source=t,typeof i!="undefined"&&(r.context=i),r},transportError:function(n,t,r,u){var f=this.error(n,r,u);return f.transport=t?t.name:i,f},format:function(){for(var t=arguments[0],n=0;n<arguments.length-1;n++)t=t.replace("{"+n+"}",arguments[n+1]);return t},firefoxMajorVersion:function(n){var t=n.match(/Firefox\/(\d+)/);return!t||!t.length||t.length<2?0:parseInt(t[1],10)},configurePingInterval:function(i){var f=i._.config,e=function(t){n(i).triggerHandler(u.onError,[t])};f&&!i._.pingIntervalId&&f.pingInterval&&(i._.pingIntervalId=t.setInterval(function(){r.transports._logic.pingServer(i).fail(e)},f.pingInterval))}};r.events=u;r.resources=f;r.ajaxDefaults={processData:!0,timeout:null,async:!0,global:!1,cache:!1};r.changeState=o;r.isDisconnecting=y;r.connectionState={connecting:0,connected:1,reconnecting:2,disconnected:4};r.hub={start:function(){throw new Error("SignalR: Error loading hubs. Ensure your hubs reference is correct, e.g. <script src='/signalr/js'><\/script>.");}};e.load(function(){s=!0});r.fn=r.prototype={init:function(t,i,r){var f=n(this);this.url=t;this.qs=i;this.lastError=null;this._={keepAliveData:{},connectingMessageBuffer:new k(this,function(n){f.triggerHandler(u.onReceived,[n])}),lastMessageAt:(new Date).getTime(),lastActiveAt:(new Date).getTime(),beatInterval:5e3,beatHandle:null,totalTransportConnectTimeout:0};typeof r=="boolean"&&(this.logging=r)},_parseResponse:function(n){var t=this;return n?typeof n=="string"?t.json.parse(n):n:n},_originalJson:t.JSON,json:t.JSON,isCrossDomain:function(i,r){var u;return(i=n.trim(i),r=r||t.location,i.indexOf("http")!==0)?!1:(u=t.document.createElement("a"),u.href=i,u.protocol+a(u.protocol,u.host)!==r.protocol+a(r.protocol,r.host))},ajaxDataType:"text",contentType:"application/json; charset=UTF-8",logging:!1,state:r.connectionState.disconnected,clientProtocol:"1.5",reconnectDelay:2e3,transportConnectTimeout:0,disconnectTimeout:3e4,reconnectWindow:3e4,keepAliveWarnAt:2/3,start:function(i,h){var a=this,v={pingInterval:3e5,waitForPageLoad:!0,transport:"auto",jsonp:!1},d,y=a._deferral||n.Deferred(),b=t.document.createElement("a"),k,g;if(a.lastError=null,a._deferral=y,!a.json)throw new Error("SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.");if(n.type(i)==="function"?h=i:n.type(i)==="object"&&(n.extend(v,i),n.type(v.callback)==="function"&&(h=v.callback)),v.transport=w(v.transport,a),!v.transport)throw new Error("SignalR: Invalid transport(s) specified, aborting start.");return(a._.config=v,!s&&v.waitForPageLoad===!0)?(a._.deferredStartHandler=function(){a.start(i,h)},e.bind("load",a._.deferredStartHandler),y.promise()):a.state===r.connectionState.connecting?y.promise():o(a,r.connectionState.disconnected,r.connectionState.connecting)===!1?(y.resolve(a),y.promise()):(p(a),b.href=a.url,b.protocol&&b.protocol!==":"?(a.protocol=b.protocol,a.host=b.host):(a.protocol=t.document.location.protocol,a.host=b.host||t.document.location.host),a.baseUrl=a.protocol+"//"+a.host,a.wsProtocol=a.protocol==="https:"?"wss://":"ws://",v.transport==="auto"&&v.jsonp===!0&&(v.transport="longPolling"),a.url.indexOf("//")===0&&(a.url=t.location.protocol+a.url,a.log("Protocol relative URL detected, normalizing it to '"+a.url+"'.")),this.isCrossDomain(a.url)&&(a.log("Auto detected cross domain url."),v.transport==="auto"&&(v.transport=["webSockets","serverSentEvents","longPolling"]),typeof v.withCredentials=="undefined"&&(v.withCredentials=!0),v.jsonp||(v.jsonp=!n.support.cors,v.jsonp&&a.log("Using jsonp because this browser doesn't support CORS.")),a.contentType=r._.defaultContentType),a.withCredentials=v.withCredentials,a.ajaxDataType=v.jsonp?"jsonp":"text",n(a).bind(u.onStart,function(){n.type(h)==="function"&&h.call(a);y.resolve(a)}),a._.initHandler=r.transports._logic.initHandler(a),d=function(i,s){var c=r._.error(f.noTransportOnInit);if(s=s||0,s>=i.length){s===0?a.log("No transports supported by the server were selected."):s===1?a.log("No fallback transports were selected."):a.log("Fallback transports exhausted.");n(a).triggerHandler(u.onError,[c]);y.reject(c);a.stop();return}if(a.state!==r.connectionState.disconnected){var p=i[s],h=r.transports[p],v=function(){d(i,s+1)};a.transport=h;try{a._.initHandler.start(h,function(){var i=r._.firefoxMajorVersion(t.navigator.userAgent)>=11,f=!!a.withCredentials&&i;a.log("The start request succeeded. Transitioning to the connected state.");l(a)&&r.transports._logic.monitorKeepAlive(a);r.transports._logic.startHeartbeat(a);r._.configurePingInterval(a);o(a,r.connectionState.connecting,r.connectionState.connected)||a.log("WARNING! The connection was not in the connecting state.");a._.connectingMessageBuffer.drain();n(a).triggerHandler(u.onStart);e.bind("unload",function(){a.log("Window unloading, stopping the connection.");a.stop(f)});i&&e.bind("beforeunload",function(){t.setTimeout(function(){a.stop(f)},0)})},v)}catch(w){a.log(h.name+" transport threw '"+w.message+"' when attempting to start.");v()}}},k=a.url+"/negotiate",g=function(t,i){var e=r._.error(f.errorOnNegotiate,t,i._.negotiateRequest);n(i).triggerHandler(u.onError,e);y.reject(e);i.stop()},n(a).triggerHandler(u.onStarting),k=r.transports._logic.prepareQueryString(a,k),a.log("Negotiating with '"+k+"'."),a._.negotiateRequest=r.transports._logic.ajax(a,{url:k,error:function(n,t){t!==c?g(n,a):y.reject(r._.error(f.stoppedWhileNegotiating,null,a._.negotiateRequest))},success:function(t){var i,e,h,o=[],s=[];try{i=a._parseResponse(t)}catch(c){g(r._.error(f.errorParsingNegotiateResponse,c),a);return}if(e=a._.keepAliveData,a.appRelativeUrl=i.Url,a.id=i.ConnectionId,a.token=i.ConnectionToken,a.webSocketServerUrl=i.WebSocketServerUrl,a._.pollTimeout=i.ConnectionTimeout*1e3+1e4,a.disconnectTimeout=i.DisconnectTimeout*1e3,a._.totalTransportConnectTimeout=a.transportConnectTimeout+i.TransportConnectTimeout*1e3,i.KeepAliveTimeout?(e.activated=!0,e.timeout=i.KeepAliveTimeout*1e3,e.timeoutWarning=e.timeout*a.keepAliveWarnAt,a._.beatInterval=(e.timeout-e.timeoutWarning)/3):e.activated=!1,a.reconnectWindow=a.disconnectTimeout+(e.timeout||0),!i.ProtocolVersion||i.ProtocolVersion!==a.clientProtocol){h=r._.error(r._.format(f.protocolIncompatible,a.clientProtocol,i.ProtocolVersion));n(a).triggerHandler(u.onError,[h]);y.reject(h);return}n.each(r.transports,function(n){if(n.indexOf("_")===0||n==="webSockets"&&!i.TryWebSockets)return!0;s.push(n)});n.isArray(v.transport)?n.each(v.transport,function(t,i){n.inArray(i,s)>=0&&o.push(i)}):v.transport==="auto"?o=s:n.inArray(v.transport,s)>=0&&o.push(v.transport);d(o)}}),y.promise())},starting:function(t){var i=this;return n(i).bind(u.onStarting,function(){t.call(i)}),i},send:function(n){var t=this;if(t.state===r.connectionState.disconnected)throw new Error("SignalR: Connection must be started before data can be sent. Call .start() before .send()");if(t.state===r.connectionState.connecting)throw new Error("SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.");return t.transport.send(t,n),t},received:function(t){var i=this;return n(i).bind(u.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(u.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(u.onError,function(n,r,u){i.lastError=r;t.call(i,r,u)}),i},disconnected:function(t){var i=this;return n(i).bind(u.onDisconnect,function(){t.call(i)}),i},connectionSlow:function(t){var i=this;return n(i).bind(u.onConnectionSlow,function(){t.call(i)}),i},reconnecting:function(t){var i=this;return n(i).bind(u.onReconnecting,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(u.onReconnect,function(){t.call(i)}),i},stop:function(i,h){var a=this,v=a._deferral;if(a._.deferredStartHandler&&e.unbind("load",a._.deferredStartHandler),delete a._.config,delete a._.deferredStartHandler,!s&&(!a._.config||a._.config.waitForPageLoad===!0)){a.log("Stopping connection prior to negotiate.");v&&v.reject(r._.error(f.stoppedWhileLoading));return}if(a.state!==r.connectionState.disconnected)return a.log("Stopping connection."),o(a,a.state,r.connectionState.disconnected),t.clearTimeout(a._.beatHandle),t.clearInterval(a._.pingIntervalId),a.transport&&(a.transport.stop(a),h!==!1&&a.transport.abort(a,i),l(a)&&r.transports._logic.stopMonitoringKeepAlive(a),a.transport=null),a._.negotiateRequest&&(a._.negotiateRequest.abort(c),delete a._.negotiateRequest),a._.initHandler&&a._.initHandler.stop(),n(a).triggerHandler(u.onDisconnect),delete a._deferral,delete a.messageId,delete a.groupsToken,delete a.id,delete a._.pingIntervalId,delete a._.lastMessageAt,delete a._.lastActiveAt,a._.connectingMessageBuffer.clear(),a},log:function(n){v(n,this.logging)}};r.fn.init.prototype=r.fn;r.noConflict=function(){return n.connection===r&&(n.connection=h),r};n.connection&&(h=n.connection);n.connection=n.signalR=r})(window.jQuery,window),function(n,t,i){function s(n){n._.keepAliveData.monitoring&&l(n);u.markActive(n)&&(n._.beatHandle=t.setTimeout(function(){s(n)},n._.beatInterval))}function l(t){var i=t._.keepAliveData,u;t.state===r.connectionState.connected&&(u=(new Date).getTime()-t._.lastMessageAt,u>=i.timeout?(t.log("Keep alive timed out. Notifying transport that connection has been lost."),t.transport.lostConnection(t)):u>=i.timeoutWarning?i.userNotified||(t.log("Keep alive has been missed, connection may be dead/slow."),n(t).triggerHandler(f.onConnectionSlow),i.userNotified=!0):i.userNotified=!1)}function e(n,t){var i=n.url+t;return n.transport&&(i+="?transport="+n.transport.name),u.prepareQueryString(n,i)}function h(n){this.connection=n;this.startRequested=!1;this.startCompleted=!1;this.connectionStopped=!1}var r=n.signalR,f=n.signalR.events,c=n.signalR.changeState,o="__Start Aborted__",u;r.transports={};h.prototype={start:function(n,r,u){var f=this,e=f.connection,o=!1;if(f.startRequested||f.connectionStopped){e.log("WARNING! "+n.name+" transport cannot be started. Initialization ongoing or completed.");return}e.log(n.name+" transport starting.");f.transportTimeoutHandle=t.setTimeout(function(){o||(o=!0,e.log(n.name+" transport timed out when trying to connect."),f.transportFailed(n,i,u))},e._.totalTransportConnectTimeout);n.start(e,function(){o||f.initReceived(n,r)},function(t){return o||(o=!0,f.transportFailed(n,t,u)),!f.startCompleted||f.connectionStopped})},stop:function(){this.connectionStopped=!0;t.clearTimeout(this.transportTimeoutHandle);r.transports._logic.tryAbortStartRequest(this.connection)},initReceived:function(n,i){var u=this,f=u.connection;if(u.startRequested){f.log("WARNING! The client received multiple init messages.");return}u.connectionStopped||(u.startRequested=!0,t.clearTimeout(u.transportTimeoutHandle),f.log(n.name+" transport connected. Initiating start request."),r.transports._logic.ajaxStart(f,function(){u.startCompleted=!0;i()}))},transportFailed:function(i,u,e){var o=this.connection,h=o._deferral,s;this.connectionStopped||(t.clearTimeout(this.transportTimeoutHandle),this.startRequested?this.startCompleted||(s=r._.error(r.resources.errorDuringStartRequest,u),o.log(i.name+" transport failed during the start request. Stopping the connection."),n(o).triggerHandler(f.onError,[s]),h&&h.reject(s),o.stop()):(i.stop(o),o.log(i.name+" transport failed to connect. Attempting to fall back."),e()))}};u=r.transports._logic={ajax:function(t,i){return n.ajax(n.extend(!0,{},n.signalR.ajaxDefaults,{type:"GET",data:{},xhrFields:{withCredentials:t.withCredentials},contentType:t.contentType,dataType:t.ajaxDataType},i))},pingServer:function(t){var e,f,i=n.Deferred();return t.transport?(e=t.url+"/ping",e=u.addQs(e,t.qs),f=u.ajax(t,{url:e,success:function(n){var u;try{u=t._parseResponse(n)}catch(e){i.reject(r._.transportError(r.resources.pingServerFailedParse,t.transport,e,f));t.stop();return}u.Response==="pong"?i.resolve():i.reject(r._.transportError(r._.format(r.resources.pingServerFailedInvalidResponse,n),t.transport,null,f))},error:function(n){n.status===401||n.status===403?(i.reject(r._.transportError(r._.format(r.resources.pingServerFailedStatusCode,n.status),t.transport,n,f)),t.stop()):i.reject(r._.transportError(r.resources.pingServerFailed,t.transport,n,f))}})):i.reject(r._.transportError(r.resources.noConnectionTransport,t.transport)),i.promise()},prepareQueryString:function(n,i){var r;return r=u.addQs(i,"clientProtocol="+n.clientProtocol),r=u.addQs(r,n.qs),n.token&&(r+="&connectionToken="+t.encodeURIComponent(n.token)),n.data&&(r+="&connectionData="+t.encodeURIComponent(n.data)),r},addQs:function(t,i){var r=t.indexOf("?")!==-1?"&":"?",u;if(!i)return t;if(typeof i=="object")return t+r+n.param(i);if(typeof i=="string")return u=i.charAt(0),(u==="?"||u==="&")&&(r=""),t+r+i;throw new Error("Query string property must be either a string or object.");},getUrl:function(n,i,r,f,e){var h=i==="webSockets"?"":n.baseUrl,o=h+n.appRelativeUrl,s="transport="+i;return!e&&n.groupsToken&&(s+="&groupsToken="+t.encodeURIComponent(n.groupsToken)),r?(o+=f?"/poll":"/reconnect",!e&&n.messageId&&(s+="&messageId="+t.encodeURIComponent(n.messageId))):o+="/connect",o+="?"+s,o=u.prepareQueryString(n,o),e||(o+="&tid="+Math.floor(Math.random()*11)),o},maximizePersistentResponse:function(n){return{MessageId:n.C,Messages:n.M,Initialized:typeof n.S!="undefined"?!0:!1,ShouldReconnect:typeof n.T!="undefined"?!0:!1,LongPollDelay:n.L,GroupsToken:n.G}},updateGroups:function(n,t){t&&(n.groupsToken=t)},stringifySend:function(n,t){return typeof t=="string"||typeof t=="undefined"||t===null?t:n.json.stringify(t)},ajaxSend:function(t,i){var h=u.stringifySend(t,i),c=e(t,"/send"),o,s=function(t,u){n(u).triggerHandler(f.onError,[r._.transportError(r.resources.sendFailed,u.transport,t,o),i])};return o=u.ajax(t,{url:c,type:t.ajaxDataType==="jsonp"?"GET":"POST",contentType:r._.defaultContentType,data:{data:h},success:function(n){var i;if(n){try{i=t._parseResponse(n)}catch(r){s(r,t);t.stop();return}u.triggerReceived(t,i)}},error:function(n,i){i!=="abort"&&i!=="parsererror"&&s(n,t)}})},ajaxAbort:function(n,t){if(typeof n.transport!="undefined"){t=typeof t=="undefined"?!0:t;var i=e(n,"/abort");u.ajax(n,{url:i,async:t,timeout:1e3,type:"POST"});n.log("Fired ajax abort async = "+t+".")}},ajaxStart:function(t,i){var h=function(n){var i=t._deferral;i&&i.reject(n)},s=function(i){t.log("The start request failed. Stopping the connection.");n(t).triggerHandler(f.onError,[i]);h(i);t.stop()};t._.startRequest=u.ajax(t,{url:e(t,"/start"),success:function(n,u,f){var e;try{e=t._parseResponse(n)}catch(o){s(r._.error(r._.format(r.resources.errorParsingStartResponse,n),o,f));return}e.Response==="started"?i():s(r._.error(r._.format(r.resources.invalidStartResponse,n),null,f))},error:function(n,i,u){i!==o?s(r._.error(r.resources.errorDuringStartRequest,u,n)):(t.log("The start request aborted because connection.stop() was called."),h(r._.error(r.resources.stoppedDuringStartRequest,null,n)))}})},tryAbortStartRequest:function(n){n._.startRequest&&(n._.startRequest.abort(o),delete n._.startRequest)},tryInitialize:function(n,t){n.Initialized&&t()},triggerReceived:function(t,i){t._.connectingMessageBuffer.tryBuffer(i)||n(t).triggerHandler(f.onReceived,[i])},processMessages:function(t,i,r){var f;u.markLastMessage(t);i&&(f=u.maximizePersistentResponse(i),u.updateGroups(t,f.GroupsToken),f.MessageId&&(t.messageId=f.MessageId),f.Messages&&(n.each(f.Messages,function(n,i){u.triggerReceived(t,i)}),u.tryInitialize(f,r)))},monitorKeepAlive:function(t){var i=t._.keepAliveData;i.monitoring?t.log("Tried to monitor keep alive but it's already being monitored."):(i.monitoring=!0,u.markLastMessage(t),t._.keepAliveData.reconnectKeepAliveUpdate=function(){u.markLastMessage(t)},n(t).bind(f.onReconnect,t._.keepAliveData.reconnectKeepAliveUpdate),t.log("Now monitoring keep alive with a warning timeout of "+i.timeoutWarning+", keep alive timeout of "+i.timeout+" and disconnecting timeout of "+t.disconnectTimeout))},stopMonitoringKeepAlive:function(t){var i=t._.keepAliveData;i.monitoring&&(i.monitoring=!1,n(t).unbind(f.onReconnect,t._.keepAliveData.reconnectKeepAliveUpdate),t._.keepAliveData={},t.log("Stopping the monitoring of the keep alive."))},startHeartbeat:function(n){n._.lastActiveAt=(new Date).getTime();s(n)},markLastMessage:function(n){n._.lastMessageAt=(new Date).getTime()},markActive:function(n){return u.verifyLastActive(n)?(n._.lastActiveAt=(new Date).getTime(),!0):!1},isConnectedOrReconnecting:function(n){return n.state===r.connectionState.connected||n.state===r.connectionState.reconnecting},ensureReconnectingState:function(t){return c(t,r.connectionState.connected,r.connectionState.reconnecting)===!0&&n(t).triggerHandler(f.onReconnecting),t.state===r.connectionState.reconnecting},clearReconnectTimeout:function(n){n&&n._.reconnectTimeout&&(t.clearTimeout(n._.reconnectTimeout),delete n._.reconnectTimeout)},verifyLastActive:function(t){if((new Date).getTime()-t._.lastActiveAt>=t.reconnectWindow){var i=r._.format(r.resources.reconnectWindowTimeout,new Date(t._.lastActiveAt),t.reconnectWindow);return t.log(i),n(t).triggerHandler(f.onError,[r._.error(i,"TimeoutException")]),t.stop(!1,!1),!1}return!0},reconnect:function(n,i){var f=r.transports[i];if(u.isConnectedOrReconnecting(n)&&!n._.reconnectTimeout){if(!u.verifyLastActive(n))return;n._.reconnectTimeout=t.setTimeout(function(){u.verifyLastActive(n)&&(f.stop(n),u.ensureReconnectingState(n)&&(n.log(i+" reconnecting."),f.start(n)))},n.reconnectDelay)}},handleParseFailure:function(t,i,u,e,o){var s=r._.transportError(r._.format(r.resources.parseFailed,i),t.transport,u,o);e&&e(s)?t.log("Failed to parse server response while attempting to connect."):(n(t).triggerHandler(f.onError,[s]),t.stop())},initHandler:function(n){return new h(n)},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.webSockets={name:"webSockets",supportsKeepAlive:function(){return!0},send:function(t,f){var e=i.stringifySend(t,f);try{t.socket.send(e)}catch(o){n(t).triggerHandler(u.onError,[r._.transportError(r.resources.webSocketsInvalidState,t.transport,o,t.socket),f])}},start:function(e,o,s){var h,c=!1,l=this,a=!o,v=n(e);if(!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,h+=i.getUrl(e,this.name,a),e.log("Connecting to websocket endpoint '"+h+"'."),e.socket=new t.WebSocket(h),e.socket.onopen=function(){c=!0;e.log("Websocket opened.");i.clearReconnectTimeout(e);f(e,r.connectionState.reconnecting,r.connectionState.connected)===!0&&v.triggerHandler(u.onReconnect)},e.socket.onclose=function(t){var i;this===e.socket&&(c&&typeof t.wasClean!="undefined"&&t.wasClean===!1?(i=r._.transportError(r.resources.webSocketClosed,e.transport,t),e.log("Unclean disconnect from websocket: "+(t.reason||"[no reason given]."))):e.log("Websocket closed."),s&&s(i)||(i&&n(e).triggerHandler(u.onError,[i]),l.reconnect(e)))},e.socket.onmessage=function(t){var r;try{r=e._parseResponse(t.data)}catch(u){i.handleParseFailure(e,t.data,u,s,t);return}r&&(n.isEmptyObject(r)||r.M?i.processMessages(e,r,o):i.triggerReceived(e,r))})},reconnect:function(n){i.reconnect(n,this.name)},lostConnection:function(n){this.reconnect(n)},stop:function(n){i.clearReconnectTimeout(n);n.socket&&(n.log("Closing the Websocket."),n.socket.close(),n.socket=null)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){var i=n.signalR,u=n.signalR.events,e=n.signalR.changeState,r=i.transports._logic,f=function(n){t.clearTimeout(n._.reconnectAttemptTimeoutHandle);delete n._.reconnectAttemptTimeoutHandle};i.transports.serverSentEvents={name:"serverSentEvents",supportsKeepAlive:function(){return!0},timeOut:3e3,start:function(o,s,h){var c=this,l=!1,a=n(o),v=!s,y;if(o.eventSource&&(o.log("The connection already has an event source. Stopping it."),o.stop()),!t.EventSource){h&&(o.log("This browser doesn't support SSE."),h());return}y=r.getUrl(o,this.name,v);try{o.log("Attempting to connect to SSE endpoint '"+y+"'.");o.eventSource=new t.EventSource(y,{withCredentials:o.withCredentials})}catch(p){o.log("EventSource failed trying to connect with error "+p.Message+".");h?h():(a.triggerHandler(u.onError,[i._.transportError(i.resources.eventSourceFailedToConnect,o.transport,p)]),v&&c.reconnect(o));return}v&&(o._.reconnectAttemptTimeoutHandle=t.setTimeout(function(){l===!1&&o.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(o)},c.timeOut));o.eventSource.addEventListener("open",function(){o.log("EventSource connected.");f(o);r.clearReconnectTimeout(o);l===!1&&(l=!0,e(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&a.triggerHandler(u.onReconnect))},!1);o.eventSource.addEventListener("message",function(n){var t;if(n.data!=="initialized"){try{t=o._parseResponse(n.data)}catch(i){r.handleParseFailure(o,n.data,i,h,n);return}r.processMessages(o,t,s)}},!1);o.eventSource.addEventListener("error",function(n){var r=i._.transportError(i.resources.eventSourceError,o.transport,n);this===o.eventSource&&(h&&h(r)||(o.log("EventSource readyState: "+o.eventSource.readyState+"."),n.eventPhase===t.EventSource.CLOSED?(o.log("EventSource reconnecting due to the server connection ending."),c.reconnect(o)):(o.log("EventSource error."),a.triggerHandler(u.onError,[r]))))},!1)},reconnect:function(n){r.reconnect(n,this.name)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){f(n);r.clearReconnectTimeout(n);n&&n.eventSource&&(n.log("EventSource calling close()."),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){var r=n.signalR,e=n.signalR.events,o=n.signalR.changeState,i=r.transports._logic,u=function(){var n=t.document.createElement("iframe");return n.setAttribute("style","position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;"),n},f=function(){var i=null,f=1e3,n=0;return{prevent:function(){r._.ieVersion<=8&&(n===0&&(i=t.setInterval(function(){var n=u();t.document.body.appendChild(n);t.document.body.removeChild(n);n=null},f)),n++)},cancel:function(){n===1&&t.clearInterval(i);n>0&&n--}}}();r.transports.foreverFrame={name:"foreverFrame",supportsKeepAlive:function(){return!0},iframeClearThreshold:50,start:function(n,r,e){var l=this,s=i.foreverFrame.count+=1,h,o=u(),c=function(){n.log("Forever frame iframe finished loading and is no longer receiving messages.");e&&e()||l.reconnect(n)};if(t.EventSource){e&&(n.log("Forever Frame is not supported by SignalR on browsers with SSE support."),e());return}o.setAttribute("data-signalr-connection-id",n.id);f.prevent();h=i.getUrl(n,this.name);h+="&frameId="+s;t.document.documentElement.appendChild(o);n.log("Binding to iframe's load event.");o.addEventListener?o.addEventListener("load",c,!1):o.attachEvent&&o.attachEvent("onload",c);o.src=h;i.foreverFrame.connections[s]=n;n.frame=o;n.frameId=s;r&&(n.onSuccess=function(){n.log("Iframe transport started.");r()})},reconnect:function(n){var r=this;i.isConnectedOrReconnecting(n)&&i.verifyLastActive(n)&&t.setTimeout(function(){if(i.verifyLastActive(n)&&n.frame&&i.ensureReconnectingState(n)){var u=n.frame,t=i.getUrl(n,r.name,!0)+"&frameId="+n.frameId;n.log("Updating iframe src to '"+t+"'.");u.src=t}},n.reconnectDelay)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,u){var f,e,o;if(t.json!==t._originalJson&&(u=t._originalJson.stringify(u)),o=t._parseResponse(u),i.processMessages(t,o,t.onSuccess),t.state===n.signalR.connectionState.connected&&(t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>r.transports.foreverFrame.iframeClearThreshold&&(t.frameMessageCount=0,f=t.frame.contentWindow||t.frame.contentDocument,f&&f.document&&f.document.body)))for(e=f.document.body;e.firstChild;)e.removeChild(e.firstChild)},stop:function(n){var r=null;if(f.cancel(),n.frame){if(n.frame.stop)n.frame.stop();else try{r=n.frame.contentWindow||n.frame.contentDocument;r.document&&r.document.execCommand&&r.document.execCommand("Stop")}catch(u){n.log("Error occured when stopping foreverFrame transport. Message = "+u.message+".")}n.frame.parentNode===t.document.body&&t.document.body.removeChild(n.frame);delete i.foreverFrame.connections[n.frameId];n.frame=null;n.frameId=null;delete n.frame;delete n.frameId;delete n.onSuccess;delete n.frameMessageCount;n.log("Stopping forever frame.")}},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){o(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).triggerHandler(e.onReconnect)}}}(window.jQuery,window),function(n,t){var r=n.signalR,u=n.signalR.events,e=n.signalR.changeState,f=n.signalR.isDisconnecting,i=r.transports._logic;r.transports.longPolling={name:"longPolling",supportsKeepAlive:function(){return!1},reconnectDelay:3e3,start:function(o,s,h){var a=this,v=function(){v=n.noop;o.log("LongPolling connected.");s()},y=function(n){return h(n)?(o.log("LongPolling failed to connect."),!0):!1},c=o._,l=0,p=function(i){t.clearTimeout(c.reconnectTimeoutId);c.reconnectTimeoutId=null;e(i,r.connectionState.reconnecting,r.connectionState.connected)===!0&&(i.log("Raising the reconnect event"),n(i).triggerHandler(u.onReconnect))},w=36e5;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop());o.messageId=null;c.reconnectTimeoutId=null;c.pollTimeoutId=t.setTimeout(function(){(function e(s,h){var g=s.messageId,nt=g===null,k=!nt,tt=!h,d=i.getUrl(s,a.name,k,tt,!0),b={};(s.messageId&&(b.messageId=s.messageId),s.groupsToken&&(b.groupsToken=s.groupsToken),f(s)!==!0)&&(o.log("Opening long polling request to '"+d+"'."),s.pollXhr=i.ajax(o,{xhrFields:{onprogress:function(){i.markLastMessage(o)}},url:d,type:"POST",contentType:r._.defaultContentType,data:b,timeout:o._.pollTimeout,success:function(r){var h,w=0,u,a;o.log("Long poll complete.");l=0;try{h=o._parseResponse(r)}catch(b){i.handleParseFailure(s,r,b,y,s.pollXhr);return}(c.reconnectTimeoutId!==null&&p(s),h&&(u=i.maximizePersistentResponse(h)),i.processMessages(s,h,v),u&&n.type(u.LongPollDelay)==="number"&&(w=u.LongPollDelay),f(s)!==!0)&&(a=u&&u.ShouldReconnect,!a||i.ensureReconnectingState(s))&&(w>0?c.pollTimeoutId=t.setTimeout(function(){e(s,a)},w):e(s,a))},error:function(f,h){var v=r._.transportError(r.resources.longPollFailed,o.transport,f,s.pollXhr);if(t.clearTimeout(c.reconnectTimeoutId),c.reconnectTimeoutId=null,h==="abort"){o.log("Aborted xhr request.");return}if(!y(v)){if(l++,o.state!==r.connectionState.reconnecting&&(o.log("An error occurred using longPolling. Status = "+h+". Response = "+f.responseText+"."),n(s).triggerHandler(u.onError,[v])),(o.state===r.connectionState.connected||o.state===r.connectionState.reconnecting)&&!i.verifyLastActive(o))return;if(!i.ensureReconnectingState(s))return;c.pollTimeoutId=t.setTimeout(function(){e(s,!0)},a.reconnectDelay)}}}),k&&h===!0&&(c.reconnectTimeoutId=t.setTimeout(function(){p(s)},Math.min(1e3*(Math.pow(2,l)-1),w))))})(o)},250)},lostConnection:function(n){n.pollXhr&&n.pollXhr.abort("lostConnection")},send:function(n,t){i.ajaxSend(n,t)},stop:function(n){t.clearTimeout(n._.pollTimeoutId);t.clearTimeout(n._.reconnectTimeoutId);delete n._.pollTimeoutId;delete n._.reconnectTimeoutId;n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n){function r(n){return n+e}function s(n,t,i){for(var f=n.length,u=[],r=0;r<f;r+=1)n.hasOwnProperty(r)&&(u[r]=t.call(i,n[r],r,n));return u}function h(t){return n.isFunction(t)?null:n.type(t)==="undefined"?null:t}function u(n){for(var t in n)if(n.hasOwnProperty(t))return!0;return!1}function f(n,t){var i=n._.invocationCallbacks,r,f;u(i)&&n.log("Clearing hub invocation callbacks with error: "+t+".");n._.invocationCallbackId=0;delete n._.invocationCallbacks;n._.invocationCallbacks={};for(f in i)r=i[f],r.method.call(r.scope,{E:t})}function i(n,t){return new i.fn.init(n,t)}function t(i,r){var u={qs:null,logging:!1,useDefaultPath:!0};return n.extend(u,r),(!i||u.useDefaultPath)&&(i=(i||"")+"/signalr"),new t.fn.init(i,u)}var e=".hubProxy",o=n.signalR;i.fn=i.prototype={init:function(n,t){this.state={};this.connection=n;this.hubName=t;this._={callbackMap:{}}},constructor:i,hasSubscriptions:function(){return u(this._.callbackMap)},on:function(t,i){var u=this,f=u._.callbackMap;return t=t.toLowerCase(),f[t]||(f[t]={}),f[t][i]=function(n,t){i.apply(u,t)},n(u).bind(r(t),f[t][i]),u},off:function(t,i){var e=this,o=e._.callbackMap,f;return t=t.toLowerCase(),f=o[t],f&&(f[i]?(n(e).unbind(r(t),f[i]),delete f[i],u(f)||delete o[t]):i||(n(e).unbind(r(t)),delete o[t])),e},invoke:function(t){var i=this,r=i.connection,e=n.makeArray(arguments).slice(1),c=s(e,h),f={H:i.hubName,M:t,A:c,I:r._.invocationCallbackId},u=n.Deferred(),l=function(f){var e=i._maximizeHubResponse(f),h,s;n.extend(i.state,e.State);e.Progress?u.notifyWith?u.notifyWith(i,[e.Progress.Data]):r._.progressjQueryVersionLogged||(r.log("A hub method invocation progress update was received but the version of jQuery in use ("+n.prototype.jquery+") does not support progress updates. Upgrade to jQuery 1.7+ to receive progress notifications."),r._.progressjQueryVersionLogged=!0):e.Error?(e.StackTrace&&r.log(e.Error+"\n"+e.StackTrace+"."),h=e.IsHubException?"HubException":"Exception",s=o._.error(e.Error,h),s.data=e.ErrorData,r.log(i.hubName+"."+t+" failed to execute. Error: "+s.message),u.rejectWith(i,[s])):(r.log("Invoked "+i.hubName+"."+t),u.resolveWith(i,[e.Result]))};return r._.invocationCallbacks[r._.invocationCallbackId.toString()]={scope:i,method:l},r._.invocationCallbackId+=1,n.isEmptyObject(i.state)||(f.S=i.state),r.log("Invoking "+i.hubName+"."+t),r.send(f),u.promise()},_maximizeHubResponse:function(n){return{State:n.S,Result:n.R,Progress:n.P?{Id:n.P.I,Data:n.P.D}:null,Id:n.I,IsHubException:n.H,Error:n.E,StackTrace:n.T,ErrorData:n.D}}};i.fn.init.prototype=i.fn;t.fn=t.prototype=n.connection();t.fn.init=function(t,i){var e={qs:null,logging:!1,useDefaultPath:!0},u=this;n.extend(e,i);n.signalR.fn.init.call(u,t,e.qs,e.logging);u.proxies={};u._.invocationCallbackId=0;u._.invocationCallbacks={};u.received(function(t){var f,o,e,i,s,h;t&&(typeof t.P!="undefined"?(e=t.P.I.toString(),i=u._.invocationCallbacks[e],i&&i.method.call(i.scope,t)):typeof t.I!="undefined"?(e=t.I.toString(),i=u._.invocationCallbacks[e],i&&(u._.invocationCallbacks[e]=null,delete u._.invocationCallbacks[e],i.method.call(i.scope,t))):(f=this._maximizeClientHubInvocation(t),u.log("Triggering client hub event '"+f.Method+"' on hub '"+f.Hub+"'."),s=f.Hub.toLowerCase(),h=f.Method.toLowerCase(),o=this.proxies[s],n.extend(o.state,f.State),n(o).triggerHandler(r(h),[f.Args])))});u.error(function(n,t){var i,r;t&&(i=t.I,r=u._.invocationCallbacks[i],r&&(u._.invocationCallbacks[i]=null,delete u._.invocationCallbacks[i],r.method.call(r.scope,{E:n})))});u.reconnecting(function(){u.transport&&u.transport.name==="webSockets"&&f(u,"Connection started reconnecting before invocation result was received.")});u.disconnected(function(){f(u,"Connection was disconnected before invocation result was received.")})};t.fn._maximizeClientHubInvocation=function(n){return{Hub:n.H,Method:n.M,Args:n.A,State:n.S}};t.fn._registerSubscribedHubs=function(){var t=this;t._subscribedToHubs||(t._subscribedToHubs=!0,t.starting(function(){var i=[];n.each(t.proxies,function(n){this.hasSubscriptions()&&(i.push({name:n}),t.log("Client subscribed to hub '"+n+"'."))});i.length===0&&t.log("No hubs have been subscribed to. The client will not receive data from hubs. To fix, declare at least one client side function prior to connection start for each hub you wish to subscribe to.");t.data=t.json.stringify(i)}))};t.fn.createHubProxy=function(n){n=n.toLowerCase();var t=this.proxies[n];return t||(t=i(this,n),this.proxies[n]=t),this._registerSubscribedHubs(),t};t.fn.init.prototype=t.fn;n.hubConnection=t}(window.jQuery,window),function(n){n.signalR.version="2.2.0"}(window.jQuery) \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/SignalRServer.csproj b/src/SignalR/clients/cpp/samples/SignalRServer/SignalRServer.csproj deleted file mode 100644 index bcb17f2b43aa6def63e1bbff0827044c69ffc683..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/SignalRServer.csproj +++ /dev/null @@ -1,153 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProductVersion> - </ProductVersion> - <SchemaVersion>2.0</SchemaVersion> - <ProjectGuid>{A6782DC4-7435-4DB2-9E34-3F0390BC3FDE}</ProjectGuid> - <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> - <OutputType>Library</OutputType> - <AppDesignerFolder>Properties</AppDesignerFolder> - <RootNamespace>SignalRServer</RootNamespace> - <AssemblyName>SignalRServer</AssemblyName> - <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> - <UseIISExpress>true</UseIISExpress> - <IISExpressSSLPort /> - <IISExpressAnonymousAuthentication /> - <IISExpressWindowsAuthentication /> - <IISExpressUseClassicPipelineMode /> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> - <DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">true</DownloadNuGetExe> - <RestorePackages>true</RestorePackages> - </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="Microsoft.AspNet.SignalR.Core"> - <HintPath>..\..\packages\Microsoft.AspNet.SignalR.Core.2.2.0\lib\net45\Microsoft.AspNet.SignalR.Core.dll</HintPath> - </Reference> - <Reference Include="Microsoft.AspNet.SignalR.SystemWeb"> - <HintPath>..\..\packages\Microsoft.AspNet.SignalR.SystemWeb.2.2.0\lib\net45\Microsoft.AspNet.SignalR.SystemWeb.dll</HintPath> - </Reference> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath> - </Reference> - <Reference Include="Microsoft.Owin.Host.SystemWeb"> - <HintPath>..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath> - </Reference> - <Reference Include="Microsoft.Owin.Security"> - <HintPath>..\..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath> - </Reference> - <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> - <Private>True</Private> - <HintPath>..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath> - </Reference> - <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath> - </Reference> - <Reference Include="Owin"> - <HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath> - </Reference> - <Reference Include="System.Web.DynamicData" /> - <Reference Include="System.Web.Entity" /> - <Reference Include="System.Web.ApplicationServices" /> - <Reference Include="System.ComponentModel.DataAnnotations" /> - <Reference Include="System" /> - <Reference Include="System.Data" /> - <Reference Include="System.Core" /> - <Reference Include="System.Data.DataSetExtensions" /> - <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" /> - </ItemGroup> - <ItemGroup> - <Content Include="packages.config" /> - <Content Include="Scripts\jquery-1.10.2.min.map" /> - <None Include="Web.Debug.config"> - <DependentUpon>Web.config</DependentUpon> - </None> - <None Include="Web.Release.config"> - <DependentUpon>Web.config</DependentUpon> - </None> - </ItemGroup> - <ItemGroup> - <None Include="Scripts\jquery-1.10.2.intellisense.js" /> - <Content Include="index.html" /> - <Content Include="Scripts\jquery-1.10.2.js" /> - <Content Include="Scripts\jquery-1.10.2.min.js" /> - <Content Include="Scripts\jquery.signalR-2.2.0.js" /> - <Content Include="Scripts\jquery.signalR-2.2.0.min.js" /> - <Content Include="Web.config" /> - </ItemGroup> - <ItemGroup> - <Compile Include="ChatHub.cs" /> - <Compile Include="EchoConnection.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="Startup.cs" /> - </ItemGroup> - <PropertyGroup> - <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> - <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> - </PropertyGroup> - <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> - <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> - <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /> - <ProjectExtensions> - <VisualStudio> - <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}"> - <WebProjectProperties> - <UseIIS>True</UseIIS> - <AutoAssignPort>True</AutoAssignPort> - <DevelopmentServerPort>34281</DevelopmentServerPort> - <DevelopmentServerVPath>/</DevelopmentServerVPath> - <IISUrl>http://localhost:34281/</IISUrl> - <NTLMAuthentication>False</NTLMAuthentication> - <UseCustomServer>False</UseCustomServer> - <CustomServerUrl> - </CustomServerUrl> - <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile> - </WebProjectProperties> - </FlavorProperties> - </VisualStudio> - </ProjectExtensions> - <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> - <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> - <PropertyGroup> - <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> - </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" /> - </Target> - <!-- 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> - --> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/Startup.cs b/src/SignalR/clients/cpp/samples/SignalRServer/Startup.cs deleted file mode 100644 index d2c4b421cbe462cadfe16aa9fcc14b7ff7ff5d04..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Startup.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Threading.Tasks; -using Microsoft.Owin; -using Owin; - -[assembly: OwinStartup(typeof(SignalRServer.Startup))] - -namespace SignalRServer -{ - public class Startup - { - public void Configuration(IAppBuilder app) - { - app.MapSignalR(); - app.MapSignalR<EchoConnection>("/echo"); - } - } -} diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/Web.Debug.config b/src/SignalR/clients/cpp/samples/SignalRServer/Web.Debug.config deleted file mode 100644 index 2e302f9f9548be48e2d23d63555602b2f7362dbb..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Web.Debug.config +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- 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 attribute "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/SignalR/clients/cpp/samples/SignalRServer/Web.Release.config b/src/SignalR/clients/cpp/samples/SignalRServer/Web.Release.config deleted file mode 100644 index c35844462ba8e330eec0cc96b63d61bd4ed65df4..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Web.Release.config +++ /dev/null @@ -1,31 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- 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 attribute "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/SignalR/clients/cpp/samples/SignalRServer/Web.config b/src/SignalR/clients/cpp/samples/SignalRServer/Web.config deleted file mode 100644 index 68a9c04f415dfba334e9c885091ed2ea60a84716..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/Web.config +++ /dev/null @@ -1,23 +0,0 @@ -<?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=169433 - --> -<configuration> - <system.web> - <compilation debug="true" targetFramework="4.5" /> - <httpRuntime targetFramework="4.5" /> - </system.web> - <runtime> - <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> - <dependentAssembly> - <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> - </dependentAssembly> - <dependentAssembly> - <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> - </dependentAssembly> - </assemblyBinding> - </runtime> -</configuration> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/index.html b/src/SignalR/clients/cpp/samples/SignalRServer/index.html deleted file mode 100644 index 5a031cb4f3fee23d1ca9fdd863dab59f6392365d..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/index.html +++ /dev/null @@ -1,58 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title>SignalR Simple Chat</title> - <style type="text/css"> - .container { - background-color: #99CCFF; - border: thick solid #808080; - padding: 20px; - margin: 20px; - } - </style> -</head> -<body> - <div class="container"> - <input type="text" id="message" /> - <input type="button" id="sendmessage" value="Send" /> - <input type="hidden" id="displayname" /> - <ul id="discussion"></ul> - </div> - <!--Script references. --> - <!--Reference the jQuery library. --> - <script src="Scripts/jquery-1.10.2.min.js"></script> - <!--Reference the SignalR library. --> - <script src="Scripts/jquery.signalR-2.2.0.min.js"></script> - <!--Reference the autogenerated SignalR hub script. --> - <script src="signalr/hubs"></script> - <!--Add script to update the page and send messages.--> - <script type="text/javascript"> - $(function () { - // Declare a proxy to reference the hub. - var chat = $.connection.chatHub; - // Create a function that the hub can call to broadcast messages. - chat.client.broadcastMessage = function (name, message) { - // Html encode display name and message. - var encodedName = $('<div />').text(name).html(); - var encodedMsg = $('<div />').text(message).html(); - // Add the message to the page. - $('#discussion').append('<li><strong>' + encodedName - + '</strong>: ' + encodedMsg + '</li>'); - }; - // Get the user name and store it to prepend to messages. - $('#displayname').val(prompt('Enter your name:', '')); - // Set initial focus to message input box. - $('#message').focus(); - // Start the connection. - $.connection.hub.start().done(function () { - $('#sendmessage').click(function () { - // Call the Send method on the hub. - chat.server.send($('#displayname').val(), $('#message').val()); - // Clear text box and reset focus for next comment. - $('#message').val('').focus(); - }); - }); - }); - </script> -</body> -</html> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/samples/SignalRServer/packages.config b/src/SignalR/clients/cpp/samples/SignalRServer/packages.config deleted file mode 100644 index db5106da6dabd478cba30fdbae5e8bf85256847d..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/samples/SignalRServer/packages.config +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<packages> - <package id="jQuery" version="1.10.2" targetFramework="net45" /> - <package id="Microsoft.AspNet.SignalR" version="2.2.0" targetFramework="net45" /> - <package id="Microsoft.AspNet.SignalR.Core" version="2.2.0" targetFramework="net45" /> - <package id="Microsoft.AspNet.SignalR.JS" version="2.2.0" targetFramework="net45" /> - <package id="Microsoft.AspNet.SignalR.SystemWeb" version="2.2.0" targetFramework="net45" /> - <package id="Microsoft.Owin" version="3.0.1" targetFramework="net45" /> - <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.0" targetFramework="net45" /> - <package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net45" /> - <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" /> - <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net45" /> - <package id="Owin" version="1.0" targetFramework="net45" /> -</packages> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/signalrclient.sln b/src/SignalR/clients/cpp/signalrclient.sln deleted file mode 100644 index 06a00bf2b76d7f4c9bdea8e77d521fe0ba9f86fa..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/signalrclient.sln +++ /dev/null @@ -1,144 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.0.0 -MinimumVisualStudioVersion = 16.0.0.0 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signalrclient", "src\signalrclient\Build\VS\signalrclient.vcxproj", "{87ED3AD4-D820-48CD-8382-A12564213A12}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signalrclienttests", "test\signalrclienttests\Build\VS\signalrclienttests.vcxproj", "{10376148-BCF4-4B55-98A5-3C98C87FD898}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signalrclientdll", "src\signalrclientdll\Build\VS\signalrclientdll.vcxproj", "{18377AE8-E372-40CE-94FD-7F65008D39A3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{AABF08B1-12A4-4D06-A188-F01FBF8A9658}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "signalrclient-e2e-tests", "test\signalrclient-e2e-tests\Build\VS\signalrclient-e2e-tests.vcxproj", "{6006C96A-29F0-4B18-8DDD-764DC3419E2F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "signalrclient-testhost", "test\signalrclient-testhost\signalrclient-testhost.csproj", "{11848039-1F13-4047-9539-8F9F45930788}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HubConnectionSample", "samples\HubConnectionSample\HubConnectionSample.vcxproj", "{3C9BD092-18E6-4C6E-A887-CDFC80ACB206}" - ProjectSection(ProjectDependencies) = postProject - {18377AE8-E372-40CE-94FD-7F65008D39A3} = {18377AE8-E372-40CE-94FD-7F65008D39A3} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest", "test\gtest\gtest.vcxproj", "{CAC1267B-8778-4257-AAC6-CAF481723B01}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Any CPU = Release|Any CPU - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Win32.ActiveCfg = Debug|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|Win32.Build.0 = Debug|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|x64.ActiveCfg = Debug|x64 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Debug|x64.Build.0 = Debug|x64 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Any CPU.ActiveCfg = Release|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Mixed Platforms.Build.0 = Release|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Win32.ActiveCfg = Release|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Release|Win32.Build.0 = Release|Win32 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Release|x64.ActiveCfg = Release|x64 - {87ED3AD4-D820-48CD-8382-A12564213A12}.Release|x64.Build.0 = Release|x64 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Win32.ActiveCfg = Debug|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|Win32.Build.0 = Debug|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|x64.ActiveCfg = Debug|x64 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Debug|x64.Build.0 = Debug|x64 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Any CPU.ActiveCfg = Release|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Mixed Platforms.Build.0 = Release|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Win32.ActiveCfg = Release|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|Win32.Build.0 = Release|Win32 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|x64.ActiveCfg = Release|x64 - {10376148-BCF4-4B55-98A5-3C98C87FD898}.Release|x64.Build.0 = Release|x64 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Win32.ActiveCfg = Debug|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|Win32.Build.0 = Debug|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|x64.ActiveCfg = Debug|x64 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Debug|x64.Build.0 = Debug|x64 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Any CPU.ActiveCfg = Release|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Mixed Platforms.Build.0 = Release|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Win32.ActiveCfg = Release|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|Win32.Build.0 = Release|Win32 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|x64.ActiveCfg = Release|x64 - {18377AE8-E372-40CE-94FD-7F65008D39A3}.Release|x64.Build.0 = Release|x64 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Win32.ActiveCfg = Debug|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|Win32.Build.0 = Debug|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|x64.ActiveCfg = Debug|x64 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Debug|x64.Build.0 = Debug|x64 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Any CPU.ActiveCfg = Release|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Mixed Platforms.Build.0 = Release|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Win32.ActiveCfg = Release|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|Win32.Build.0 = Release|Win32 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|x64.ActiveCfg = Release|x64 - {6006C96A-29F0-4B18-8DDD-764DC3419E2F}.Release|x64.Build.0 = Release|x64 - {11848039-1F13-4047-9539-8F9F45930788}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Debug|Any CPU.Build.0 = Debug|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Debug|Win32.ActiveCfg = Debug|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Debug|x64.ActiveCfg = Debug|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Release|Any CPU.ActiveCfg = Release|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Release|Any CPU.Build.0 = Release|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Release|Win32.ActiveCfg = Release|Any CPU - {11848039-1F13-4047-9539-8F9F45930788}.Release|x64.ActiveCfg = Release|Any CPU - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.ActiveCfg = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|Win32.Build.0 = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Debug|x64.ActiveCfg = Debug|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Any CPU.ActiveCfg = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Mixed Platforms.Build.0 = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.ActiveCfg = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|Win32.Build.0 = Release|Win32 - {3C9BD092-18E6-4C6E-A887-CDFC80ACB206}.Release|x64.ActiveCfg = Release|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Win32.ActiveCfg = Debug|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|Win32.Build.0 = Debug|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|x64.ActiveCfg = Debug|x64 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Debug|x64.Build.0 = Debug|x64 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Any CPU.ActiveCfg = Release|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Mixed Platforms.Build.0 = Release|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Win32.ActiveCfg = Release|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|Win32.Build.0 = Release|Win32 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|x64.ActiveCfg = Release|x64 - {CAC1267B-8778-4257-AAC6-CAF481723B01}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {10376148-BCF4-4B55-98A5-3C98C87FD898} = {AABF08B1-12A4-4D06-A188-F01FBF8A9658} - {6006C96A-29F0-4B18-8DDD-764DC3419E2F} = {AABF08B1-12A4-4D06-A188-F01FBF8A9658} - {11848039-1F13-4047-9539-8F9F45930788} = {AABF08B1-12A4-4D06-A188-F01FBF8A9658} - {CAC1267B-8778-4257-AAC6-CAF481723B01} = {AABF08B1-12A4-4D06-A188-F01FBF8A9658} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {0286287F-3519-42E6-9165-FB342028F9FF} - EndGlobalSection -EndGlobal diff --git a/src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj b/src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj deleted file mode 100644 index 88168fdf9844d8b0d0f067cc1a17211b025b58da..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj +++ /dev/null @@ -1,112 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="..\..\..\..\Build\SignalRClient.Build.Settings" /> - <PropertyGroup Label="Globals"> - <ProjectGuid>{87ED3AD4-D820-48CD-8382-A12564213A12}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>signalr</RootNamespace> - <ProjectName>signalrclient</ProjectName> - <TargetName>$(SignalrClientTargetName)</TargetName> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir> - <OutDir Condition="'$(OutDir)' == ''">$(SolutionDir)$(Configuration)\</OutDir> - <OutDir>$(OutDir)lib\</OutDir> - <IntDir>$(Configuration)\lib\</IntDir> - <ConfigurationType>StaticLibrary</ConfigurationType> - <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="..\..\..\..\Build\Config.Definitions.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_WINDOWS;_USRDLL;NO_SIGNALRCLIENT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\..\..\..\include\signalrclient\connection.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\connection_state.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\http_client.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\hub_connection.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\hub_exception.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\log_writer.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\signalr_client_config.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\signalr_exception.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\trace_level.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\transfer_format.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\websocket_client.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\web_exception.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\_exports.h" /> - <ClInclude Include="..\..\case_insensitive_comparison_utils.h" /> - <ClInclude Include="..\..\connection_impl.h" /> - <ClInclude Include="..\..\constants.h" /> - <ClInclude Include="..\..\default_http_client.h" /> - <ClInclude Include="..\..\default_websocket_client.h" /> - <ClInclude Include="..\..\event.h" /> - <ClInclude Include="..\..\http_sender.h" /> - <ClInclude Include="..\..\hub_connection_impl.h" /> - <ClInclude Include="..\..\callback_manager.h" /> - <ClInclude Include="..\..\logger.h" /> - <ClInclude Include="..\..\negotiation_response.h" /> - <ClInclude Include="..\..\negotiate.h" /> - <ClInclude Include="..\..\stdafx.h" /> - <ClInclude Include="..\..\trace_log_writer.h" /> - <ClInclude Include="..\..\transport.h" /> - <ClInclude Include="..\..\transport_factory.h" /> - <ClInclude Include="..\..\url_builder.h" /> - <ClInclude Include="..\..\websocket_transport.h" /> - <ClInclude Include="..\..\web_request.h" /> - <ClInclude Include="..\..\web_request_factory.h" /> - <ClInclude Include="..\..\web_response.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\connection.cpp" /> - <ClCompile Include="..\..\connection_impl.cpp" /> - <ClCompile Include="..\..\default_http_client.cpp" /> - <ClCompile Include="..\..\http_sender.cpp" /> - <ClCompile Include="..\..\hub_connection.cpp" /> - <ClCompile Include="..\..\hub_connection_impl.cpp" /> - <ClCompile Include="..\..\callback_manager.cpp" /> - <ClCompile Include="..\..\logger.cpp" /> - <ClCompile Include="..\..\negotiate.cpp" /> - <ClCompile Include="..\..\signalr_client_config.cpp" /> - <ClCompile Include="..\..\stdafx.cpp"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - <ClCompile Include="..\..\trace_log_writer.cpp" /> - <ClCompile Include="..\..\transport.cpp" /> - <ClCompile Include="..\..\transport_factory.cpp" /> - <ClCompile Include="..\..\url_builder.cpp" /> - <ClCompile Include="..\..\default_websocket_client.cpp" /> - <ClCompile Include="..\..\websocket_transport.cpp" /> - <ClCompile Include="..\..\web_request.cpp" /> - <ClCompile Include="..\..\web_request_factory.cpp" /> - </ItemGroup> - <ItemGroup> - <PackageReference Include="cpprestsdk" Version="2.9.1.1" /> - <PackageReference Include="cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj.filters b/src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj.filters deleted file mode 100644 index aceb1a98079d799f2b2620588c0012bf63586dfa..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/Build/VS/signalrclient.vcxproj.filters +++ /dev/null @@ -1,183 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\..\stdafx.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\connection.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\_exports.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\trace_level.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\url_builder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\constants.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\http_sender.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\web_exception.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\negotiation_response.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\websocket_transport.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\connection_impl.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\connection_state.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\default_websocket_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\log_writer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\logger.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\trace_log_writer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\transport_factory.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\web_request_factory.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\transport.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\web_response.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\web_request.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\hub_connection_impl.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\callback_manager.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\hub_exception.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\hub_connection.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\case_insensitive_comparison_utils.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\event.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\signalr_exception.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\signalr_client_config.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\default_http_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\negotiate.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\http_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\transfer_format.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\websocket_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\stdafx.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\url_builder.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\web_request.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\connection_impl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\http_sender.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\connection.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\transport_factory.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\web_request_factory.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\default_websocket_client.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\websocket_transport.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\logger.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\transport.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\hub_connection_impl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\callback_manager.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\hub_connection.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\trace_log_writer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\signalr_client_config.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\default_http_client.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\negotiate.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/src/signalrclient/CMakeLists.txt b/src/SignalR/clients/cpp/src/signalrclient/CMakeLists.txt deleted file mode 100644 index 2a48428ef06ed17722e4679d1bd5aea491dcd3d4..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ - - -set (SOURCES - callback_manager.cpp - connection.cpp - connection_impl.cpp - default_websocket_client.cpp - http_sender.cpp - hub_connection.cpp - hub_connection_impl.cpp - logger.cpp - request_sender.cpp - signalr_client_config.cpp - stdafx.cpp - trace_log_writer.cpp - transport.cpp - transport_factory.cpp - url_builder.cpp - web_request.cpp - web_request_factory.cpp - websocket_transport.cpp -) - -add_library (signalrclient SHARED ${SOURCES}) - -target_link_libraries(signalrclient ${CPPREST_SO}) diff --git a/src/SignalR/clients/cpp/src/signalrclient/callback_manager.cpp b/src/SignalR/clients/cpp/src/signalrclient/callback_manager.cpp deleted file mode 100644 index 31f6806c54104564c2a5b3e4d2b1720817335545..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/callback_manager.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "callback_manager.h" - -namespace signalr -{ - // dtor_clear_arguments will be passed when closing any pending callbacks when the `callback_manager` is - // destroyed (i.e. in the dtor) - callback_manager::callback_manager(const web::json::value& dtor_clear_arguments) - : m_dtor_clear_arguments(dtor_clear_arguments) - { } - - callback_manager::~callback_manager() - { - clear(m_dtor_clear_arguments); - } - - // note: callback must not throw except for the `on_progress` callback which will never be invoked from the dtor - std::string callback_manager::register_callback(const std::function<void(const web::json::value&)>& callback) - { - auto callback_id = get_callback_id(); - - { - std::lock_guard<std::mutex> lock(m_map_lock); - - m_callbacks.insert(std::make_pair(callback_id, callback)); - } - - return callback_id; - } - - - // invokes a callback and stops tracking it if remove callback set to true - bool callback_manager::invoke_callback(const std::string& callback_id, const web::json::value& arguments, bool remove_callback) - { - std::function<void(const web::json::value& arguments)> callback; - - { - std::lock_guard<std::mutex> lock(m_map_lock); - - auto iter = m_callbacks.find(callback_id); - if (iter == m_callbacks.end()) - { - return false; - } - - callback = iter->second; - - if (remove_callback) - { - m_callbacks.erase(callback_id); - } - } - - callback(arguments); - return true; - } - - bool callback_manager::remove_callback(const std::string& callback_id) - { - { - std::lock_guard<std::mutex> lock(m_map_lock); - - return m_callbacks.erase(callback_id) != 0; - } - } - - void callback_manager::clear(const web::json::value& arguments) - { - { - std::lock_guard<std::mutex> lock(m_map_lock); - - for (auto& kvp : m_callbacks) - { - kvp.second(arguments); - } - - m_callbacks.clear(); - } - } - - std::string callback_manager::get_callback_id() - { - const auto callback_id = m_id++; - std::stringstream ss; - ss << callback_id; - return ss.str(); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/callback_manager.h b/src/SignalR/clients/cpp/src/signalrclient/callback_manager.h deleted file mode 100644 index ae1bb877bbf118f29d927c00858a4072e859f32f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/callback_manager.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <atomic> -#include <unordered_map> -#include <functional> -#include <mutex> -#include "cpprest/json.h" - -namespace signalr -{ - class callback_manager - { - public: - explicit callback_manager(const web::json::value& dtor_error); - ~callback_manager(); - - callback_manager(const callback_manager&) = delete; - callback_manager& operator=(const callback_manager&) = delete; - - std::string register_callback(const std::function<void(const web::json::value&)>& callback); - bool invoke_callback(const std::string& callback_id, const web::json::value& arguments, bool remove_callback); - bool remove_callback(const std::string& callback_id); - void clear(const web::json::value& arguments); - - private: - std::atomic<int> m_id { 0 }; - std::unordered_map<std::string, std::function<void(const web::json::value&)>> m_callbacks; - std::mutex m_map_lock; - const web::json::value m_dtor_clear_arguments; - - std::string get_callback_id(); - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/case_insensitive_comparison_utils.h b/src/SignalR/clients/cpp/src/signalrclient/case_insensitive_comparison_utils.h deleted file mode 100644 index a5b3f2eb31318133edc054c46ca51b33af7f0f30..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/case_insensitive_comparison_utils.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <functional> -#include <cctype> -#include "cpprest/details/basic_types.h" - -namespace signalr -{ - // Note: These functions are not pretending to be all-purpose helpers for case insensitive string comparison. Rather - // we use them to compare hub and hub method names which are expected to be almost exclusively ASCII and this is the - // simplest thing that would work without having to take dependencies on third party libraries. - struct case_insensitive_equals : std::binary_function<std::string, std::string, bool> - { - bool operator()(const std::string& s1, const std::string& s2) const - { - if (s1.length() != s2.length()) - { - return false; - } - - for (auto s1_iterator = s1.begin(), s2_iterator = s2.begin(); s1_iterator != s1.end(); ++s1_iterator, ++s2_iterator) - { - if (std::toupper(*s1_iterator) != std::toupper(*s2_iterator)) - { - return false; - } - } - - return true; - } - }; - - struct case_insensitive_hash : std::unary_function<std::string, std::size_t> - { - std::size_t operator()(const std::string& s) const noexcept - { - size_t hash = 0; - std::hash<size_t> hasher; - for (const utility::char_t& c : s) - { - hash ^= hasher(std::toupper(c)) + (hash << 5) + (hash >> 2); - } - - return hash; - } - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/connection.cpp b/src/SignalR/clients/cpp/src/signalrclient/connection.cpp deleted file mode 100644 index 6a5a94064030dedfa6f451360e4f3e685df1801b..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/connection.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "signalrclient/connection.h" -#include "signalrclient/transport_type.h" -#include "connection_impl.h" - -namespace signalr -{ - connection::connection(const std::string& url, trace_level trace_level, std::shared_ptr<log_writer> log_writer) - : m_pImpl(connection_impl::create(url, trace_level, std::move(log_writer))) - {} - - // Do NOT remove this destructor. Letting the compiler generate and inline the default dtor may lead to - // undefinded behavior since we are using an incomplete type. More details here: http://herbsutter.com/gotw/_100/ - connection::~connection() = default; - - void connection::start(std::function<void(std::exception_ptr)> callback) noexcept - { - m_pImpl->start(callback); - } - - void connection::send(const std::string& data, std::function<void(std::exception_ptr)> callback) noexcept - { - m_pImpl->send(data, callback); - } - - void connection::set_message_received(const message_received_handler& message_received_callback) - { - m_pImpl->set_message_received(message_received_callback); - } - - void connection::set_disconnected(const std::function<void()>& disconnected_callback) - { - m_pImpl->set_disconnected(disconnected_callback); - } - - void connection::set_client_config(const signalr_client_config& config) - { - m_pImpl->set_client_config(config); - } - - void connection::stop(std::function<void(std::exception_ptr)> callback) noexcept - { - m_pImpl->stop(callback); - } - - connection_state connection::get_connection_state() const noexcept - { - return m_pImpl->get_connection_state(); - } - - std::string connection::get_connection_id() const - { - return m_pImpl->get_connection_id(); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/connection_impl.cpp b/src/SignalR/clients/cpp/src/signalrclient/connection_impl.cpp deleted file mode 100644 index 4348db6562786791dd9ddbfaa474353b7c180768..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/connection_impl.cpp +++ /dev/null @@ -1,627 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include <thread> -#include <algorithm> -#include "constants.h" -#include "connection_impl.h" -#include "negotiate.h" -#include "url_builder.h" -#include "trace_log_writer.h" -#include "make_unique.h" -#include "signalrclient/signalr_exception.h" -#include "default_http_client.h" - -namespace signalr -{ - // unnamed namespace makes it invisble outside this translation unit - namespace - { - // this is a workaround for a compiler bug where mutable lambdas won't sometimes compile - static void log(const logger& logger, trace_level level, const std::string& entry); - } - - std::shared_ptr<connection_impl> connection_impl::create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer) - { - return connection_impl::create(url, trace_level, log_writer, nullptr, std::make_unique<transport_factory>()); - } - - std::shared_ptr<connection_impl> connection_impl::create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer, - std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory) - { - return std::shared_ptr<connection_impl>(new connection_impl(url, trace_level, - log_writer ? log_writer : std::make_shared<trace_log_writer>(), std::move(http_client), std::move(transport_factory))); - } - - connection_impl::connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer, - std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory) - : m_base_url(url), m_connection_state(connection_state::disconnected), m_logger(log_writer, trace_level), m_transport(nullptr), - m_transport_factory(std::move(transport_factory)), m_message_received([](const std::string&) noexcept {}), m_disconnected([]() noexcept {}) - { - if (http_client != nullptr) - { - m_http_client = std::move(http_client); - } - else - { - m_http_client = std::unique_ptr<class http_client>(new default_http_client()); - } - } - - connection_impl::~connection_impl() - { - try - { - // Signaling the event is safe here. We are in the dtor so noone is using this instance. There might be some - // outstanding threads that hold on to the connection via a weak pointer but they won't be able to acquire - // the instance since it is being destroyed. Note that the event may actually be in non-signaled state here. - m_start_completed_event.set(); - shutdown().get(); - } - catch (const pplx::task_canceled&) - { - // because we are in the dtor and the `connection_imp` is ref counted we should not get the `task_canceled` - // exception because it would indicate that some other thread/task still holds reference to this instance - // so how come we are in the dtor? - _ASSERTE(false); - return; - } - catch (...) // must not throw from destructors - { } - - m_transport = nullptr; - change_state(connection_state::disconnected); - } - - void connection_impl::start(std::function<void(std::exception_ptr)> callback) noexcept - { - { - std::lock_guard<std::mutex> lock(m_stop_lock); - if (!change_state(connection_state::disconnected, connection_state::connecting)) - { - callback(std::make_exception_ptr(signalr_exception("cannot start a connection that is not in the disconnected state"))); - return; - } - - // there should not be any active transport at this point - _ASSERTE(!m_transport); - - m_disconnect_cts = pplx::cancellation_token_source(); - m_start_completed_event.reset(); - m_connection_id = ""; - } - - start_negotiate(m_base_url, 0) - .then([callback](pplx::task<void> prev_task) - { - try - { - prev_task.get(); - callback(nullptr); - } - catch (...) - { - callback(std::current_exception()); - } - }); - } - - pplx::task<void> connection_impl::start_negotiate(const std::string& url, int redirect_count) - { - if (redirect_count >= MAX_NEGOTIATE_REDIRECTS) - { - return pplx::task_from_exception<void>(signalr_exception("Negotiate redirection limit exceeded.")); - } - - pplx::task_completion_event<void> start_tce; - - std::weak_ptr<connection_impl> weak_connection = shared_from_this(); - - pplx::task_from_result() - .then([weak_connection, url]() - { - auto connection = weak_connection.lock(); - if (!connection) - { - return pplx::task_from_exception<negotiation_response>("connection no longer exists"); - } - return negotiate::negotiate(*connection->m_http_client, url, connection->m_signalr_client_config); - }, m_disconnect_cts.get_token()) - .then([weak_connection, start_tce, redirect_count, url](negotiation_response negotiation_response) - { - auto connection = weak_connection.lock(); - if (!connection) - { - return pplx::task_from_exception<void>("connection no longer exists"); - } - - if (!negotiation_response.error.empty()) - { - return pplx::task_from_exception<void>(signalr_exception(negotiation_response.error)); - } - - if (!negotiation_response.url.empty()) - { - if (!negotiation_response.accessToken.empty()) - { - auto headers = connection->m_signalr_client_config.get_http_headers(); - headers[_XPLATSTR("Authorization")] = utility::conversions::to_string_t("Bearer " + negotiation_response.accessToken); - connection->m_signalr_client_config.set_http_headers(headers); - } - return connection->start_negotiate(negotiation_response.url, redirect_count + 1); - } - - connection->m_connection_id = std::move(negotiation_response.connectionId); - - // TODO: fallback logic - - bool foundWebsockets = false; - for (auto availableTransport : negotiation_response.availableTransports) - { - if (availableTransport.transport == "WebSockets") - { - foundWebsockets = true; - break; - } - } - - if (!foundWebsockets) - { - return pplx::task_from_exception<void>(signalr_exception("The server does not support WebSockets which is currently the only transport supported by this client.")); - } - - // TODO: use transfer format - - return connection->start_transport(url) - .then([weak_connection, start_tce](std::shared_ptr<transport> transport) - { - auto connection = weak_connection.lock(); - if (!connection) - { - return pplx::task_from_exception<void>("connection no longer exists"); - } - connection->m_transport = transport; - - if (!connection->change_state(connection_state::connecting, connection_state::connected)) - { - connection->m_logger.log(trace_level::errors, - std::string("internal error - transition from an unexpected state. expected state: connecting, actual state: ") - .append(translate_connection_state(connection->get_connection_state()))); - - _ASSERTE(false); - } - - return pplx::task_from_result(); - }); - }, m_disconnect_cts.get_token()) - .then([start_tce, weak_connection](pplx::task<void> previous_task) - { - auto connection = weak_connection.lock(); - if (!connection) - { - return pplx::task_from_exception<void>(_XPLATSTR("connection no longer exists")); - } - try - { - previous_task.get(); - connection->m_start_completed_event.set(); - start_tce.set(); - } - catch (const std::exception & e) - { - auto task_canceled_exception = dynamic_cast<const pplx::task_canceled*>(&e); - if (task_canceled_exception) - { - connection->m_logger.log(trace_level::info, - "starting the connection has been canceled."); - } - else - { - connection->m_logger.log(trace_level::errors, - std::string("connection could not be started due to: ") - .append(e.what())); - } - - connection->m_transport = nullptr; - connection->change_state(connection_state::disconnected); - connection->m_start_completed_event.set(); - start_tce.set_exception(std::current_exception()); - } - - return pplx::task_from_result(); - }); - - return pplx::create_task(start_tce); - } - - pplx::task<std::shared_ptr<transport>> connection_impl::start_transport(const std::string& url) - { - auto connection = shared_from_this(); - - pplx::task_completion_event<void> connect_request_tce; - - auto weak_connection = std::weak_ptr<connection_impl>(connection); - const auto& disconnect_cts = m_disconnect_cts; - const auto& logger = m_logger; - - auto transport = connection->m_transport_factory->create_transport( - transport_type::websockets, connection->m_logger, connection->m_signalr_client_config); - - transport->on_receive([disconnect_cts, connect_request_tce, logger, weak_connection](std::string message, std::exception_ptr exception) - { - if (exception != nullptr) - { - try - { - // Rethrowing the exception so we can log it - std::rethrow_exception(exception); - } - catch (const std::exception & e) - { - // When a connection is stopped we don't wait for its transport to stop. As a result if the same connection - // is immediately re-started the old transport can still invoke this callback. To prevent this we capture - // the disconnect_cts by value which allows distinguishing if the error is for the running connection - // or for the one that was already stopped. If this is the latter we just ignore it. - if (disconnect_cts.get_token().is_canceled()) - { - logger.log(trace_level::info, - std::string{ "ignoring stray error received after connection was restarted. error: " } - .append(e.what())); - - return; - } - - // no op after connection started successfully - connect_request_tce.set_exception(exception); - } - } - else - { - if (disconnect_cts.get_token().is_canceled()) - { - logger.log(trace_level::info, - std::string{ "ignoring stray message received after connection was restarted. message: " } - .append(message)); - return; - } - - auto connection = weak_connection.lock(); - if (connection) - { - connection->process_response(message); - } - } - }); - - pplx::create_task([connect_request_tce, disconnect_cts, weak_connection]() - { - // TODO? std::this_thread::sleep_for(std::chrono::milliseconds(negotiation_response.transport_connect_timeout)); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - - // if the disconnect_cts is canceled it means that the connection has been stopped or went out of scope in - // which case we should not throw due to timeout. Instead we need to set the tce prevent the task that is - // using this tce from hanging indifinitely. (This will eventually result in throwing the pplx::task_canceled - // exception to the user since this is what we do in the start() function if disconnect_cts is tripped). - if (disconnect_cts.get_token().is_canceled()) - { - connect_request_tce.set(); - } - else - { - connect_request_tce.set_exception(signalr_exception("transport timed out when trying to connect")); - } - }); - - return connection->send_connect_request(transport, url, connect_request_tce) - .then([transport](){ return pplx::task_from_result(transport); }); - } - - pplx::task<void> connection_impl::send_connect_request(const std::shared_ptr<transport>& transport, const std::string& url, const pplx::task_completion_event<void>& connect_request_tce) - { - auto logger = m_logger; - auto query_string = "id=" + m_connection_id; - auto connect_url = url_builder::build_connect(url, transport->get_transport_type(), query_string); - - transport->start(connect_url, transfer_format::text, [transport, connect_request_tce, logger](std::exception_ptr exception) - mutable { - try - { - if (exception != nullptr) - { - std::rethrow_exception(exception); - } - connect_request_tce.set(); - } - catch (const std::exception& e) - { - logger.log( - trace_level::errors, - std::string("transport could not connect due to: ") - .append(e.what())); - - connect_request_tce.set_exception(std::current_exception()); - } - }); - - return pplx::create_task(connect_request_tce); - } - - void connection_impl::process_response(const std::string& response) - { - m_logger.log(trace_level::messages, - std::string("processing message: ").append(response)); - - invoke_message_received(response); - } - - void connection_impl::invoke_message_received(const std::string& message) - { - try - { - m_message_received(message); - } - catch (const std::exception &e) - { - m_logger.log( - trace_level::errors, - std::string("message_received callback threw an exception: ") - .append(e.what())); - } - catch (...) - { - m_logger.log(trace_level::errors, "message_received callback threw an unknown exception"); - } - } - - void connection_impl::send(const std::string& data, std::function<void(std::exception_ptr)> callback) noexcept - { - // To prevent an (unlikely) condition where the transport is nulled out after we checked the connection_state - // and before sending data we store the pointer in the local variable. In this case `send()` will throw but - // we won't crash. - auto transport = m_transport; - - const auto connection_state = get_connection_state(); - if (connection_state != signalr::connection_state::connected || !transport) - { - callback(std::make_exception_ptr(signalr_exception( - std::string("cannot send data when the connection is not in the connected state. current connection state: ") - .append(translate_connection_state(connection_state))))); - return; - } - - auto logger = m_logger; - - logger.log(trace_level::info, std::string("sending data: ").append(data)); - - transport->send(data, [logger, callback](std::exception_ptr exception) - mutable { - try - { - if (exception != nullptr) - { - std::rethrow_exception(exception); - } - callback(nullptr); - } - catch (const std::exception &e) - { - logger.log( - trace_level::errors, - std::string("error sending data: ") - .append(e.what())); - - callback(exception); - } - }); - } - - void connection_impl::stop(std::function<void(std::exception_ptr)> callback) noexcept - { - m_logger.log(trace_level::info, "stopping connection"); - - auto connection = shared_from_this(); - shutdown() - .then([connection, callback](pplx::task<void> prev_task) - { - try - { - prev_task.get(); - } - catch (...) - { - callback(std::current_exception()); - return; - } - - { - // the lock prevents a race where the user calls `stop` on a disconnected connection and calls `start` - // on a different thread at the same time. In this case we must not null out the transport if we are - // not in the `disconnecting` state to not affect the 'start' invocation. - std::lock_guard<std::mutex> lock(connection->m_stop_lock); - if (connection->change_state(connection_state::disconnecting, connection_state::disconnected)) - { - // we do let the exception through (especially the task_canceled exception) - connection->m_transport = nullptr; - } - } - - try - { - connection->m_disconnected(); - } - catch (const std::exception &e) - { - connection->m_logger.log( - trace_level::errors, - std::string("disconnected callback threw an exception: ") - .append(e.what())); - } - catch (...) - { - connection->m_logger.log( - trace_level::errors, - std::string("disconnected callback threw an unknown exception")); - } - - callback(nullptr); - }); - } - - // This function is called from the dtor so you must not use `shared_from_this` here (it will throw). - pplx::task<void> connection_impl::shutdown() - { - { - std::lock_guard<std::mutex> lock(m_stop_lock); - m_logger.log(trace_level::info, "acquired lock in shutdown()"); - - const auto current_state = get_connection_state(); - if (current_state == connection_state::disconnected) - { - return pplx::task_from_result(); - } - - if (current_state == connection_state::disconnecting) - { - // canceled task will be returned if `stop` was called while another `stop` was already in progress. - // This is to prevent from resetting the `m_transport` in the upstream callers because doing so might - // affect the other invocation which is using it. - auto cts = pplx::cancellation_token_source(); - cts.cancel(); - return pplx::create_task([]() noexcept {}, cts.get_token()); - } - - // we request a cancellation of the ongoing start (if any) and wait until it is canceled - m_disconnect_cts.cancel(); - - while (m_start_completed_event.wait(60000) != 0) - { - m_logger.log(trace_level::errors, - "internal error - stopping the connection is still waiting for the start operation to finish which should have already finished or timed out"); - } - - // at this point we are either in the connected or disconnected state. If we are in the disconnected state - // we must break because the transport has already been nulled out. - if (m_connection_state == connection_state::disconnected) - { - return pplx::task_from_result(); - } - - _ASSERTE(m_connection_state == connection_state::connected); - - change_state(connection_state::disconnecting); - } - - pplx::task_completion_event<void> tce; - m_transport->stop([tce](std::exception_ptr exception) - { - if (exception != nullptr) - { - tce.set_exception(exception); - } - else - { - tce.set(); - } - }); - - return pplx::create_task(tce); - } - - connection_state connection_impl::get_connection_state() const noexcept - { - return m_connection_state.load(); - } - - std::string connection_impl::get_connection_id() const noexcept - { - if (m_connection_state.load() == connection_state::connecting) - { - return ""; - } - - return m_connection_id; - } - - void connection_impl::set_message_received(const std::function<void(const std::string&)>& message_received) - { - ensure_disconnected("cannot set the callback when the connection is not in the disconnected state. "); - m_message_received = message_received; - } - - void connection_impl::set_client_config(const signalr_client_config& config) - { - ensure_disconnected("cannot set client config when the connection is not in the disconnected state. "); - m_signalr_client_config = config; - } - - void connection_impl::set_disconnected(const std::function<void()>& disconnected) - { - ensure_disconnected("cannot set the disconnected callback when the connection is not in the disconnected state. "); - m_disconnected = disconnected; - } - - void connection_impl::ensure_disconnected(const std::string& error_message) const - { - const auto state = get_connection_state(); - if (state != connection_state::disconnected) - { - throw signalr_exception( - error_message + "current connection state: " + translate_connection_state(state)); - } - } - - bool connection_impl::change_state(connection_state old_state, connection_state new_state) - { - if (m_connection_state.compare_exchange_strong(old_state, new_state, std::memory_order_seq_cst)) - { - handle_connection_state_change(old_state, new_state); - return true; - } - - return false; - } - - connection_state connection_impl::change_state(connection_state new_state) - { - auto old_state = m_connection_state.exchange(new_state); - if (old_state != new_state) - { - handle_connection_state_change(old_state, new_state); - } - - return old_state; - } - - void connection_impl::handle_connection_state_change(connection_state old_state, connection_state new_state) - { - m_logger.log( - trace_level::state_changes, - translate_connection_state(old_state) - .append(" -> ") - .append(translate_connection_state(new_state))); - - // Words of wisdom (if we decide to add a state_changed callback and invoke it from here): - // "Be extra careful when you add this callback, because this is sometimes being called with the m_stop_lock. - // This could lead to interesting problems.For example, you could run into a segfault if the connection is - // stopped while / after transitioning into the connecting state." - } - - std::string connection_impl::translate_connection_state(connection_state state) - { - switch (state) - { - case connection_state::connecting: - return "connecting"; - case connection_state::connected: - return "connected"; - case connection_state::disconnecting: - return "disconnecting"; - case connection_state::disconnected: - return "disconnected"; - default: - _ASSERTE(false); - return "(unknown)"; - } - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/connection_impl.h b/src/SignalR/clients/cpp/src/signalrclient/connection_impl.h deleted file mode 100644 index b347fed9885bfacbceb3b1e34cbdc8c9ee2ffd2b..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/connection_impl.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <atomic> -#include <mutex> -#include "signalrclient/http_client.h" -#include "signalrclient/trace_level.h" -#include "signalrclient/connection_state.h" -#include "signalrclient/signalr_client_config.h" -#include "web_request_factory.h" -#include "transport_factory.h" -#include "logger.h" -#include "negotiation_response.h" -#include "event.h" - -namespace signalr -{ - // Note: - // Factory methods and private constructors prevent from using this class incorrectly. Because this class - // derives from `std::enable_shared_from_this` the instance has to be owned by a `std::shared_ptr` whenever - // a member method calls `std::shared_from_this()` otherwise the behavior is undefined. Therefore constructors - // are private to disallow creating instances directly and factory methods return `std::shared_ptr<connection_impl>`. - class connection_impl : public std::enable_shared_from_this<connection_impl> - { - public: - static std::shared_ptr<connection_impl> create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer); - - static std::shared_ptr<connection_impl> create(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer, - std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory); - - connection_impl(const connection_impl&) = delete; - - connection_impl& operator=(const connection_impl&) = delete; - - ~connection_impl(); - - void start(std::function<void(std::exception_ptr)> callback) noexcept; - void send(const std::string &data, std::function<void(std::exception_ptr)> callback) noexcept; - void stop(std::function<void(std::exception_ptr)> callback) noexcept; - - connection_state get_connection_state() const noexcept; - std::string get_connection_id() const noexcept; - - void set_message_received(const std::function<void(const std::string&)>& message_received); - void set_disconnected(const std::function<void()>& disconnected); - void set_client_config(const signalr_client_config& config); - - private: - std::string m_base_url; - std::atomic<connection_state> m_connection_state; - logger m_logger; - std::shared_ptr<transport> m_transport; - std::unique_ptr<transport_factory> m_transport_factory; - - std::function<void(const std::string&)> m_message_received; - std::function<void()> m_disconnected; - signalr_client_config m_signalr_client_config; - - pplx::cancellation_token_source m_disconnect_cts; - std::mutex m_stop_lock; - event m_start_completed_event; - std::string m_connection_id; - std::unique_ptr<http_client> m_http_client; - - connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer, - std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory); - - pplx::task<std::shared_ptr<transport>> start_transport(const std::string& url); - pplx::task<void> send_connect_request(const std::shared_ptr<transport>& transport, - const std::string& url, const pplx::task_completion_event<void>& connect_request_tce); - pplx::task<void> start_negotiate(const std::string& url, int redirect_count); - - void process_response(const std::string& response); - - pplx::task<void> shutdown(); - - bool change_state(connection_state old_state, connection_state new_state); - connection_state change_state(connection_state new_state); - void handle_connection_state_change(connection_state old_state, connection_state new_state); - void invoke_message_received(const std::string& message); - - static std::string translate_connection_state(connection_state state); - void ensure_disconnected(const std::string& error_message) const; - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/constants.h b/src/SignalR/clients/cpp/src/signalrclient/constants.h deleted file mode 100644 index 80098b24c88a5a135e648c4d9d64614d26bb0b04..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/constants.h +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#define SIGNALR_VERSION "0.1.0-alpha0" -#define USER_AGENT "SignalR.Client.Cpp/" SIGNALR_VERSION -#define MAX_NEGOTIATE_REDIRECTS 100 diff --git a/src/SignalR/clients/cpp/src/signalrclient/default_http_client.cpp b/src/SignalR/clients/cpp/src/signalrclient/default_http_client.cpp deleted file mode 100644 index 6a56e5c0d7233210b10fc8e33a74f5369a5875de..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/default_http_client.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "default_http_client.h" - -namespace signalr -{ - void default_http_client::send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback) - { - web::http::method method; - if (request.method == http_method::GET) - { - method = U("GET"); - } - else if (request.method == http_method::POST) - { - method = U("POST"); - } - else - { - callback(http_response(), std::make_exception_ptr(std::runtime_error("unknown http method"))); - return; - } - - web::http::http_request http_request; - http_request.set_method(method); - http_request.set_body(request.content); - if (request.headers.size() > 0) - { - web::http::http_headers headers; - for (auto& header : request.headers) - { - headers.add(utility::conversions::to_string_t(header.first), utility::conversions::to_string_t(header.second)); - } - http_request.headers() = headers; - } - - auto milliseconds = std::chrono::milliseconds(request.timeout).count(); - pplx::cancellation_token_source cts; - if (milliseconds != 0) - { - pplx::create_task([milliseconds, cts]() - { - pplx::wait((unsigned int)milliseconds); - cts.cancel(); - }); - } - - web::http::client::http_client client(utility::conversions::to_string_t(url)); - client.request(http_request, cts.get_token()) - .then([callback](pplx::task<web::http::http_response> response_task) - { - try - { - auto http_response = response_task.get(); - auto status_code = http_response.status_code(); - http_response.extract_utf8string() - .then([callback, status_code](std::string response_body) - { - signalr::http_response response; - response.content = response_body; - response.status_code = status_code; - callback(std::move(response), nullptr); - }); - } - catch (...) - { - callback(http_response(), std::current_exception()); - } - }); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/default_http_client.h b/src/SignalR/clients/cpp/src/signalrclient/default_http_client.h deleted file mode 100644 index 6cffb8d37a118c93d091fd2d2d66a04cf301a297..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/default_http_client.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "signalrclient/http_client.h" -#include "cpprest/http_client.h" - -namespace signalr -{ - class default_http_client : public http_client - { - public: - void send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback) override; - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.cpp b/src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.cpp deleted file mode 100644 index e8c683c141b59bbbc52120a7286b05d75b0db17f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "default_websocket_client.h" - -namespace signalr -{ - namespace - { - static web::websockets::client::websocket_client_config create_client_config(const signalr_client_config& signalr_client_config) noexcept - { - auto websocket_client_config = signalr_client_config.get_websocket_client_config(); - websocket_client_config.headers() = signalr_client_config.get_http_headers(); - - return websocket_client_config; - } - } - - default_websocket_client::default_websocket_client(const signalr_client_config& signalr_client_config) noexcept - : m_underlying_client(create_client_config(signalr_client_config)) - { } - - void default_websocket_client::start(std::string url, transfer_format, std::function<void(std::exception_ptr)> callback) - { - m_underlying_client.connect(utility::conversions::to_string_t(url)) - .then([callback](pplx::task<void> task) - { - try - { - task.get(); - callback(nullptr); - } - catch (...) - { - callback(std::current_exception()); - } - }); - } - - void default_websocket_client::stop(std::function<void(std::exception_ptr)> callback) - { - m_underlying_client.close() - .then([callback](pplx::task<void> task) - { - try - { - callback(nullptr); - } - catch (...) - { - callback(std::current_exception()); - } - }); - } - - void default_websocket_client::send(std::string payload, std::function<void(std::exception_ptr)> callback) - { - web::websockets::client::websocket_outgoing_message msg; - msg.set_utf8_message(payload); - m_underlying_client.send(msg) - .then([callback](pplx::task<void> task) - { - try - { - task.get(); - callback(nullptr); - } - catch (...) - { - callback(std::current_exception()); - } - }); - } - - void default_websocket_client::receive(std::function<void(std::string, std::exception_ptr)> callback) - { - m_underlying_client.receive() - .then([callback](pplx::task<web::websockets::client::websocket_incoming_message> task) - { - try - { - auto response = task.get(); - auto msg = response.extract_string().get(); - callback(msg, nullptr); - } - catch (...) - { - callback("", std::current_exception()); - } - }); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.h b/src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.h deleted file mode 100644 index 7da7760a1f5c8e51b22a4d0943b6c617f116a706..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/default_websocket_client.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "cpprest/ws_client.h" -#include "signalrclient/signalr_client_config.h" -#include "signalrclient/websocket_client.h" - -namespace signalr -{ - class default_websocket_client : public websocket_client - { - public: - explicit default_websocket_client(const signalr_client_config& signalr_client_config = {}) noexcept; - - void start(std::string url, transfer_format format, std::function<void(std::exception_ptr)> callback) override; - void stop(std::function<void(std::exception_ptr)> callback) override; - void send(std::string payload, std::function<void(std::exception_ptr)> callback) override; - void receive(std::function<void(std::string, std::exception_ptr)> callback) override; - private: - web::websockets::client::websocket_client m_underlying_client; - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/event.h b/src/SignalR/clients/cpp/src/signalrclient/event.h deleted file mode 100644 index 0a3e7e757b47dad1bee8c418096542f4d41236a3..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/event.h +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <assert.h> -#include <condition_variable> -#include <mutex> - -namespace signalr -{ - class event - { - private: - std::mutex m_lock; - std::condition_variable m_condition; - bool m_signaled; - public: - - static const unsigned int timeout_infinite = 0xFFFFFFFF; - - event() noexcept - : m_signaled(false) - { - } - - void set() - { - std::lock_guard<std::mutex> lock(m_lock); - m_signaled = true; - m_condition.notify_all(); - } - - void reset() - { - std::lock_guard<std::mutex> lock(m_lock); - m_signaled = false; - } - - unsigned int wait(unsigned int timeout) - { - std::unique_lock<std::mutex> lock(m_lock); - if (timeout == event::timeout_infinite) - { - m_condition.wait(lock, [this]() noexcept { return m_signaled; }); - return 0; - } - else - { - const std::chrono::milliseconds period(timeout); - const auto status = m_condition.wait_for(lock, period, [this]() noexcept { return m_signaled; }); - assert(status == m_signaled); - // Return 0 if the wait completed as a result of signaling the event. Otherwise, return timeout_infinite - return status ? 0 : event::timeout_infinite; - } - } - - unsigned int wait() - { - return wait(event::timeout_infinite); - } - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/http_sender.cpp b/src/SignalR/clients/cpp/src/signalrclient/http_sender.cpp deleted file mode 100644 index 4c3cc67d2aff402e73dfbbe1d323667e9a3b1fd9..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/http_sender.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "signalrclient/web_exception.h" -#include "web_request_factory.h" -#include "constants.h" - -namespace signalr -{ - namespace http_sender - { - pplx::task<std::string> get(web_request_factory& request_factory, const std::string& url, - const signalr_client_config& signalr_client_config) - { - auto request = request_factory.create_web_request(url); - request->set_method(utility::conversions::to_utf8string(web::http::methods::GET)); - - request->set_user_agent(USER_AGENT); - request->set_client_config(signalr_client_config); - - return request->get_response().then([](web_response response) - { - if (response.status_code != 200) - { - std::stringstream oss; - oss << "web exception - " << response.status_code << " " << response.reason_phrase; - throw web_exception(oss.str(), response.status_code); - } - - return response.body; - }); - } - - pplx::task<std::string> post(web_request_factory& request_factory, const std::string& url, - const signalr_client_config& signalr_client_config) - { - auto request = request_factory.create_web_request(url); - request->set_method(utility::conversions::to_utf8string(web::http::methods::POST)); - - request->set_user_agent(USER_AGENT); - request->set_client_config(signalr_client_config); - - return request->get_response().then([](web_response response) - { - if (response.status_code != 200) - { - std::stringstream oss; - oss << "web exception - " << response.status_code << " " << response.reason_phrase; - throw web_exception(oss.str(), response.status_code); - } - - return response.body; - }); - } - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/http_sender.h b/src/SignalR/clients/cpp/src/signalrclient/http_sender.h deleted file mode 100644 index 9c6c97298ef33900c08200b60f70826938df4561..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/http_sender.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "pplx/pplxtasks.h" -#include "signalrclient/signalr_client_config.h" -#include "web_request_factory.h" - -namespace signalr -{ - namespace http_sender - { - pplx::task<std::string> get(web_request_factory& request_factory, const std::string& url, - const signalr_client_config& client_config = signalr_client_config{}); - - pplx::task<std::string> post(web_request_factory& request_factory, const std::string& url, - const signalr_client_config& client_config = signalr_client_config{}); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/hub_connection.cpp b/src/SignalR/clients/cpp/src/signalrclient/hub_connection.cpp deleted file mode 100644 index c1f68dab6b4d7915b46341e038ac0528135ada43..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/hub_connection.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "signalrclient/hub_connection.h" -#include "hub_connection_impl.h" -#include "signalrclient/signalr_exception.h" - -namespace signalr -{ - hub_connection::hub_connection(const std::string& url, - trace_level trace_level, std::shared_ptr<log_writer> log_writer) - : m_pImpl(hub_connection_impl::create(url, trace_level, std::move(log_writer))) - {} - - // Do NOT remove this destructor. Letting the compiler generate and inline the default dtor may lead to - // undefinded behavior since we are using an incomplete type. More details here: http://herbsutter.com/gotw/_100/ - hub_connection::~hub_connection() = default; - - void hub_connection::start(std::function<void(std::exception_ptr)> callback) noexcept - { - if (!m_pImpl) - { - callback(std::make_exception_ptr(signalr_exception("start() cannot be called on destructed hub_connection instance"))); - } - - m_pImpl->start(callback); - } - - void hub_connection::stop(std::function<void(std::exception_ptr)> callback) noexcept - { - if (!m_pImpl) - { - callback(std::make_exception_ptr(signalr_exception("stop() cannot be called on destructed hub_connection instance"))); - } - - m_pImpl->stop(callback); - } - - void hub_connection::on(const std::string& event_name, const method_invoked_handler& handler) - { - if (!m_pImpl) - { - throw signalr_exception("on() cannot be called on destructed hub_connection instance"); - } - - return m_pImpl->on(event_name, handler); - } - - void hub_connection::invoke(const std::string& method_name, const web::json::value& arguments, std::function<void(const web::json::value&, std::exception_ptr)> callback) noexcept - { - if (!m_pImpl) - { - callback(web::json::value(), std::make_exception_ptr(signalr_exception("invoke() cannot be called on destructed hub_connection instance"))); - return; - } - - return m_pImpl->invoke(method_name, arguments, callback); - } - - void hub_connection::send(const std::string& method_name, const web::json::value& arguments, std::function<void(std::exception_ptr)> callback) noexcept - { - if (!m_pImpl) - { - callback(std::make_exception_ptr(signalr_exception("send() cannot be called on destructed hub_connection instance"))); - return; - } - - m_pImpl->send(method_name, arguments, callback); - } - - connection_state hub_connection::get_connection_state() const - { - if (!m_pImpl) - { - throw signalr_exception("get_connection_state() cannot be called on destructed hub_connection instance"); - } - - return m_pImpl->get_connection_state(); - } - - std::string hub_connection::get_connection_id() const - { - if (!m_pImpl) - { - throw signalr_exception("get_connection_id() cannot be called on destructed hub_connection instance"); - } - - return m_pImpl->get_connection_id(); - } - - void hub_connection::set_disconnected(const std::function<void()>& disconnected_callback) - { - if (!m_pImpl) - { - throw signalr_exception("set_disconnected() cannot be called on destructed hub_connection instance"); - } - - m_pImpl->set_disconnected(disconnected_callback); - } - - void hub_connection::set_client_config(const signalr_client_config& config) - { - if (!m_pImpl) - { - throw signalr_exception("set_client_config() cannot be called on destructed hub_connection instance"); - } - - m_pImpl->set_client_config(config); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.cpp b/src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.cpp deleted file mode 100644 index b0ea676006cbd18ef40fa9279ee81d39ba83524c..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.cpp +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "hub_connection_impl.h" -#include "signalrclient/hub_exception.h" -#include "trace_log_writer.h" -#include "make_unique.h" -#include "signalrclient/signalr_exception.h" - -using namespace web; - -namespace signalr -{ - // unnamed namespace makes it invisble outside this translation unit - namespace - { - static std::function<void(const json::value&)> create_hub_invocation_callback(const logger& logger, - const std::function<void(const json::value&)>& set_result, - const std::function<void(const std::exception_ptr e)>& set_exception); - } - - std::shared_ptr<hub_connection_impl> hub_connection_impl::create(const std::string& url, trace_level trace_level, - const std::shared_ptr<log_writer>& log_writer) - { - return hub_connection_impl::create(url, trace_level, log_writer, - nullptr, std::make_unique<transport_factory>()); - } - - std::shared_ptr<hub_connection_impl> hub_connection_impl::create(const std::string& url, trace_level trace_level, - const std::shared_ptr<log_writer>& log_writer, std::unique_ptr<http_client> http_client, - std::unique_ptr<transport_factory> transport_factory) - { - auto connection = std::shared_ptr<hub_connection_impl>(new hub_connection_impl(url, trace_level, - log_writer ? log_writer : std::make_shared<trace_log_writer>(), std::move(http_client), std::move(transport_factory))); - - connection->initialize(); - - return connection; - } - - hub_connection_impl::hub_connection_impl(const std::string& url, trace_level trace_level, - const std::shared_ptr<log_writer>& log_writer, std::unique_ptr<http_client> http_client, - std::unique_ptr<transport_factory> transport_factory) - : m_connection(connection_impl::create(url, trace_level, log_writer, - std::move(http_client), std::move(transport_factory))), m_logger(log_writer, trace_level), - m_callback_manager(json::value::parse(_XPLATSTR("{ \"error\" : \"connection went out of scope before invocation result was received\"}"))), - m_disconnected([]() noexcept {}), m_handshakeReceived(false) - { } - - void hub_connection_impl::initialize() - { - // weak_ptr prevents a circular dependency leading to memory leak and other problems - std::weak_ptr<hub_connection_impl> weak_hub_connection = shared_from_this(); - - m_connection->set_message_received([weak_hub_connection](const std::string& message) - { - auto connection = weak_hub_connection.lock(); - if (connection) - { - connection->process_message(message); - } - }); - - m_connection->set_disconnected([weak_hub_connection]() - { - auto connection = weak_hub_connection.lock(); - if (connection) - { - connection->m_handshakeTask.set_exception(signalr_exception("connection closed while handshake was in progress.")); - connection->m_disconnected(); - } - }); - } - - void hub_connection_impl::on(const std::string& event_name, const std::function<void(const json::value &)>& handler) - { - if (event_name.length() == 0) - { - throw std::invalid_argument("event_name cannot be empty"); - } - - auto weak_connection = std::weak_ptr<hub_connection_impl>(shared_from_this()); - auto connection = weak_connection.lock(); - if (connection && connection->get_connection_state() != connection_state::disconnected) - { - throw signalr_exception("can't register a handler if the connection is in a disconnected state"); - } - - if (m_subscriptions.find(event_name) != m_subscriptions.end()) - { - throw signalr_exception( - "an action for this event has already been registered. event name: " + event_name); - } - - m_subscriptions.insert(std::pair<std::string, std::function<void(const json::value &)>> {event_name, handler}); - } - - void hub_connection_impl::start(std::function<void(std::exception_ptr)> callback) noexcept - { - if (m_connection->get_connection_state() != connection_state::disconnected) - { - callback(std::make_exception_ptr(signalr_exception( - "the connection can only be started if it is in the disconnected state"))); - return; - } - - m_connection->set_client_config(m_signalr_client_config); - m_handshakeTask = pplx::task_completion_event<void>(); - m_handshakeReceived = false; - std::weak_ptr<hub_connection_impl> weak_connection = shared_from_this(); - m_connection->start([weak_connection, callback](std::exception_ptr start_exception) - { - auto connection = weak_connection.lock(); - if (!connection) - { - // The connection has been destructed - callback(std::make_exception_ptr(signalr_exception("the hub connection has been deconstructed"))); - return; - } - - if (start_exception) - { - connection->m_connection->stop([start_exception, callback, weak_connection](std::exception_ptr) - { - try - { - auto connection = weak_connection.lock(); - if (!connection) - { - callback(std::make_exception_ptr(signalr_exception("the hub connection has been deconstructed"))); - return; - } - pplx::task<void>(connection->m_handshakeTask).get(); - } - catch (...) {} - - callback(start_exception); - }); - return; - } - - // TODO: Generate this later when we have the protocol abstraction - auto handshake_request = "{\"protocol\":\"json\",\"version\":1}\x1e"; - connection->m_connection->send(handshake_request, [weak_connection, callback](std::exception_ptr exception) - { - auto connection = weak_connection.lock(); - if (!connection) - { - // The connection has been destructed - callback(std::make_exception_ptr(signalr_exception("the hub connection has been deconstructed"))); - return; - } - - if (exception) - { - callback(exception); - return; - } - - try - { - pplx::task<void>(connection->m_handshakeTask).get(); - callback(nullptr); - } - catch (...) - { - auto handshake_exception = std::current_exception(); - connection->m_connection->stop([callback, handshake_exception](std::exception_ptr) - { - callback(handshake_exception); - }); - } - }); - }); - } - - void hub_connection_impl::stop(std::function<void(std::exception_ptr)> callback) noexcept - { - m_callback_manager.clear(json::value::parse(_XPLATSTR("{ \"error\" : \"connection was stopped before invocation result was received\"}"))); - m_connection->stop(callback); - } - - enum MessageType - { - Invocation = 1, - StreamItem, - Completion, - StreamInvocation, - CancelInvocation, - Ping, - Close, - }; - - void hub_connection_impl::process_message(const std::string& response) - { - try - { - auto pos = response.find('\x1e'); - std::size_t lastPos = 0; - while (pos != std::string::npos) - { - auto message = response.substr(lastPos, pos - lastPos); - const auto result = web::json::value::parse(utility::conversions::to_string_t(message)); - - if (!result.is_object()) - { - m_logger.log(trace_level::info, std::string("unexpected response received from the server: ") - .append(message)); - - return; - } - - if (!m_handshakeReceived) - { - if (result.has_field(_XPLATSTR("error"))) - { - auto error = utility::conversions::to_utf8string(result.at(_XPLATSTR("error")).as_string()); - m_logger.log(trace_level::errors, std::string("handshake error: ") - .append(error)); - m_handshakeTask.set_exception(signalr_exception(std::string("Received an error during handshake: ").append(error))); - return; - } - else - { - if (result.has_field(_XPLATSTR("type"))) - { - m_handshakeTask.set_exception(signalr_exception(std::string("Received unexpected message while waiting for the handshake response."))); - } - m_handshakeReceived = true; - m_handshakeTask.set(); - return; - } - } - - auto messageType = result.at(_XPLATSTR("type")); - switch (messageType.as_integer()) - { - case MessageType::Invocation: - { - auto method = utility::conversions::to_utf8string(result.at(_XPLATSTR("target")).as_string()); - auto event = m_subscriptions.find(method); - if (event != m_subscriptions.end()) - { - event->second(result.at(_XPLATSTR("arguments"))); - } - break; - } - case MessageType::StreamInvocation: - // Sent to server only, should not be received by client - throw std::runtime_error("Received unexpected message type 'StreamInvocation'."); - case MessageType::StreamItem: - // TODO - break; - case MessageType::Completion: - { - if (result.has_field(_XPLATSTR("error")) && result.has_field(_XPLATSTR("result"))) - { - // TODO: error - } - invoke_callback(result); - break; - } - case MessageType::CancelInvocation: - // Sent to server only, should not be received by client - throw std::runtime_error("Received unexpected message type 'CancelInvocation'."); - case MessageType::Ping: - // TODO - break; - case MessageType::Close: - // TODO - break; - } - - lastPos = pos + 1; - pos = response.find('\x1e', lastPos); - } - } - catch (const std::exception &e) - { - m_logger.log(trace_level::errors, std::string("error occured when parsing response: ") - .append(e.what()) - .append(". response: ") - .append(response)); - } - } - - bool hub_connection_impl::invoke_callback(const web::json::value& message) - { - auto id = utility::conversions::to_utf8string(message.at(_XPLATSTR("invocationId")).as_string()); - if (!m_callback_manager.invoke_callback(id, message, true)) - { - m_logger.log(trace_level::info, std::string("no callback found for id: ").append(id)); - return false; - } - - return true; - } - - void hub_connection_impl::invoke(const std::string& method_name, const json::value& arguments, std::function<void(const web::json::value&, std::exception_ptr)> callback) noexcept - { - _ASSERTE(arguments.is_array()); - - const auto callback_id = m_callback_manager.register_callback( - create_hub_invocation_callback(m_logger, [callback](const json::value& result) { callback(result, nullptr); }, - [callback](const std::exception_ptr e) { callback(json::value(), e); })); - - invoke_hub_method(method_name, arguments, callback_id, nullptr, - [callback](const std::exception_ptr e){ callback(json::value(), e); }); - } - - void hub_connection_impl::send(const std::string& method_name, const json::value& arguments, std::function<void(std::exception_ptr)> callback) noexcept - { - _ASSERTE(arguments.is_array()); - - invoke_hub_method(method_name, arguments, "", - [callback]() { callback(nullptr); }, - [callback](const std::exception_ptr e){ callback(e); }); - } - - void hub_connection_impl::invoke_hub_method(const std::string& method_name, const json::value& arguments, - const std::string& callback_id, std::function<void()> set_completion, std::function<void(const std::exception_ptr)> set_exception) noexcept - { - json::value request; - request[_XPLATSTR("type")] = json::value(1); - if (!callback_id.empty()) - { - request[_XPLATSTR("invocationId")] = json::value::string(utility::conversions::to_string_t(callback_id)); - } - request[_XPLATSTR("target")] = json::value::string(utility::conversions::to_string_t(method_name)); - request[_XPLATSTR("arguments")] = arguments; - - // weak_ptr prevents a circular dependency leading to memory leak and other problems - auto weak_hub_connection = std::weak_ptr<hub_connection_impl>(shared_from_this()); - - m_connection->send(utility::conversions::to_utf8string(request.serialize() + _XPLATSTR('\x1e')), [set_completion, set_exception, weak_hub_connection, callback_id](std::exception_ptr exception) - { - if (exception) - { - set_exception(exception); - auto hub_connection = weak_hub_connection.lock(); - if (hub_connection) - { - hub_connection->m_callback_manager.remove_callback(callback_id); - } - } - else - { - if (callback_id.empty()) - { - // complete nonBlocking call - set_completion(); - } - } - }); - } - - connection_state hub_connection_impl::get_connection_state() const noexcept - { - return m_connection->get_connection_state(); - } - - std::string hub_connection_impl::get_connection_id() const - { - return m_connection->get_connection_id(); - } - - void hub_connection_impl::set_client_config(const signalr_client_config& config) - { - m_signalr_client_config = config; - m_connection->set_client_config(config); - } - - void hub_connection_impl::set_disconnected(const std::function<void()>& disconnected) - { - m_disconnected = disconnected; - } - - // unnamed namespace makes it invisble outside this translation unit - namespace - { - static std::function<void(const json::value&)> create_hub_invocation_callback(const logger& logger, - const std::function<void(const json::value&)>& set_result, - const std::function<void(const std::exception_ptr)>& set_exception) - { - return [logger, set_result, set_exception](const json::value& message) - { - if (message.has_field(_XPLATSTR("result"))) - { - set_result(message.at(_XPLATSTR("result"))); - } - else if (message.has_field(_XPLATSTR("error"))) - { - set_exception( - std::make_exception_ptr( - hub_exception(utility::conversions::to_utf8string(message.at(_XPLATSTR("error")).serialize())))); - } - else - { - set_result(json::value::value()); - } - }; - } - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.h b/src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.h deleted file mode 100644 index 44c42b4614ac3dc386f851418471769a251a4bd3..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/hub_connection_impl.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <unordered_map> -#include "connection_impl.h" -#include "callback_manager.h" -#include "case_insensitive_comparison_utils.h" - -using namespace web; - -namespace signalr -{ - // Note: - // Factory methods and private constructors prevent from using this class incorrectly. Because this class - // derives from `std::enable_shared_from_this` the instance has to be owned by a `std::shared_ptr` whenever - // a member method calls `std::shared_from_this()` otherwise the behavior is undefined. Therefore constructors - // are private to disallow creating instances directly and factory methods return `std::shared_ptr<connection_impl>`. - class hub_connection_impl : public std::enable_shared_from_this<hub_connection_impl> - { - public: - static std::shared_ptr<hub_connection_impl> create(const std::string& url, trace_level trace_level, - const std::shared_ptr<log_writer>& log_writer); - - static std::shared_ptr<hub_connection_impl> create(const std::string& url, trace_level trace_level, - const std::shared_ptr<log_writer>& log_writer, std::unique_ptr<http_client> http_client, - std::unique_ptr<transport_factory> transport_factory); - - hub_connection_impl(const hub_connection_impl&) = delete; - hub_connection_impl& operator=(const hub_connection_impl&) = delete; - - void on(const std::string& event_name, const std::function<void(const json::value &)>& handler); - - void invoke(const std::string& method_name, const json::value& arguments, std::function<void(const json::value&, std::exception_ptr)> callback) noexcept; - void send(const std::string& method_name, const json::value& arguments, std::function<void(std::exception_ptr)> callback) noexcept; - - void start(std::function<void(std::exception_ptr)> callback) noexcept; - void stop(std::function<void(std::exception_ptr)> callback) noexcept; - - connection_state get_connection_state() const noexcept; - std::string get_connection_id() const; - - void set_client_config(const signalr_client_config& config); - void set_disconnected(const std::function<void()>& disconnected); - - private: - hub_connection_impl(const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer, - std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory); - - std::shared_ptr<connection_impl> m_connection; - logger m_logger; - callback_manager m_callback_manager; - std::unordered_map<std::string, std::function<void(const json::value &)>, case_insensitive_hash, case_insensitive_equals> m_subscriptions; - bool m_handshakeReceived; - pplx::task_completion_event<void> m_handshakeTask; - std::function<void()> m_disconnected; - signalr_client_config m_signalr_client_config; - - void initialize(); - - void process_message(const std::string& message); - - void invoke_hub_method(const std::string& method_name, const json::value& arguments, const std::string& callback_id, - std::function<void()> set_completion, std::function<void(const std::exception_ptr)> set_exception) noexcept; - bool invoke_callback(const web::json::value& message); - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/logger.cpp b/src/SignalR/clients/cpp/src/signalrclient/logger.cpp deleted file mode 100644 index c1226bff43a8ad0dc0f8b37432a37bc9d9643a9d..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/logger.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "logger.h" -#include "cpprest/asyncrt_utils.h" -#include <iomanip> - -namespace signalr -{ - logger::logger(const std::shared_ptr<log_writer>& log_writer, trace_level trace_level) noexcept - : m_log_writer(log_writer), m_trace_level(trace_level) - { } - - void logger::log(trace_level level, const std::string& entry) const - { - if ((level & m_trace_level) != trace_level::none) - { - try - { - std::stringstream os; - os << utility::conversions::to_utf8string(utility::datetime::utc_now().to_string(utility::datetime::date_format::ISO_8601)) << " [" - << std::left << std::setw(12) << translate_trace_level(level) << "] "<< entry << std::endl; - m_log_writer->write(os.str()); - } - catch (const std::exception &e) - { - std::cerr << "error occurred when logging: " << e.what() - << std::endl << " entry: " << entry << std::endl; - } - catch (...) - { - std::cerr << "unknown error occurred when logging" << std::endl << " entry: " << entry << std::endl; - } - } - } - - std::string logger::translate_trace_level(trace_level trace_level) - { - switch (trace_level) - { - case signalr::trace_level::messages: - return "message"; - case signalr::trace_level::state_changes: - return "state change"; - case signalr::trace_level::events: - return "event"; - case signalr::trace_level::errors: - return "error"; - case signalr::trace_level::info: - return "info"; - default: - _ASSERTE(false); - return "(unknown)"; - } - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/logger.h b/src/SignalR/clients/cpp/src/signalrclient/logger.h deleted file mode 100644 index 4bec153d44c16f1020dbe0c0891a0ce2a381b6bd..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/logger.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <memory> -#include "signalrclient/trace_level.h" -#include "signalrclient/log_writer.h" - -namespace signalr -{ - class logger - { - public: - logger(const std::shared_ptr<log_writer>& log_writer, trace_level trace_level) noexcept; - - void log(trace_level level, const std::string& entry) const; - - private: - std::shared_ptr<log_writer> m_log_writer; - trace_level m_trace_level; - - static std::string translate_trace_level(trace_level trace_level); - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/make_unique.h b/src/SignalR/clients/cpp/src/signalrclient/make_unique.h deleted file mode 100644 index 2e8df5cfd8cc98a3063cbc7f61c3d547116897d2..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/make_unique.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#if defined (__GNUC__) - -#include <memory> - -namespace std -{ - template<typename T, typename... Args> - std::unique_ptr<T> make_unique(Args&&... args) - { - return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); - } -} -#endif diff --git a/src/SignalR/clients/cpp/src/signalrclient/negotiate.cpp b/src/SignalR/clients/cpp/src/signalrclient/negotiate.cpp deleted file mode 100644 index a38d1e31e3a9faf2da3afd4a8199ee96a4adc662..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/negotiate.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "negotiate.h" -#include "url_builder.h" -#include "signalrclient/signalr_exception.h" - -namespace signalr -{ - namespace negotiate - { - pplx::task<negotiation_response> negotiate(http_client& client, const std::string& base_url, - const signalr_client_config& config) - { - auto negotiate_url = url_builder::build_negotiate(base_url); - - pplx::task_completion_event<negotiation_response> tce; - - // TODO: signalr_client_config - http_request request; - request.method = http_method::POST; - - for (auto& header : config.get_http_headers()) - { - request.headers.insert(std::make_pair(utility::conversions::to_utf8string(header.first), utility::conversions::to_utf8string(header.second))); - } - - client.send(negotiate_url, request, [tce](http_response http_response, std::exception_ptr exception) - { - if (exception != nullptr) - { - tce.set_exception(exception); - return; - } - - if (http_response.status_code != 200) - { - tce.set_exception(signalr_exception("negotiate failed with status code " + std::to_string(http_response.status_code))); - return; - } - - try - { - auto negotiation_response_json = web::json::value::parse(utility::conversions::to_string_t(http_response.content)); - - negotiation_response response; - - if (negotiation_response_json.has_field(_XPLATSTR("error"))) - { - response.error = utility::conversions::to_utf8string(negotiation_response_json[_XPLATSTR("error")].as_string()); - tce.set(std::move(response)); - return; - } - - if (negotiation_response_json.has_field(_XPLATSTR("connectionId"))) - { - response.connectionId = utility::conversions::to_utf8string(negotiation_response_json[_XPLATSTR("connectionId")].as_string()); - } - - if (negotiation_response_json.has_field(_XPLATSTR("availableTransports"))) - { - for (auto transportData : negotiation_response_json[_XPLATSTR("availableTransports")].as_array()) - { - available_transport transport; - transport.transport = utility::conversions::to_utf8string(transportData[_XPLATSTR("transport")].as_string()); - - for (auto format : transportData[_XPLATSTR("transferFormats")].as_array()) - { - transport.transfer_formats.push_back(utility::conversions::to_utf8string(format.as_string())); - } - - response.availableTransports.push_back(transport); - } - } - - if (negotiation_response_json.has_field(_XPLATSTR("url"))) - { - response.url = utility::conversions::to_utf8string(negotiation_response_json[_XPLATSTR("url")].as_string()); - - if (negotiation_response_json.has_field(_XPLATSTR("accessToken"))) - { - response.accessToken = utility::conversions::to_utf8string(negotiation_response_json[_XPLATSTR("accessToken")].as_string()); - } - } - - if (negotiation_response_json.has_field(_XPLATSTR("ProtocolVersion"))) - { - tce.set_exception(signalr_exception("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.")); - } - - tce.set(std::move(response)); - } - catch (...) - { - tce.set_exception(std::current_exception()); - } - }); - - return pplx::create_task(tce); - } - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/negotiate.h b/src/SignalR/clients/cpp/src/signalrclient/negotiate.h deleted file mode 100644 index a627e533d78cc30e56298526b813f331149e78a3..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/negotiate.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "signalrclient/signalr_client_config.h" -#include "signalrclient/transport_type.h" -#include "web_request_factory.h" -#include "negotiation_response.h" -#include "signalrclient/http_client.h" - -namespace signalr -{ - namespace negotiate - { - pplx::task<negotiation_response> negotiate(http_client& client, const std::string& base_url, - const signalr_client_config& signalr_client_config = signalr::signalr_client_config{}); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/negotiation_response.cpp b/src/SignalR/clients/cpp/src/signalrclient/negotiation_response.cpp deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/SignalR/clients/cpp/src/signalrclient/negotiation_response.h b/src/SignalR/clients/cpp/src/signalrclient/negotiation_response.h deleted file mode 100644 index 56fa8f7bd4ca2be6af29a7f045cc17b12c4274db..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/negotiation_response.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -namespace signalr -{ - struct available_transport - { - std::string transport; - std::vector<std::string> transfer_formats; - }; - - struct negotiation_response - { - std::string connectionId; - std::vector<available_transport> availableTransports; - std::string url; - std::string accessToken; - std::string error; - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/signalr_client_config.cpp b/src/SignalR/clients/cpp/src/signalrclient/signalr_client_config.cpp deleted file mode 100644 index 4700fd87865f36c6cd72c95daa84ed8411f1cdd3..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/signalr_client_config.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "signalrclient/signalr_client_config.h" -#include "cpprest/http_client.h" -#include "cpprest/ws_client.h" - -namespace signalr -{ - void signalr_client_config::set_proxy(const web::web_proxy &proxy) - { - m_http_client_config.set_proxy(proxy); - m_websocket_client_config.set_proxy(proxy); - } - - void signalr_client_config::set_credentials(const web::credentials &credentials) - { - m_http_client_config.set_credentials(credentials); - m_websocket_client_config.set_credentials(credentials); - } - - web::http::client::http_client_config signalr_client_config::get_http_client_config() const - { - return m_http_client_config; - } - - void signalr_client_config::set_http_client_config(const web::http::client::http_client_config& http_client_config) - { - m_http_client_config = http_client_config; - } - - web::websockets::client::websocket_client_config signalr_client_config::get_websocket_client_config() const noexcept - { - return m_websocket_client_config; - } - - void signalr_client_config::set_websocket_client_config(const web::websockets::client::websocket_client_config& websocket_client_config) - { - m_websocket_client_config = websocket_client_config; - } - - web::http::http_headers signalr_client_config::get_http_headers() const noexcept - { - return m_http_headers; - } - - void signalr_client_config::set_http_headers(const web::http::http_headers& http_headers) - { - m_http_headers = http_headers; - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/stdafx.cpp b/src/SignalR/clients/cpp/src/signalrclient/stdafx.cpp deleted file mode 100644 index 4ddb0135bdeb0f9ea0d9e7b7d1a3747d4e0925c5..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/stdafx.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" \ No newline at end of file diff --git a/src/SignalR/clients/cpp/src/signalrclient/stdafx.h b/src/SignalR/clients/cpp/src/signalrclient/stdafx.h deleted file mode 100644 index e53577816494ed5666d5ffa34a91a245b3914572..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/stdafx.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#ifdef _WIN32 // used in the default log writer and to build the dll - -// prevents from defining min/max macros that conflict with std::min()/std::max() functions -#define NOMINMAX - -#include <SDKDDKVer.h> - -#define WIN32_LEAN_AND_MEAN - -#include <windows.h> - -#endif - -#include <functional> -#include <unordered_map> -#include "cpprest/details/basic_types.h" -#include "cpprest/json.h" -#include "pplx/pplxtasks.h" \ No newline at end of file diff --git a/src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.cpp b/src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.cpp deleted file mode 100644 index 466c79324ed329a70863f754ccab6b85d6a64cfc..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "trace_log_writer.h" - -namespace signalr -{ - void trace_log_writer::write(const std::string &entry) - { -#ifdef _WIN32 - // OutputDebugString is thread safe - OutputDebugStringA(entry.c_str()); -#else - // Note: there is no data race for standard output streams in C++ 11 but the results - // might be garbled when the method is called concurrently from multiple threads -#ifdef _UTF16_STRINGS - std::wclog << entry; -#else - std::clog << entry; -#endif // _UTF16_STRINGS - -#endif // _MS_WINDOWS - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.h b/src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.h deleted file mode 100644 index f944fa1e70dfd577597f0ca8b2408495416783af..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/trace_log_writer.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "signalrclient/log_writer.h" - -namespace signalr -{ - class trace_log_writer : public log_writer - { - public: - void __cdecl write(const std::string &entry) override; - }; -} \ No newline at end of file diff --git a/src/SignalR/clients/cpp/src/signalrclient/transport.cpp b/src/SignalR/clients/cpp/src/signalrclient/transport.cpp deleted file mode 100644 index 4f235e16f4380c44a31be5022bd72340a77f57ad..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/transport.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "transport.h" -#include "connection_impl.h" - -namespace signalr -{ - transport::transport(const logger& logger) - : m_logger(logger) - {} - - // Do NOT remove this destructor. Letting the compiler generate and inline the default dtor may lead to - // undefinded behavior since we are using an incomplete type. More details here: http://herbsutter.com/gotw/_100/ - transport::~transport() - { } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/transport.h b/src/SignalR/clients/cpp/src/signalrclient/transport.h deleted file mode 100644 index cde0ed1e8e2ff56b55e73ef5270aa444cf561bb6..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/transport.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "pplx/pplxtasks.h" -#include "signalrclient/transport_type.h" -#include "signalrclient/transfer_format.h" -#include "logger.h" - -namespace signalr -{ - class transport - { - public: - virtual transport_type get_transport_type() const = 0; - - virtual ~transport(); - - virtual void start(const std::string& url, transfer_format format, std::function<void(std::exception_ptr)> callback) noexcept = 0; - virtual void stop(std::function<void(std::exception_ptr)> callback) noexcept = 0; - virtual void on_close(std::function<void(std::exception_ptr)> callback) = 0; - - virtual void send(std::string payload, std::function<void(std::exception_ptr)> callback) noexcept = 0; - - virtual void on_receive(std::function<void(std::string, std::exception_ptr)> callback) = 0; - - protected: - transport(const logger& logger); - - logger m_logger; - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/transport_factory.cpp b/src/SignalR/clients/cpp/src/signalrclient/transport_factory.cpp deleted file mode 100644 index 8c74b6aeed282524426666b2acfddf029f8ebe1f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/transport_factory.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "transport_factory.h" -#include "websocket_transport.h" - -namespace signalr -{ - std::shared_ptr<transport> transport_factory::create_transport(transport_type transport_type, const logger& logger, - const signalr_client_config& signalr_client_config) - { - if (transport_type == signalr::transport_type::websockets) - { - return websocket_transport::create( - [signalr_client_config](){ return std::make_shared<default_websocket_client>(signalr_client_config); }, - logger); - } - - throw std::runtime_error("not implemented"); - } - - transport_factory::~transport_factory() - { } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/transport_factory.h b/src/SignalR/clients/cpp/src/signalrclient/transport_factory.h deleted file mode 100644 index 3d55b83a92855d1510b9165afdba0f6b4e21a77c..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/transport_factory.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <memory> -#include "signalrclient/signalr_client_config.h" -#include "signalrclient/transport_type.h" -#include "transport.h" - -namespace signalr -{ - class transport_factory - { - public: - virtual std::shared_ptr<transport> create_transport(transport_type transport_type, const logger& logger, - const signalr_client_config& signalr_client_config); - - virtual ~transport_factory(); - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/url_builder.cpp b/src/SignalR/clients/cpp/src/signalrclient/url_builder.cpp deleted file mode 100644 index 66a1512f910c1b9cbbbbcef1fcdd491cf52a6a4a..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/url_builder.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "cpprest/http_client.h" -#include "signalrclient/transport_type.h" - -namespace signalr -{ - namespace url_builder - { - web::uri_builder &convert_to_websocket_url(web::uri_builder &builder, transport_type transport) - { - if (transport == transport_type::websockets) - { - if (builder.scheme() == _XPLATSTR("https")) - { - builder.set_scheme(utility::conversions::to_string_t("wss")); - } - else - { - builder.set_scheme(utility::conversions::to_string_t("ws")); - } - } - - return builder; - } - - web::uri_builder build_uri(const std::string& base_url, const std::string& command, const std::string& query_string) - { - web::uri_builder builder(utility::conversions::to_string_t(base_url)); - builder.append_path(utility::conversions::to_string_t(command)); - return builder.append_query(utility::conversions::to_string_t(query_string)); - } - - web::uri_builder build_uri(const std::string& base_url, const std::string& command) - { - web::uri_builder builder(utility::conversions::to_string_t(base_url)); - return builder.append_path(utility::conversions::to_string_t(command)); - } - - std::string build_negotiate(const std::string& base_url) - { - return utility::conversions::to_utf8string(build_uri(base_url, "negotiate").to_string()); - } - - std::string build_connect(const std::string& base_url, transport_type transport, const std::string& query_string) - { - auto builder = build_uri(base_url, "", query_string); - return utility::conversions::to_utf8string(convert_to_websocket_url(builder, transport).to_string()); - } - - std::string build_start(const std::string& base_url, const std::string &query_string) - { - return utility::conversions::to_utf8string(build_uri(base_url, "", query_string).to_string()); - } - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/url_builder.h b/src/SignalR/clients/cpp/src/signalrclient/url_builder.h deleted file mode 100644 index f165e67ca51e9751f63f3b7d3b83fae3a7ad8413..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/url_builder.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "cpprest/http_client.h" -#include "signalrclient/transport_type.h" - -namespace signalr -{ - namespace url_builder - { - std::string build_negotiate(const std::string& base_url); - std::string build_connect(const std::string& base_url, transport_type transport, const std::string& query_string); - std::string build_start(const std::string& base_url, const std::string& query_string); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/web_request.cpp b/src/SignalR/clients/cpp/src/signalrclient/web_request.cpp deleted file mode 100644 index abe4685638420bbb082307ce5f559ff01f8d2755..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/web_request.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "cpprest/http_client.h" -#include "web_request.h" - -namespace signalr -{ - web_request::web_request(const std::string& url) - : m_url(url) - { } - - void web_request::set_method(const std::string &method) - { - m_request.set_method(utility::conversions::to_string_t(method)); - } - - void web_request::set_user_agent(const std::string &user_agent_string) - { - m_user_agent_string = user_agent_string; - } - - void web_request::set_client_config(const signalr_client_config& signalr_client_config) - { - m_signalr_client_config = signalr_client_config; - } - - pplx::task<web_response> web_request::get_response() - { - web::http::client::http_client client(utility::conversions::to_string_t(m_url), m_signalr_client_config.get_http_client_config()); - - m_request.headers() = m_signalr_client_config.get_http_headers(); - if (!m_user_agent_string.empty()) - { - m_request.headers()[_XPLATSTR("User-Agent")] = utility::conversions::to_string_t(m_user_agent_string); - } - - return client.request(m_request) - .then([](web::http::http_response response) - { - return web_response - { - response.status_code(), - utility::conversions::to_utf8string(response.reason_phrase()), - response.extract_string().then([](const utility::string_t& body) - { - return utility::conversions::to_utf8string(body); - }) - }; - }); - } - - web_request::~web_request() = default; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/web_request.h b/src/SignalR/clients/cpp/src/signalrclient/web_request.h deleted file mode 100644 index 4f02397c8d0b0d2eb3e04efe505147044b16a074..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/web_request.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "web_response.h" -#include "signalrclient/signalr_client_config.h" - -namespace signalr -{ - class web_request - { - public: - explicit web_request(const std::string& url); - - virtual void set_method(const std::string &method); - virtual void set_user_agent(const std::string &user_agent_string); - virtual void set_client_config(const signalr_client_config& signalr_client_config); - - virtual pplx::task<web_response> get_response(); - - web_request& operator=(const web_request&) = delete; - - virtual ~web_request(); - - private: - const std::string m_url; - web::http::http_request m_request; - std::string m_user_agent_string; - signalr_client_config m_signalr_client_config; - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/web_request_factory.cpp b/src/SignalR/clients/cpp/src/signalrclient/web_request_factory.cpp deleted file mode 100644 index 234507cc6038e923f916e437765936dbdd54a4f6..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/web_request_factory.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "web_request_factory.h" -#include "make_unique.h" - -namespace signalr -{ - std::unique_ptr<web_request> web_request_factory::create_web_request(const std::string& url) - { - return std::make_unique<web_request>(url); - } - - web_request_factory::~web_request_factory() - {} -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/web_request_factory.h b/src/SignalR/clients/cpp/src/signalrclient/web_request_factory.h deleted file mode 100644 index fe0e5542e7d00fe19fe958fa2e81c8c15b74ac62..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/web_request_factory.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "web_request.h" - -namespace signalr -{ - class web_request_factory - { - public: - virtual std::unique_ptr<web_request> create_web_request(const std::string& url); - - virtual ~web_request_factory(); - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/web_response.h b/src/SignalR/clients/cpp/src/signalrclient/web_response.h deleted file mode 100644 index 2ea3b235a7e5efae099c1a2d8bd9cbba5c6fb6a8..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/web_response.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "pplx/pplxtasks.h" - -namespace signalr -{ - struct web_response - { - unsigned short status_code; - std::string reason_phrase; - pplx::task<std::string> body; - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/websocket_transport.cpp b/src/SignalR/clients/cpp/src/signalrclient/websocket_transport.cpp deleted file mode 100644 index b00e677dcbe69b96994d1bed22581c03f2e3c5a8..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/websocket_transport.cpp +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "websocket_transport.h" -#include "logger.h" -#include "signalrclient/signalr_exception.h" -#include <future> - -namespace signalr -{ - std::shared_ptr<transport> websocket_transport::create(const std::function<std::shared_ptr<websocket_client>()>& websocket_client_factory, - const logger& logger) - { - return std::shared_ptr<transport>( - new websocket_transport(websocket_client_factory, logger)); - } - - websocket_transport::websocket_transport(const std::function<std::shared_ptr<websocket_client>()>& websocket_client_factory, - const logger& logger) - : transport(logger), m_websocket_client_factory(websocket_client_factory), m_close_callback([](std::exception_ptr) {}), - m_process_response_callback([](std::string, std::exception_ptr) {}) - { - // we use this cts to check if the receive loop is running so it should be - // initially cancelled to indicate that the receive loop is not running - m_receive_loop_cts.cancel(); - } - - websocket_transport::~websocket_transport() - { - try - { - pplx::task_completion_event<void> event; - stop([event](std::exception_ptr) { event.set(); }); - pplx::create_task(event).get(); - } - catch (...) // must not throw from the destructor - {} - } - - transport_type websocket_transport::get_transport_type() const noexcept - { - return transport_type::websockets; - } - - // Note that the connection assumes that the error callback won't be fired when the result is being processed. This - // may no longer be true when we replace the `receive_loop` with "on_message_received" and "on_close" events if they - // can be fired on different threads in which case we will have to lock before setting groups token and message id. - void websocket_transport::receive_loop(pplx::cancellation_token_source cts) - { - auto this_transport = shared_from_this(); - auto logger = this_transport->m_logger; - - // Passing the `std::weak_ptr<websocket_transport>` prevents from a memory leak where we would capture the shared_ptr to - // the transport in the continuation lambda and as a result as long as the loop runs the ref count would never get to - // zero. Now we capture the weak pointer and get the shared pointer only when the continuation runs so the ref count is - // incremented when the shared pointer is acquired and then decremented when it goes out of scope of the continuation. - auto weak_transport = std::weak_ptr<websocket_transport>(this_transport); - - auto websocket_client = this_transport->safe_get_websocket_client(); - - // There are two cases when we exit the loop. The first case is implicit - we pass the cancellation_token - // to `then` (note this is after the lambda body) and if the token is cancelled the continuation will not - // run at all. The second - explicit - case happens if the token gets cancelled after the continuation has - // been started in which case we just stop the loop by not scheduling another receive task. - websocket_client->receive([weak_transport, cts, logger, websocket_client](std::string message, std::exception_ptr exception) - { - if (exception != nullptr) - { - try - { - std::rethrow_exception(exception); - } - catch (const std::exception & e) - { - logger.log( - trace_level::errors, - std::string("[websocket transport] error receiving response from websocket: ") - .append(e.what())); - } - catch (...) - { - logger.log( - trace_level::errors, - std::string("[websocket transport] unknown error occurred when receiving response from websocket")); - - exception = std::make_exception_ptr(signalr_exception("unknown error")); - } - - cts.cancel(); - - std::promise<void> promise; - websocket_client->stop([&promise](std::exception_ptr exception) - { - if (exception != nullptr) - { - promise.set_exception(exception); - } - else - { - promise.set_value(); - } - }); - - try - { - promise.get_future().get(); - } - // We prefer the outer exception bubbling up to the user - // REVIEW: log here? - catch (...) {} - - auto transport = weak_transport.lock(); - if (transport) - { - transport->m_close_callback(exception); - } - - return; - } - - auto transport = weak_transport.lock(); - if (transport) - { - transport->m_process_response_callback(message, nullptr); - - if (!cts.get_token().is_canceled()) - { - transport->receive_loop(cts); - } - } - }); - } - - std::shared_ptr<websocket_client> websocket_transport::safe_get_websocket_client() - { - { - const std::lock_guard<std::mutex> lock(m_websocket_client_lock); - auto websocket_client = m_websocket_client; - - return websocket_client; - } - } - - void websocket_transport::start(const std::string& url, transfer_format format, std::function<void(std::exception_ptr)> callback) noexcept - { - web::uri uri(utility::conversions::to_string_t(url)); - _ASSERTE(uri.scheme() == _XPLATSTR("ws") || uri.scheme() == _XPLATSTR("wss")); - - { - std::lock_guard<std::mutex> stop_lock(m_start_stop_lock); - - if (!m_receive_loop_cts.get_token().is_canceled()) - { - callback(std::make_exception_ptr(signalr_exception("transport already connected"))); - return; - } - - m_logger.log(trace_level::info, - std::string("[websocket transport] connecting to: ") - .append(url)); - - auto websocket_client = m_websocket_client_factory(); - - { - std::lock_guard<std::mutex> client_lock(m_websocket_client_lock); - m_websocket_client = websocket_client; - } - - pplx::cancellation_token_source receive_loop_cts; - - auto transport = shared_from_this(); - - websocket_client->start(url, format, [transport, receive_loop_cts, callback](std::exception_ptr exception) - { - try - { - if (exception != nullptr) - { - std::rethrow_exception(exception); - } - transport->receive_loop(receive_loop_cts); - callback(nullptr); - } - catch (const std::exception & e) - { - transport->m_logger.log( - trace_level::errors, - std::string("[websocket transport] exception when connecting to the server: ") - .append(e.what())); - - receive_loop_cts.cancel(); - callback(std::current_exception()); - } - }); - - m_receive_loop_cts = receive_loop_cts; - } - } - - void websocket_transport::stop(std::function<void(std::exception_ptr)> callback) noexcept - { - std::shared_ptr<websocket_client> websocket_client = nullptr; - - { - std::lock_guard<std::mutex> lock(m_start_stop_lock); - - if (m_receive_loop_cts.get_token().is_canceled()) - { - callback(nullptr); - return; - } - - m_receive_loop_cts.cancel(); - - websocket_client = safe_get_websocket_client(); - } - - auto logger = m_logger; - auto close_callback = m_close_callback; - - websocket_client->stop([logger, callback, close_callback](std::exception_ptr exception) - { - try - { - if (exception != nullptr) - { - std::rethrow_exception(exception); - } - callback(nullptr); - } - catch (const std::exception & e) - { - logger.log( - trace_level::errors, - std::string("[websocket transport] exception when closing websocket: ") - .append(e.what())); - - callback(exception); - } - - close_callback(exception); - }); - } - - void websocket_transport::on_close(std::function<void(std::exception_ptr)> callback) - { - m_close_callback = callback; - } - - void websocket_transport::on_receive(std::function<void(std::string, std::exception_ptr)> callback) - { - m_process_response_callback = callback; - } - - void websocket_transport::send(std::string payload, std::function<void(std::exception_ptr)> callback) noexcept - { - safe_get_websocket_client()->send(payload, [callback](std::exception_ptr exception) - { - if (exception != nullptr) - { - callback(exception); - } - else - { - callback(nullptr); - } - }); - } -} diff --git a/src/SignalR/clients/cpp/src/signalrclient/websocket_transport.h b/src/SignalR/clients/cpp/src/signalrclient/websocket_transport.h deleted file mode 100644 index 45ef6b41e1ea67c20b0933f5d7e69f6569991673..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclient/websocket_transport.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "cpprest/ws_client.h" -#include "url_builder.h" -#include "transport.h" -#include "logger.h" -#include "default_websocket_client.h" -#include "connection_impl.h" - -namespace signalr -{ - class websocket_transport : public transport, public std::enable_shared_from_this<websocket_transport> - { - public: - static std::shared_ptr<transport> create(const std::function<std::shared_ptr<websocket_client>()>& websocket_client_factory, - const logger& logger); - - ~websocket_transport(); - - websocket_transport(const websocket_transport&) = delete; - - websocket_transport& operator=(const websocket_transport&) = delete; - - transport_type get_transport_type() const noexcept override; - - void start(const std::string& url, transfer_format format, std::function<void(std::exception_ptr)> callback) noexcept override; - void stop(std::function<void(std::exception_ptr)> callback) noexcept override; - void on_close(std::function<void(std::exception_ptr)> callback) override; - - void send(std::string payload, std::function<void(std::exception_ptr)> callback) noexcept override; - - void on_receive(std::function<void(std::string, std::exception_ptr)>) override; - - private: - websocket_transport(const std::function<std::shared_ptr<websocket_client>()>& websocket_client_factory, - const logger& logger); - - std::function<std::shared_ptr<websocket_client>()> m_websocket_client_factory; - std::shared_ptr<websocket_client> m_websocket_client; - std::mutex m_websocket_client_lock; - std::mutex m_start_stop_lock; - std::function<void(std::string, std::exception_ptr)> m_process_response_callback; - std::function<void(std::exception_ptr)> m_close_callback; - - pplx::cancellation_token_source m_receive_loop_cts; - - void receive_loop(pplx::cancellation_token_source cts); - - std::shared_ptr<websocket_client> safe_get_websocket_client(); - }; -} diff --git a/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj b/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj deleted file mode 100644 index 8639ac5c6d29d2e2907d8bc831cfb318245a1b04..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj +++ /dev/null @@ -1,140 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="..\..\..\..\Build\SignalRClient.Build.Settings" /> - <PropertyGroup Label="Globals"> - <ProjectGuid>{18377AE8-E372-40CE-94FD-7F65008D39A3}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>signalrclient</RootNamespace> - <ProjectName>signalrclientdll</ProjectName> - <TargetName>$(SignalrClientTargetName)</TargetName> - <SolutionDir Condition="$(SolutionDir) == '' Or '$(SolutionDir)' == '*Undefined*'">..\..\..\..\</SolutionDir> - <OutDir Condition="'$(OutDir)' == ''">$(SolutionDir)bin\$(SubSystem)\$(Platform)\$(Configuration)\</OutDir> - <OutDir>$(OutDir)dll\</OutDir> - <IntDir>$(Configuration)\dll\</IntDir> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="..\..\..\..\Build\Config.Definitions.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions Condition="'$(SubSystem)' != 'UWP'">_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions Condition="'$(SubSystem)' == 'UWP'">_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <PreprocessorDefinitions>SIGNALRCLIENT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile> - </ClCompile> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\..\..\..\include\signalrclient\connection.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\connection_state.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\http_client.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\hub_connection.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\hub_exception.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\log_writer.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\trace_level.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\transfer_format.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\websocket_client.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\web_exception.h" /> - <ClInclude Include="..\..\..\..\include\signalrclient\_exports.h" /> - <ClInclude Include="..\..\..\signalrclient\case_insensitive_comparison_utils.h" /> - <ClInclude Include="..\..\..\signalrclient\connection_impl.h" /> - <ClInclude Include="..\..\..\signalrclient\constants.h" /> - <ClInclude Include="..\..\..\signalrclient\default_http_client.h" /> - <ClInclude Include="..\..\..\signalrclient\default_websocket_client.h" /> - <ClInclude Include="..\..\..\signalrclient\http_sender.h" /> - <ClInclude Include="..\..\..\signalrclient\hub_connection_impl.h" /> - <ClInclude Include="..\..\..\signalrclient\callback_manager.h" /> - <ClInclude Include="..\..\..\signalrclient\logger.h" /> - <ClInclude Include="..\..\..\signalrclient\negotiate.h" /> - <ClInclude Include="..\..\..\signalrclient\negotiation_response.h" /> - <ClInclude Include="..\..\..\signalrclient\stdafx.h" /> - <ClInclude Include="..\..\..\signalrclient\trace_log_writer.h" /> - <ClInclude Include="..\..\..\signalrclient\transport.h" /> - <ClInclude Include="..\..\..\signalrclient\transport_factory.h" /> - <ClInclude Include="..\..\..\signalrclient\url_builder.h" /> - <ClInclude Include="..\..\..\signalrclient\websocket_transport.h" /> - <ClInclude Include="..\..\..\signalrclient\web_request.h" /> - <ClInclude Include="..\..\..\signalrclient\web_request_factory.h" /> - <ClInclude Include="..\..\..\signalrclient\web_response.h" /> - <ClInclude Include="..\..\resource.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\..\signalrclient\connection.cpp" /> - <ClCompile Include="..\..\..\signalrclient\connection_impl.cpp" /> - <ClCompile Include="..\..\..\signalrclient\default_http_client.cpp" /> - <ClCompile Include="..\..\..\signalrclient\default_websocket_client.cpp" /> - <ClCompile Include="..\..\..\signalrclient\http_sender.cpp" /> - <ClCompile Include="..\..\..\signalrclient\hub_connection.cpp" /> - <ClCompile Include="..\..\..\signalrclient\hub_connection_impl.cpp" /> - <ClCompile Include="..\..\..\signalrclient\callback_manager.cpp" /> - <ClCompile Include="..\..\..\signalrclient\logger.cpp" /> - <ClCompile Include="..\..\..\signalrclient\negotiate.cpp" /> - <ClCompile Include="..\..\..\signalrclient\signalr_client_config.cpp" /> - <ClCompile Include="..\..\..\signalrclient\stdafx.cpp"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\transport.cpp" /> - <ClCompile Include="..\..\..\signalrclient\transport_factory.cpp" /> - <ClCompile Include="..\..\..\signalrclient\url_builder.cpp" /> - <ClCompile Include="..\..\..\signalrclient\trace_log_writer.cpp" /> - <ClCompile Include="..\..\..\signalrclient\websocket_transport.cpp" /> - <ClCompile Include="..\..\..\signalrclient\web_request.cpp" /> - <ClCompile Include="..\..\..\signalrclient\web_request_factory.cpp" /> - <ClCompile Include="..\..\dllmain.cpp"> - <CompileAsManaged>false</CompileAsManaged> - <PrecompiledHeader> - </PrecompiledHeader> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\..\Resource.rc" /> - </ItemGroup> - <ItemGroup> - <PackageReference Include="cpprestsdk" Version="2.9.1.1" /> - <PackageReference Include="cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <Target Name="CreateVersionHeader" BeforeTargets="EnsureNuGetPackageBuildImports"> - <PropertyGroup> - <Revision>$(build_number)</Revision> - <Revision Condition="'$(Revision)' == ''">0</Revision> - </PropertyGroup> - <ItemGroup> - <VersionHeaderContents Include="// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved." /> - <VersionHeaderContents Include="// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information." /> - <VersionHeaderContents Include="%0a" /> - <VersionHeaderContents Include="// This file is auto-generated" /> - <VersionHeaderContents Include="%0a" /> - <VersionHeaderContents Include="#define FileVersion $(SignalRClientCppVersionMajor),$(SignalRClientCppVersionMinor),$(SignalRClientCppVersionPatch),$(Revision)" /> - <VersionHeaderContents Include="#define FileVersionStr "$(SignalRClientCppVersionMajor).$(SignalRClientCppVersionMinor).$(SignalRClientCppVersionPatch).$(Revision)\0"" /> - <VersionHeaderContents Include="#define ProductVersion $(SignalRClientCppVersionMajor),$(SignalRClientCppVersionMinor),$(SignalRClientCppVersionPatch),$(Revision)" /> - <VersionHeaderContents Include="#define ProductVersionStr "$(SignalRClientCppVersionString)\0"" /> - <VersionHeaderContents Include="#define PlatformToolset "$(PlatformToolset)\0"" /> - </ItemGroup> - <WriteLinesToFile File="..\..\version.h" Lines="@(VersionHeaderContents)" OverWrite="true" /> - </Target> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj.filters b/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj.filters deleted file mode 100644 index 16b4115e9b8d61d98a9644cc04c32a4cde9f640e..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclientdll/Build/VS/signalrclientdll.vcxproj.filters +++ /dev/null @@ -1,185 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\..\..\signalrclient\callback_manager.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\connection_impl.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\constants.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\default_websocket_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\http_sender.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\hub_connection_impl.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\logger.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\negotiation_response.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\transport.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\transport_factory.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\url_builder.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\web_request.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\web_request_factory.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\web_response.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\websocket_transport.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\_exports.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\connection.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\connection_state.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\hub_exception.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\log_writer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\transport_type.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\web_exception.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\stdafx.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\hub_connection.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\trace_level.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\trace_log_writer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\case_insensitive_comparison_utils.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\resource.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\default_http_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\signalrclient\negotiate.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\http_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\transfer_format.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\..\..\include\signalrclient\websocket_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\dllmain.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\connection.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\connection_impl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\default_websocket_client.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\http_sender.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\hub_connection_impl.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\logger.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\transport.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\transport_factory.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\url_builder.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\trace_log_writer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\web_request.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\web_request_factory.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\websocket_transport.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\stdafx.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\hub_connection.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\callback_manager.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\signalr_client_config.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\default_http_client.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\..\signalrclient\negotiate.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ResourceCompile Include="..\..\Resource.rc"> - <Filter>Resource Files</Filter> - </ResourceCompile> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/src/signalrclientdll/Resource.rc b/src/SignalR/clients/cpp/src/signalrclientdll/Resource.rc deleted file mode 100644 index b832d82cc82b06c69e1e62dd129be4988487ca88..0000000000000000000000000000000000000000 Binary files a/src/SignalR/clients/cpp/src/signalrclientdll/Resource.rc and /dev/null differ diff --git a/src/SignalR/clients/cpp/src/signalrclientdll/dllmain.cpp b/src/SignalR/clients/cpp/src/signalrclientdll/dllmain.cpp deleted file mode 100644 index ecf23fdc976c2e994be6a647ff0b81eb8eb212e5..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclientdll/dllmain.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "../signalrclient/stdafx.h" - -#if !defined(__cplusplus_winrt) - -BOOL APIENTRY DllMain( HMODULE /*hModule*/, - DWORD ul_reason_for_call, - LPVOID /*lpReserved*/ - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} - -#endif diff --git a/src/SignalR/clients/cpp/src/signalrclientdll/resource.h b/src/SignalR/clients/cpp/src/signalrclientdll/resource.h deleted file mode 100644 index 7ca31da7405a89530ebe5fa4d7882e7ca7cdc179..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclientdll/resource.h +++ /dev/null @@ -1,14 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by Resource.rc - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/src/SignalR/clients/cpp/src/signalrclientdll/version.h b/src/SignalR/clients/cpp/src/signalrclientdll/version.h deleted file mode 100644 index 9271ce7766ae8b5353ca2dce3c187dc027f5f154..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/src/signalrclientdll/version.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - - -// This file is auto-generated - - -#define FileVersion 1,0,0,0 -#define FileVersionStr "1.0.0.0\0" -#define ProductVersion 1,0,0,0 -#define ProductVersionStr "1.0.0-alpha0\0" -#define PlatformToolset "v141\0" diff --git a/src/SignalR/clients/cpp/test/CMakeLists.txt b/src/SignalR/clients/cpp/test/CMakeLists.txt deleted file mode 100644 index 29630f9e7c7962201a1647bc03756bbb8f8b8570..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_subdirectory (gtest-1.7.0) -enable_testing() -include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) - -add_subdirectory (signalrclienttests) \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/gtest/gtest.vcxproj b/src/SignalR/clients/cpp/test/gtest/gtest.vcxproj deleted file mode 100644 index 41b0f95a4f8d76db9d24f7e83f8d93dc4395d448..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/gtest/gtest.vcxproj +++ /dev/null @@ -1,171 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup Label="ProjectConfigurations"> - <ProjectConfiguration Include="Debug|Win32"> - <Configuration>Debug</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|Win32"> - <Configuration>Release</Configuration> - <Platform>Win32</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Debug|x64"> - <Configuration>Debug</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - <ProjectConfiguration Include="Release|x64"> - <Configuration>Release</Configuration> - <Platform>x64</Platform> - </ProjectConfiguration> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(GoogleTestSubmoduleRoot)googletest\src\gtest-all.cc" /> - </ItemGroup> - <PropertyGroup Label="Globals"> - <VCProjectVersion>15.0</VCProjectVersion> - <ProjectGuid>{CAC1267B-8778-4257-AAC6-CAF481723B01}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>gtest</RootNamespace> - <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - <TargetName>gtestd</TargetName> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - <TargetName>gtest</TargetName> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>true</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <CharacterSet>Unicode</CharacterSet> - <TargetName>gtestd</TargetName> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <PlatformToolset>v141</PlatformToolset> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - <TargetName>gtest</TargetName> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="Shared"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <LinkIncremental>true</LinkIncremental> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath> - <SourcePath>$(VC_SourcePath);</SourcePath> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <LinkIncremental>true</LinkIncremental> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath> - <SourcePath>$(VC_SourcePath);</SourcePath> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath> - <SourcePath>$(VC_SourcePath);</SourcePath> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath> - <SourcePath>$(VC_SourcePath);</SourcePath> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(GoogleTestSubmoduleRoot)googletest\include;$(GoogleTestSubmoduleRoot)googletest;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>Disabled</Optimization> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(GoogleTestSubmoduleRoot)googletest\include;$(GoogleTestSubmoduleRoot)googletest;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(GoogleTestSubmoduleRoot)googletest\include;$(GoogleTestSubmoduleRoot)googletest;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - <WarningLevel>Level3</WarningLevel> - <Optimization>MaxSpeed</Optimization> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <SDLCheck>true</SDLCheck> - <PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <ConformanceMode>true</ConformanceMode> - <AdditionalIncludeDirectories>$(GoogleTestSubmoduleRoot)googletest\include;$(GoogleTestSubmoduleRoot)googletest;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <GenerateDebugInformation>true</GenerateDebugInformation> - </Link> - </ItemDefinitionGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/gtest/gtest.vcxproj.filters b/src/SignalR/clients/cpp/test/gtest/gtest.vcxproj.filters deleted file mode 100644 index a2bafdf4546c43763d83bc9264439733f56f917f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/gtest/gtest.vcxproj.filters +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClCompile Include="$(GoogleTestSubmoduleRoot)googletest\src\gtest-all.cc"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj deleted file mode 100644 index 9a470efcf9c924e5cc029bda4c4a2454a4b9bcac..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj +++ /dev/null @@ -1,78 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="..\..\..\..\Build\SignalRClient.Build.Settings" /> - <PropertyGroup Label="Globals"> - <ProjectGuid>{6006C96A-29F0-4B18-8DDD-764DC3419E2F}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>signalrclient-e2e-tests</RootNamespace> - <ProjectName>signalrclient-e2e-tests</ProjectName> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir> - <ConfigurationType>Application</ConfigurationType> - <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="..\..\..\..\Build\Config.Definitions.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(GoogleTestSubmoduleRoot)googletest\include;..\..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\..\test_utils.h" /> - <ClInclude Include="..\..\stdafx.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\connection_tests.cpp" /> - <ClCompile Include="..\..\hub_connection_tests.cpp" /> - <ClCompile Include="..\..\test_utils.cpp" /> - <ClCompile Include="..\..\signalrclient-e2e-tests.cpp" /> - <ClCompile Include="..\..\stdafx.cpp"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\..\..\..\src\signalrclientdll\Build\VS\signalrclientdll.vcxproj"> - <Project>{18377ae8-e372-40ce-94fd-7f65008d39a3}</Project> - <CopyLocal>true</CopyLocal> - <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies> - <LinkLibraryDependencies>true</LinkLibraryDependencies> - </ProjectReference> - <ProjectReference Include="..\..\..\gtest\gtest.vcxproj"> - <Project>{cac1267b-8778-4257-aac6-caf481723b01}</Project> - </ProjectReference> - </ItemGroup> - <ItemGroup> - <PackageReference Include="cpprestsdk" Version="2.9.1.1" /> - <PackageReference Include="cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <Target Name="AfterBuild"> - <Exec Command="copy /y "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\dll\$(SignalrClientTargetName).dll" "$(SolutionDir)bin\Desktop\$(Platform)\$(Configuration)\$(SignalrClientTargetName).dll"" /> - </Target> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj.filters b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj.filters deleted file mode 100644 index d441a9f7ab1b92d15dd4c5065b9dcda78c32cd57..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/Build/VS/signalrclient-e2e-tests.vcxproj.filters +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\..\stdafx.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\test_utils.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\stdafx.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\signalrclient-e2e-tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\connection_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\hub_connection_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\test_utils.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/connection_tests.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/connection_tests.cpp deleted file mode 100644 index b089ca9fcf064983594026eb57438b6b2e504fa9..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/connection_tests.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "stdafx.h" -#include <string> -#include "cpprest/details/basic_types.h" -#include "cpprest/json.h" -#include "signalrclient/connection.h" -#include "signalrclient/hub_connection.h" -#include "../signalrclienttests/test_utils.h" - -extern std::string url; - -TEST(connection_tests, connection_status_start_stop) -{ - auto conn = std::make_shared<signalr::connection>(url + "raw-connection"); - - auto mre = manual_reset_event<void>(); - conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_EQ(conn->get_connection_state(), signalr::connection_state::connected); - - conn->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_EQ(conn->get_connection_state(), signalr::connection_state::disconnected); - - conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_EQ(conn->get_connection_state(), signalr::connection_state::connected); -} - -TEST(connection_tests, send_message) -{ - auto conn = std::make_shared<signalr::connection>(url + "raw-connection"); - auto message = std::make_shared<std::string>(); - auto received_event = std::make_shared<signalr::event>(); - - conn->set_message_received([message, received_event](const std::string& payload) - { - *message = payload; - received_event->set(); - }); - - auto mre = manual_reset_event<void>(); - conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - web::json::value obj; - obj[U("type")] = web::json::value::number(0); - obj[U("value")] = web::json::value::string(U("test")); - conn->send(utility::conversions::to_utf8string(obj.serialize()), [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(received_event->wait(2000)); - - ASSERT_EQ(*message, "{\"data\":\"test\",\"type\":0}"); -} - -TEST(connection_tests, send_message_after_connection_restart) -{ - auto conn = std::make_shared<signalr::connection>(url + "raw-connection"); - auto message = std::make_shared<std::string>(); - auto received_event = std::make_shared<signalr::event>(); - - conn->set_message_received([message, received_event](const std::string& payload) - { - *message = payload; - received_event->set(); - }); - - auto mre = manual_reset_event<void>(); - conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - conn->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - web::json::value obj; - obj[U("type")] = web::json::value::number(0); - obj[U("value")] = web::json::value::string(U("test")); - conn->send(utility::conversions::to_utf8string(obj.serialize()), [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(received_event->wait(2000)); - - ASSERT_EQ(*message, "{\"data\":\"test\",\"type\":0}"); -} - -TEST(connection_tests, connection_id_start_stop) -{ - auto conn = std::make_shared<signalr::connection>(url + "raw-connection"); - - ASSERT_EQ("", conn->get_connection_id()); - - auto mre = manual_reset_event<void>(); - conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - auto connection_id = conn->get_connection_id(); - ASSERT_NE(connection_id, ""); - - conn->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_EQ(conn->get_connection_id(), connection_id); - - conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_NE(conn->get_connection_id(), ""); - ASSERT_NE(conn->get_connection_id(), connection_id); -} diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/hub_connection_tests.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/hub_connection_tests.cpp deleted file mode 100644 index 89d1fade27dfee73e25623390faa632a637e8350..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/hub_connection_tests.cpp +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "stdafx.h" -#include <string> -#include "cpprest/details/basic_types.h" -#include "cpprest/json.h" -#include "signalrclient/connection.h" -#include "signalrclient/hub_connection.h" -#include "signalrclient/signalr_exception.h" -#include "../signalrclienttests/test_utils.h" - -extern std::string url; - -TEST(hub_connection_tests, connection_status_start_stop_start) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url); - auto weak_hub_conn = std::weak_ptr<signalr::hub_connection>(hub_conn); - - auto mre = manual_reset_event<void>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_EQ(hub_conn->get_connection_state(), signalr::connection_state::connected); - - hub_conn->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_EQ(hub_conn->get_connection_state(), signalr::connection_state::disconnected); - - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_EQ(hub_conn->get_connection_state(), signalr::connection_state::connected); -} - -TEST(hub_connection_tests, send_message) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url + "custom", signalr::trace_level::all, nullptr); - auto message = std::make_shared<std::string>(); - auto received_event = std::make_shared<signalr::event>(); - - hub_conn->on("sendString", [message, received_event](const web::json::value& arguments) - { - *message = utility::conversions::to_utf8string(arguments.serialize()); - received_event->set(); - }); - - auto mre = manual_reset_event<void>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - web::json::value obj{}; - obj[0] = web::json::value(U("test")); - - hub_conn->send("invokeWithString", obj, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(received_event->wait(2000)); - - ASSERT_EQ(*message, "[\"Send: test\"]"); -} - -TEST(hub_connection_tests, send_message_return) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url); - - auto mre = manual_reset_event<web::json::value>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - web::json::value obj{}; - obj[0] = web::json::value(U("test")); - - hub_conn->invoke("returnString", obj, [&mre](const web::json::value & value, std::exception_ptr exception) - { - if (exception) - { - mre.set(exception); - } - else - { - mre.set(value); - } - }); - - auto test = mre.get(); - - ASSERT_EQ(test.serialize(), U("\"test\"")); -} - -TEST(hub_connection_tests, send_message_after_connection_restart) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url); - auto message = std::make_shared<std::string>(); - auto received_event = std::make_shared<signalr::event>(); - - hub_conn->on("sendString", [message, received_event](const web::json::value& arguments) - { - *message = utility::conversions::to_utf8string(arguments.serialize()); - received_event->set(); - }); - - auto mre = manual_reset_event<void>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_conn->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - web::json::value obj{}; - obj[0] = web::json::value(U("test")); - - hub_conn->send("invokeWithString", obj, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(received_event->wait(2000)); - - ASSERT_EQ(*message, "[\"Send: test\"]"); -} - -TEST(hub_connection_tests, send_message_empty_param) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url); - auto message = std::make_shared<std::string>(); - auto received_event = std::make_shared<signalr::event>(); - - hub_conn->on("sendString", [message, received_event](const web::json::value& arguments) - { - *message = utility::conversions::to_utf8string(arguments.serialize()); - received_event->set(); - }); - - auto mre = manual_reset_event<void>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - - hub_conn->invoke("invokeWithEmptyParam", web::json::value::array(), [&mre](const web::json::value &, std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(received_event->wait(2000)); - - ASSERT_EQ(*message, "[\"Send\"]"); -} - -TEST(hub_connection_tests, send_message_primitive_params) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url); - auto message = std::make_shared<std::string>(); - auto received_event = std::make_shared<signalr::event>(); - - hub_conn->on("sendPrimitiveParams", [message, received_event](const web::json::value& arguments) - { - *message = utility::conversions::to_utf8string(arguments.serialize()); - received_event->set(); - }); - - auto mre = manual_reset_event<void>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - web::json::value obj{}; - obj[0] = web::json::value(5); - obj[1] = web::json::value(21.05); - obj[2] = web::json::value(8.999999999); - obj[3] = web::json::value(true); - obj[4] = web::json::value('a'); - hub_conn->send("invokeWithPrimitiveParams", obj, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(received_event->wait(2000)); - - obj[0] = web::json::value(6); - obj[1] = web::json::value(22.05); - obj[2] = web::json::value(9.999999999); - obj[3] = web::json::value(true); - obj[4] = web::json::value::string(U("a")); - - ASSERT_EQ(*message, utility::conversions::to_utf8string(obj.serialize())); -} - -TEST(hub_connection_tests, send_message_complex_type) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url); - auto message = std::make_shared<std::string>(); - auto received_event = std::make_shared<signalr::event>(); - - hub_conn->on("sendComplexType", [message, received_event](const web::json::value& arguments) - { - *message = utility::conversions::to_utf8string(arguments.serialize()); - received_event->set(); - }); - - auto mre = manual_reset_event<void>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - web::json::value obj{}; - web::json::value person; - web::json::value address; - address[U("street")] = web::json::value::string(U("main st")); - address[U("zip")] = web::json::value::string(U("98052")); - person[U("address")] = address; - person[U("name")] = web::json::value::string(U("test")); - person[U("age")] = web::json::value::number(15); - obj[0] = person; - - hub_conn->send("invokeWithComplexType", obj, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(received_event->wait(2000)); - - ASSERT_EQ(*message, "[{\"Address\":{\"Street\":\"main st\",\"Zip\":\"98052\"},\"Age\":15,\"Name\":\"test\"}]"); -} - -TEST(hub_connection_tests, send_message_complex_type_return) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url); - - auto mre = manual_reset_event<web::json::value>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - web::json::value obj{}; - web::json::value person; - web::json::value address; - address[U("street")] = web::json::value::string(U("main st")); - address[U("zip")] = web::json::value::string(U("98052")); - person[U("address")] = address; - person[U("name")] = web::json::value::string(U("test")); - person[U("age")] = web::json::value::number(15); - obj[0] = person; - - hub_conn->invoke("returnComplexType", obj, [&mre](const web::json::value & value, std::exception_ptr exception) - { - if (exception) - { - mre.set(exception); - } - else - { - mre.set(value); - } - }); - - auto test = mre.get(); - - ASSERT_EQ(test.serialize(), U("{\"Address\":{\"Street\":\"main st\",\"Zip\":\"98052\"},\"Age\":15,\"Name\":\"test\"}")); -} - -TEST(hub_connection_tests, connection_id_start_stop_start) -{ - auto hub_conn = std::make_shared<signalr::hub_connection>(url); - auto weak_hub_conn = std::weak_ptr<signalr::hub_connection>(hub_conn); - - std::string connection_id; - - ASSERT_EQ(u8"", hub_conn->get_connection_id()); - - auto mre = manual_reset_event<void>(); - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection_id = hub_conn->get_connection_id(); - ASSERT_NE(connection_id, u8""); - - hub_conn->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_EQ(hub_conn->get_connection_id(), connection_id); - - hub_conn->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_NE(hub_conn->get_connection_id(), u8""); - ASSERT_NE(hub_conn->get_connection_id(), connection_id); - - connection_id = hub_conn->get_connection_id(); -} - -//TEST(hub_connection_tests, mirror_header) -//{ -// auto hub_conn = std::make_shared<signalr::hub_connection>(url); -// -// signalr::signalr_client_config signalr_client_config{}; -// auto headers = signalr_client_config.get_http_headers(); -// headers[U("x-mirror")] = U("MirrorThis"); -// signalr_client_config.set_http_headers(headers); -// hub_conn->set_client_config(signalr_client_config); -// -// { -// auto mirrored_header_value = hub_conn->start().then([&hub_conn]() -// { -// return hub_conn->invoke(U("mirrorHeader")); -// }).get(); -// ASSERT_EQ(U("MirrorThis"), mirrored_header_value.as_string()); -// } -// -// hub_conn->stop().wait(); -// -// headers[U("x-mirror")] = U("MirrorThat"); -// signalr_client_config.set_http_headers(headers); -// hub_conn->set_client_config(signalr_client_config); -// -// { -// auto mirrored_header_value = hub_conn->start().then([&hub_conn]() -// { -// return hub_conn->invoke(U("mirrorHeader")); -// }).get(); -// ASSERT_EQ(U("MirrorThat"), mirrored_header_value.as_string()); -// } -//} diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/signalrclient-e2e-tests.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/signalrclient-e2e-tests.cpp deleted file mode 100644 index 0cd4043ed60c94536fd7ac08316288b27735d14c..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/signalrclient-e2e-tests.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include <vector> -#include "test_utils.h" - -int main(int argc, char* argv[]) -{ - get_url(argc, argv); - - ::testing::InitGoogleTest(&argc, argv); - RUN_ALL_TESTS(); - return 0; -} diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.cpp deleted file mode 100644 index bd7a85614cfe19b82fec4f1be1f0738d8a0079d0..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.h b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.h deleted file mode 100644 index 30064654d8cc27ee1b2f0f7227d58885b1140e63..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/stdafx.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#ifdef _WIN32 -// prevents from defining min/max macros that conflict with std::min()/std::max() functions -#define NOMINMAX -#endif - -#include "gtest/gtest.h" -#include "../../src/signalrclient/event.h" \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.cpp b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.cpp deleted file mode 100644 index 8a8da25339d3501ee1e2bde63ee4b678af76c7fd..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "stdafx.h" -#include <string> -#include "cpprest/details/basic_types.h" -#include "cpprest/asyncrt_utils.h" -#include <chrono> - -std::string url; - -void get_url(int argc, char* argv[]) -{ - url = "http://localhost:42524/"; - - for (int i = 0; i < argc; ++i) - { - std::string str = argv[i]; - - auto pos = str.find("url="); - if (pos != std::string::npos) - { - url = str.substr(pos + 4); - break; - } - } -} diff --git a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.h b/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.h deleted file mode 100644 index 41d72ced843ef6d7c704e774f1533e67d9f2fde7..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-e2e-tests/test_utils.h +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "stdafx.h" - -void get_url(int argc, char* argv[]); diff --git a/src/SignalR/clients/cpp/test/signalrclient-testhost/App.config b/src/SignalR/clients/cpp/test/signalrclient-testhost/App.config deleted file mode 100644 index b58036efb3b77fed07f533e5902f5b7bcfb1d9ff..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-testhost/App.config +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<configuration> - <startup> - <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> - </startup> - <runtime> - <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> - <dependentAssembly> - <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> - </dependentAssembly> - <dependentAssembly> - <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" /> - <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" /> - </dependentAssembly> - </assemblyBinding> - </runtime> -</configuration> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/HubConnection.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/HubConnection.cs deleted file mode 100644 index 347eca7030f03f9d8c9b9266a2e77385ffd33632..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/HubConnection.cs +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNet.SignalR; - -namespace SelfHost -{ - public class HubConnection : Hub - { - public IEnumerable<int> ForceReconnect() - { - yield return 1; - // throwing here will close the websocket which should trigger reconnect - throw new Exception(); - } - - public void InvokeWithString(string message) - { - Clients.Caller.sendString("Send: " + message); - } - - public string ReturnString(string message) - { - return message; - } - - public void InvokeWithEmptyParam() - { - Clients.Caller.sendString("Send"); - } - - public void InvokeWithPrimitiveParams(int myint, float myfloat, double mydouble, bool mybool, char mychar) - { - Clients.Caller.sendPrimitiveParams(myint + 1, myfloat + 1, mydouble + 1, mybool, mychar); - } - - public void InvokeWithComplexType(Person p) - { - Clients.Caller.sendComplexType(p); - } - - public Person ReturnComplexType(Person p) - { - return p; - } - - public class Person - { - public string Name { get; set; } - public int Age { get; set; } - public Address Address { get; set; } - } - - public class Address - { - public string Street { get; set; } - public string Zip { get; set; } - } - - public async Task InvokeWithProgress(IProgress<int> progress) - { - for (int i = 0; i < 5; i++) - { - progress.Report(i); - await Task.Delay(10); - } - } - - public async Task<string> InvokeWithProgress(string jobName, IProgress<int> progress) - { - for (int i = 0; i < 5; i++) - { - progress.Report(i); - await Task.Delay(10); - - } - - return string.Format("{0} done!", jobName); - } - - public string MirrorHeader() - { - var mirrorValue = Context.Request.Headers["x-mirror"]; - return mirrorValue; - } - } -} \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/RawConnection.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/RawConnection.cs deleted file mode 100644 index cf226279e4b9ace743c1aa4459a92047a2169988..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-testhost/Connections/RawConnection.cs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Threading.Tasks; -using System.Threading; -using Microsoft.AspNet.SignalR; -using Newtonsoft.Json; - -namespace SelfHost -{ - public class RawConnection : PersistentConnection - { - protected override Task OnReceived(IRequest request, string connectionId, string data) - { - // This is test code, not best practice and does not address input validation or other security concerns. - // Applications need to ensure they perform proper data sanitization and best practices when working - // with untrusted input. - var message = JsonConvert.DeserializeObject<Message>(data); - - switch (message.Type) - { - case MessageType.String: - Connection.Send(connectionId, new { type = MessageType.String, data = message.Value }); - break; - default: - break; - } - - return base.OnReceived(request, connectionId, data); - } - - enum MessageType - { - String - } - - class Message - { - public MessageType Type { get; set; } - public string Value { get; set; } - } - } -} diff --git a/src/SignalR/clients/cpp/test/signalrclient-testhost/Program.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Program.cs deleted file mode 100644 index 2fe55914b3518c3851fef9c4923dfd616e5d6022..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-testhost/Program.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.Owin.Hosting; -using System; -using System.Threading; - -namespace SelfHost -{ - public class Program - { - static void Main(string[] args) - { - using (WebApp.Start<Startup>("http://localhost:42524")) - { - Console.WriteLine("Server running at http://localhost:42524/"); - Thread.Sleep(args.Length > 0 ? int.Parse(args[0]) : Timeout.Infinite); - } - } - } -} diff --git a/src/SignalR/clients/cpp/test/signalrclient-testhost/Properties/AssemblyInfo.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Properties/AssemblyInfo.cs deleted file mode 100644 index 5b029b5259785c799f8a673885b195a167721a1a..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-testhost/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -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("signalrclient-testhost")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("signalrclient-testhost")] -[assembly: AssemblyCopyright("Copyright © 2013")] - -// 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("6b1e3377-fed7-45e6-a1a8-9787d2f9c8dd")] - -// 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/SignalR/clients/cpp/test/signalrclient-testhost/Startup.cs b/src/SignalR/clients/cpp/test/signalrclient-testhost/Startup.cs deleted file mode 100644 index 806a9a4a1f2b919c5ab4141fa2dbebd37d9c1cb4..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-testhost/Startup.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using Owin; - -namespace SelfHost -{ - public class Startup - { - public void Configuration(IAppBuilder app) - { - app.Map("/raw-connection", map => map.RunSignalR<RawConnection>()); - - app.MapSignalR(); - - app.Map("/custom", map => map.RunSignalR()); - } - } -} \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclient-testhost/packages.config b/src/SignalR/clients/cpp/test/signalrclient-testhost/packages.config deleted file mode 100644 index 2e2e718a2e9b7562f4181925b26b524aa008b8c0..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-testhost/packages.config +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<packages> - <package id="Microsoft.AspNet.SignalR.Core" version="2.2.0" targetFramework="net451" /> - <package id="Microsoft.AspNet.SignalR.SelfHost" version="2.2.0" targetFramework="net451" /> - <package id="Microsoft.Owin" version="3.0.1" targetFramework="net451" /> - <package id="Microsoft.Owin.Diagnostics" version="3.0.1" targetFramework="net451" /> - <package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net451" /> - <package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net451" /> - <package id="Microsoft.Owin.Security" version="3.0.1" targetFramework="net451" /> - <package id="Microsoft.Owin.SelfHost" version="3.0.1" targetFramework="net451" /> - <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net451" /> - <package id="Owin" version="1.0" targetFramework="net451" /> -</packages> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclient-testhost/signalrclient-testhost.csproj b/src/SignalR/clients/cpp/test/signalrclient-testhost/signalrclient-testhost.csproj deleted file mode 100644 index 132ed69166338647058886e3769a14e6c884dadf..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclient-testhost/signalrclient-testhost.csproj +++ /dev/null @@ -1,103 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform>AnyCPU</Platform> - <ProjectGuid>{11848039-1F13-4047-9539-8F9F45930788}</ProjectGuid> - <OutputType>Exe</OutputType> - <AppDesignerFolder>Properties</AppDesignerFolder> - <RootNamespace>SelfHost</RootNamespace> - <AssemblyName>signalrclient-testhost</AssemblyName> - <TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion> - <FileAlignment>512</FileAlignment> - <SccProjectName>SAK</SccProjectName> - <SccLocalPath>SAK</SccLocalPath> - <SccAuxPath>SAK</SccAuxPath> - <SccProvider>SAK</SccProvider> - <TargetFrameworkProfile /> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir> - <RestorePackages>true</RestorePackages> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - <Prefer32Bit>false</Prefer32Bit> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <PlatformTarget>AnyCPU</PlatformTarget> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - <Prefer32Bit>false</Prefer32Bit> - </PropertyGroup> - <ItemGroup> - <Reference Include="Microsoft.AspNet.SignalR.Core"> - <HintPath>..\..\packages\Microsoft.AspNet.SignalR.Core.2.2.0\lib\net45\Microsoft.AspNet.SignalR.Core.dll</HintPath> - </Reference> - <Reference Include="Microsoft.Owin"> - <HintPath>..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath> - </Reference> - <Reference Include="Microsoft.Owin.Diagnostics"> - <HintPath>..\..\packages\Microsoft.Owin.Diagnostics.3.0.1\lib\net45\Microsoft.Owin.Diagnostics.dll</HintPath> - </Reference> - <Reference Include="Microsoft.Owin.Host.HttpListener"> - <HintPath>..\..\packages\Microsoft.Owin.Host.HttpListener.3.0.1\lib\net45\Microsoft.Owin.Host.HttpListener.dll</HintPath> - </Reference> - <Reference Include="Microsoft.Owin.Hosting"> - <HintPath>..\..\packages\Microsoft.Owin.Hosting.3.0.1\lib\net45\Microsoft.Owin.Hosting.dll</HintPath> - </Reference> - <Reference Include="Microsoft.Owin.Security"> - <HintPath>..\..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll</HintPath> - </Reference> - <Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> - <HintPath>..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath> - </Reference> - <Reference Include="Owin"> - <HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath> - </Reference> - <Reference Include="System" /> - <Reference Include="System.Core" /> - <Reference Include="System.Xml.Linq" /> - <Reference Include="System.Data.DataSetExtensions" /> - <Reference Include="Microsoft.CSharp" /> - <Reference Include="System.Data" /> - <Reference Include="System.Xml" /> - </ItemGroup> - <ItemGroup> - <Compile Include="Connections\HubConnection.cs" /> - <Compile Include="Connections\RawConnection.cs" /> - <Compile Include="Program.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="Startup.cs" /> - </ItemGroup> - <ItemGroup> - <None Include="App.config" /> - <None Include="packages.config" /> - </ItemGroup> - <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> - <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> - <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> - <PropertyGroup> - <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText> - </PropertyGroup> - <Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" /> - </Target> - <!-- 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> - --> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj b/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj deleted file mode 100644 index e88d39671070572ed78b52a8b90c02a46da829ed..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj +++ /dev/null @@ -1,102 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="..\..\..\..\Build\SignalRClient.Build.Settings" /> - <PropertyGroup Label="Globals"> - <ProjectGuid>{10376148-BCF4-4B55-98A5-3C98C87FD898}</ProjectGuid> - <Keyword>Win32Proj</Keyword> - <RootNamespace>signalrclienttests</RootNamespace> - <ProjectName>signalrclienttests</ProjectName> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\..\</SolutionDir> - <ConfigurationType>Application</ConfigurationType> - <WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion> - </PropertyGroup> - <Import Project="..\..\..\..\Build\Config.Definitions.props" /> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <PlatformToolset>v141</PlatformToolset> - </PropertyGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <PropertyGroup Label="UserMacros" /> - <ItemDefinitionGroup> - <ClCompile> - <PreprocessorDefinitions>_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING;_CONSOLE;_LIB;NO_SIGNALRCLIENT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(GoogleTestSubmoduleRoot)googletest\include;..\..\..\..\include;..\..\..\..\src\signalrclient;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> - <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</TreatWarningAsError> - <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</TreatWarningAsError> - <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</TreatWarningAsError> - <TreatWarningAsError Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</TreatWarningAsError> - </ClCompile> - <Link> - <SubSystem>Console</SubSystem> - </Link> - </ItemDefinitionGroup> - <ItemGroup> - <ClInclude Include="..\..\memory_log_writer.h" /> - <ClInclude Include="..\..\stdafx.h" /> - <ClInclude Include="..\..\targetver.h" /> - <ClInclude Include="..\..\test_http_client.h" /> - <ClInclude Include="..\..\test_transport_factory.h" /> - <ClInclude Include="..\..\test_utils.h" /> - <ClInclude Include="..\..\test_websocket_client.h" /> - <ClInclude Include="..\..\test_web_request_factory.h" /> - <ClInclude Include="..\..\web_request_stub.h" /> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\callback_manager_tests.cpp" /> - <ClCompile Include="..\..\case_insensitive_comparison_utils_tests.cpp" /> - <ClCompile Include="..\..\connection_impl_tests.cpp" /> - <ClCompile Include="..\..\http_sender_tests.cpp" /> - <ClCompile Include="..\..\hub_connection_impl_tests.cpp" /> - <ClCompile Include="..\..\hub_exception_tests.cpp" /> - <ClCompile Include="..\..\logger_tests.cpp" /> - <ClCompile Include="..\..\memory_log_writer.cpp" /> - <ClCompile Include="..\..\negotiate_tests.cpp" /> - <ClCompile Include="..\..\signalrclienttests.cpp" /> - <ClCompile Include="..\..\stdafx.cpp"> - <PrecompiledHeader>Create</PrecompiledHeader> - </ClCompile> - <ClCompile Include="..\..\test_http_client.cpp" /> - <ClCompile Include="..\..\test_transport_factory.cpp" /> - <ClCompile Include="..\..\test_utils.cpp" /> - <ClCompile Include="..\..\test_websocket_client.cpp" /> - <ClCompile Include="..\..\test_web_request_factory.cpp" /> - <ClCompile Include="..\..\url_builder_tests.cpp" /> - <ClCompile Include="..\..\websocket_transport_tests.cpp" /> - <ClCompile Include="..\..\web_request_stub.cpp" /> - <ClCompile Include="..\..\web_request_tests.cpp" /> - </ItemGroup> - <ItemGroup> - <ProjectReference Include="..\..\..\..\src\SignalRClient\Build\VS\SignalRClient.vcxproj"> - <Project>{87ed3ad4-d820-48cd-8382-a12564213a12}</Project> - </ProjectReference> - <ProjectReference Include="..\..\..\gtest\gtest.vcxproj"> - <Project>{cac1267b-8778-4257-aac6-caf481723b01}</Project> - </ProjectReference> - </ItemGroup> - <ItemGroup> - <PackageReference Include="cpprestsdk" Version="2.9.1.1" /> - <PackageReference Include="cpprestsdk.v120.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winphone.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winphonesl.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v120.winxp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v140.winapp.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - <PackageReference Include="cpprestsdk.v140.windesktop.msvcstl.dyn.rt-dyn" Version="2.9.1" /> - </ItemGroup> - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <PropertyGroup> - <IsTestProject>true</IsTestProject> - <TestProjectSkipReason>Flaky, due to https://github.com/aspnet/AspNetCore/issues/8421</TestProjectSkipReason> - </PropertyGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj.filters b/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj.filters deleted file mode 100644 index f8329224c0b3098c74a1892b1de23fde85975535..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/Build/VS/signalrclienttests.vcxproj.filters +++ /dev/null @@ -1,108 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Source Files"> - <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> - <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> - </Filter> - <Filter Include="Header Files"> - <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> - <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> - </Filter> - <Filter Include="Resource Files"> - <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> - <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> - </Filter> - </ItemGroup> - <ItemGroup> - <ClInclude Include="..\..\stdafx.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\targetver.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\web_request_stub.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\test_web_request_factory.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\test_websocket_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\memory_log_writer.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\test_utils.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\test_transport_factory.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\test_http_client.h"> - <Filter>Header Files</Filter> - </ClInclude> - </ItemGroup> - <ItemGroup> - <ClCompile Include="..\..\stdafx.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\SignalRClientTests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\url_builder_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\http_sender_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\web_request_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\websocket_transport_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\test_web_request_factory.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\web_request_stub.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\test_websocket_client.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\connection_impl_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\logger_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\memory_log_writer.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\test_utils.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\test_transport_factory.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\hub_connection_impl_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\callback_manager_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\hub_exception_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\case_insensitive_comparison_utils_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\test_http_client.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - <ClCompile Include="..\..\negotiate_tests.cpp"> - <Filter>Source Files</Filter> - </ClCompile> - </ItemGroup> -</Project> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/CMakeLists.txt b/src/SignalR/clients/cpp/test/signalrclienttests/CMakeLists.txt deleted file mode 100644 index fce4abdbae4c4dca6781046366781e63cf0fef6b..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/CMakeLists.txt +++ /dev/null @@ -1,33 +0,0 @@ - - -set (SOURCES - callback_manager_tests.cpp - case_insensitive_comparison_utils_tests.cpp - connection_impl_tests.cpp - http_sender_tests.cpp - hub_connection_impl_tests.cpp - hub_exception_tests.cpp - logger_tests.cpp - memory_log_writer.cpp - request_sender_tests.cpp - signalrclienttests.cpp - stdafx.cpp - test_transport_factory.cpp - test_utils.cpp - test_web_request_factory.cpp - test_websocket_client.cpp - url_builder_tests.cpp - web_request_stub.cpp - web_request_tests.cpp - websocket_transport_tests.cpp -) - -include_directories( - ../../src/signalrclient) - -find_package(Boost COMPONENTS system REQUIRED) -find_package(OpenSSL REQUIRED) - -add_executable (signalrclienttests ${SOURCES}) -target_link_libraries(signalrclienttests gtest gtest_main signalrclient ${CPPREST_SO} ${Boost_SYSTEM_LIBRARY} ${OPENSSL_LIBRARIES}) -add_test(signalrclienttests signalrclienttests) diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/callback_manager_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/callback_manager_tests.cpp deleted file mode 100644 index 1e0afedde4592663370f073de763c5d6660f84c6..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/callback_manager_tests.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "callback_manager.h" - -using namespace signalr; -using namespace web; - -TEST(callback_manager_register_callback, register_returns_unique_callback_ids) -{ - callback_manager callback_mgr{ json::value::object() }; - auto callback_id1 = callback_mgr.register_callback([](const json::value&){}); - auto callback_id2 = callback_mgr.register_callback([](const web::json::value&){}); - - ASSERT_NE(callback_id1, callback_id2); -} - -TEST(callback_manager_invoke_callback, invoke_callback_invokes_and_removes_callback_if_remove_callback_true) -{ - callback_manager callback_mgr{ json::value::object() }; - - std::string callback_argument{ "" }; - - auto callback_id = callback_mgr.register_callback( - [&callback_argument](const json::value& argument) - { - callback_argument = utility::conversions::to_utf8string(argument.serialize()); - }); - - auto callback_found = callback_mgr.invoke_callback(callback_id, json::value::number(42), true); - - ASSERT_TRUE(callback_found); - ASSERT_EQ("42", callback_argument); - ASSERT_FALSE(callback_mgr.remove_callback(callback_id)); -} - -TEST(callback_manager_invoke_callback, invoke_callback_invokes_and_does_not_remove_callback_if_remove_callback_false) -{ - callback_manager callback_mgr{ json::value::object() }; - - std::string callback_argument{ "" }; - - auto callback_id = callback_mgr.register_callback( - [&callback_argument](const json::value& argument) - { - callback_argument = utility::conversions::to_utf8string(argument.serialize()); - }); - - auto callback_found = callback_mgr.invoke_callback(callback_id, json::value::number(42), false); - - ASSERT_TRUE(callback_found); - ASSERT_EQ("42", callback_argument); - ASSERT_TRUE(callback_mgr.remove_callback(callback_id)); -} - -TEST(callback_manager_ivoke_callback, invoke_callback_returns_false_for_invalid_callback_id) -{ - callback_manager callback_mgr{ json::value::object() }; - auto callback_found = callback_mgr.invoke_callback("42", json::value::object(), true); - - ASSERT_FALSE(callback_found); -} - -TEST(callback_manager_remove, remove_removes_callback_and_returns_true_for_valid_callback_id) -{ - auto callback_called = false; - - { - callback_manager callback_mgr{ json::value::object() }; - - auto callback_id = callback_mgr.register_callback( - [&callback_called](const json::value&) - { - callback_called = true; - }); - - ASSERT_TRUE(callback_mgr.remove_callback(callback_id)); - } - - ASSERT_FALSE(callback_called); -} - -TEST(callback_manager_remove, remove_returns_false_for_invalid_callback_id) -{ - callback_manager callback_mgr{ json::value::object() }; - ASSERT_FALSE(callback_mgr.remove_callback("42")); -} - -TEST(callback_manager_clear, clear_invokes_all_callbacks) -{ - callback_manager callback_mgr{ json::value::object() }; - auto invocation_count = 0; - - for (auto i = 0; i < 10; i++) - { - callback_mgr.register_callback( - [&invocation_count](const json::value& argument) - { - invocation_count++; - ASSERT_EQ(_XPLATSTR("42"), argument.serialize()); - }); - } - - callback_mgr.clear(json::value::number(42)); - - ASSERT_EQ(10, invocation_count); -} - -TEST(callback_manager_dtor, clear_invokes_all_callbacks) -{ - auto invocation_count = 0; - bool parameter_correct = true; - - { - callback_manager callback_mgr{ json::value::number(42) }; - for (auto i = 0; i < 10; i++) - { - callback_mgr.register_callback( - [&invocation_count, ¶meter_correct](const json::value& argument) - { - invocation_count++; - parameter_correct &= argument.serialize() == _XPLATSTR("42"); - }); - } - } - - ASSERT_EQ(10, invocation_count); - ASSERT_TRUE(parameter_correct); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/case_insensitive_comparison_utils_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/case_insensitive_comparison_utils_tests.cpp deleted file mode 100644 index 0b94f476553f03fbebcb6e2b37d8240b49a67f2f..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/case_insensitive_comparison_utils_tests.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "case_insensitive_comparison_utils.h" - -using namespace signalr; - -TEST(case_insensitive_equals_functor, basic_comparison_tests) -{ - case_insensitive_equals case_insensitive_compare; - - ASSERT_TRUE(case_insensitive_compare("", "")); - ASSERT_TRUE(case_insensitive_compare("abc", "ABC")); - ASSERT_TRUE(case_insensitive_compare("abc123!@", "ABC123!@")); - - ASSERT_FALSE(case_insensitive_compare("abc", "ABCD")); - ASSERT_FALSE(case_insensitive_compare("abce", "ABCD")); -} - -TEST(case_insensitive_hash_functor, basic_hash_tests) -{ - case_insensitive_hash case_insensitive_hasher; - - ASSERT_EQ(0U, case_insensitive_hasher("")); - - ASSERT_EQ(case_insensitive_hasher("abc"), case_insensitive_hasher("ABC")); - ASSERT_EQ(case_insensitive_hasher("abc123!@"), case_insensitive_hasher("ABC123!@")); - ASSERT_NE(case_insensitive_hasher("abcd"), case_insensitive_hasher("ABC")); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/connection_impl_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/connection_impl_tests.cpp deleted file mode 100644 index afc68ee0c94a72c8eaecc64dba2c7ca74b516f1c..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/connection_impl_tests.cpp +++ /dev/null @@ -1,1878 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_utils.h" -#include "test_web_request_factory.h" -#include "test_websocket_client.h" -#include "test_transport_factory.h" -#include "connection_impl.h" -#include "signalrclient/trace_level.h" -#include "trace_log_writer.h" -#include "memory_log_writer.h" -#include "cpprest/ws_client.h" -#include "signalrclient/signalr_exception.h" -#include "signalrclient/web_exception.h" -#include "test_http_client.h" - -using namespace signalr; - -static std::shared_ptr<connection_impl> create_connection(std::shared_ptr<websocket_client> websocket_client = create_test_websocket_client(), - std::shared_ptr<log_writer> log_writer = std::make_shared<trace_log_writer>(), trace_level trace_level = trace_level::all) -{ - return connection_impl::create(create_uri(), trace_level, log_writer, create_test_http_client(), - std::make_unique<test_transport_factory>(websocket_client)); -} - -TEST(connection_impl_connection_state, initial_connection_state_is_disconnected) -{ - auto connection = - connection_impl::create(create_uri(), trace_level::none, std::make_shared<trace_log_writer>()); - - ASSERT_EQ(connection_state::disconnected, connection->get_connection_state()); -} - -TEST(connection_impl_start, cannot_start_non_disconnected_exception) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - try - { - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const signalr_exception& e) - { - ASSERT_STREQ("cannot start a connection that is not in the disconnected state", e.what()); - } -} - -TEST(connection_impl_start, connection_state_is_connecting_when_connection_is_being_started) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("", std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* send function */ [](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* connect function */[](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(std::make_exception_ptr(web::websockets::client::websocket_exception(_XPLATSTR("connecting failed")))); }); - - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - ASSERT_EQ(connection->get_connection_state(), connection_state::connecting); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) { } -} - -TEST(connection_impl_start, connection_state_is_connected_when_connection_established_succesfully) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client); - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - ASSERT_EQ(connection->get_connection_state(), connection_state::connected); -} - -TEST(connection_impl_start, connection_state_is_disconnected_when_connection_cannot_be_established) -{ - auto http_client = std::make_unique<test_http_client>([](const std::string&, http_request) - { - return http_response { 404, "" }; - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::none, std::make_shared<trace_log_writer>(), - std::move(http_client), std::make_unique<transport_factory>()); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) { } - - ASSERT_EQ(connection->get_connection_state(), connection_state::disconnected); -} - -TEST(connection_impl_start, throws_for_invalid_uri) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - - auto connection = connection_impl::create(":1\t ä bad_uri&a=b", trace_level::errors, writer, create_test_http_client(), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (const std::exception&) - { - // We shouldn't check the exact exception as it would be specific to the http library being used - } - - ASSERT_EQ(connection->get_connection_state(), connection_state::disconnected); -} - -TEST(connection_impl_start, start_sets_id_query_string) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - std::string query_string; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("", std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* send function */ [](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* connect function */[&query_string](const std::string& url, std::function<void(std::exception_ptr)> callback) - { - query_string = utility::conversions::to_utf8string(url.substr(url.find('?') + 1)); - callback(std::make_exception_ptr(web::websockets::client::websocket_exception("connecting failed"))); - }); - - auto connection = connection_impl::create(create_uri(""), trace_level::errors, writer, create_test_http_client(), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) { } - - ASSERT_EQ("id=f7707523-307d-4cba-9abf-3eef701241e8", query_string); -} - -TEST(connection_impl_start, start_appends_id_query_string) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - std::string query_string; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("", std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* send function */ [](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* connect function */[&query_string](const std::string& url, std::function<void(std::exception_ptr)> callback) - { - query_string = utility::conversions::to_utf8string(url.substr(url.find('?') + 1)); - callback(std::make_exception_ptr(web::websockets::client::websocket_exception(_XPLATSTR("connecting failed")))); - }); - - auto connection = connection_impl::create(create_uri("a=b&c=d"), trace_level::errors, writer, create_test_http_client(), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) { } - - ASSERT_EQ("a=b&c=d&id=f7707523-307d-4cba-9abf-3eef701241e8", query_string); -} - -TEST(connection_impl_start, start_logs_exceptions) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string&, http_request) - { - return http_response{ 404, "" }; - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::errors, writer, - std::move(http_client), std::make_unique<transport_factory>()); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) { } - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_FALSE(log_entries.empty()); - - auto entry = remove_date_from_log_entry(log_entries[0]); - ASSERT_EQ("[error ] connection could not be started due to: negotiate failed with status code 404\n", entry); -} - - -TEST(connection_impl_start, start_propagates_exceptions_from_negotiate) -{ - auto http_client = std::make_unique<test_http_client>([](const std::string&, http_request) - { - return http_response{ 404, "" }; - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::none, std::make_shared<trace_log_writer>(), - std::move(http_client), std::make_unique<transport_factory>()); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const std::exception &e) - { - ASSERT_STREQ("negotiate failed with status code 404", e.what()); - } -} - -TEST(connection_impl_start, start_fails_if_transport_connect_throws) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("", std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* send function */ [](const std::string&, std::function<void(std::exception_ptr)> callback){ callback(std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* connect function */[](const std::string&, std::function<void(std::exception_ptr)> callback) - { - callback(std::make_exception_ptr(web::websockets::client::websocket_exception(_XPLATSTR("connecting failed")))); - }); - - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const std::exception &e) - { - ASSERT_EQ(_XPLATSTR("connecting failed"), utility::conversions::to_string_t(e.what())); - } - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_TRUE(log_entries.size() > 1); - - auto entry = remove_date_from_log_entry(log_entries[1]); - ASSERT_EQ("[error ] transport could not connect due to: connecting failed\n", entry); -} - -#if defined(_WIN32) // https://github.com/aspnet/SignalR-Client-Cpp/issues/131 - -TEST(connection_impl_send, send_fails_if_transport_fails_when_receiving_messages) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto websocket_client = create_test_websocket_client([](std::function<void(std::string, std::exception_ptr)> callback) { callback("", nullptr); }, - /* send function */ [](const std::string &, std::function<void(std::exception_ptr)> callback) - { - callback(std::make_exception_ptr(std::runtime_error("send error"))); - }); - - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->send("message", [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const std::exception &e) - { - ASSERT_STREQ("send error", e.what()); - } - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_TRUE(log_entries.size() == 1) << dump_vector(log_entries); - - auto entry = remove_date_from_log_entry(log_entries[0]); - ASSERT_EQ("[error ] error sending data: send error\n", entry) << dump_vector(log_entries); -} - -#endif - -TEST(connection_impl_start, start_fails_if_negotiate_request_fails) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string&, http_request) - { - return http_response{ 400, "" }; - }); - - auto websocket_client = std::make_shared<test_websocket_client>(); - websocket_client->set_receive_function([](std::function<void(std::string, std::exception_ptr)> callback) - { - callback("{ }\x1e", nullptr); - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const std::exception &e) - { - ASSERT_STREQ("negotiate failed with status code 400", e.what()); - } -} - -TEST(connection_impl_start, start_fails_if_negotiate_response_has_error) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - auto response_body = - url.find("/negotiate") != std::string::npos - ? "{ \"error\": \"bad negotiate\" }" - : ""; - - return http_response{ 200, response_body }; - }); - - pplx::task_completion_event<void> tce; - auto websocket_client = std::make_shared<test_websocket_client>(); - websocket_client->set_connect_function([tce](const std::string&, std::function<void(std::exception_ptr)> callback) - { - pplx::task<void>(tce) - .then([callback](pplx::task<void> prev_task) - { - prev_task.get(); - callback(nullptr); - }); - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const signalr_exception & e) - { - ASSERT_STREQ("bad negotiate", e.what()); - } - - tce.set(); -} - -TEST(connection_impl_start, start_fails_if_negotiate_response_does_not_have_websockets) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - auto response_body = - url.find("/negotiate") != std::string::npos - ? "{ \"availableTransports\": [ { \"transport\": \"ServerSentEvents\", \"transferFormats\": [ \"Text\" ] } ] }" - : ""; - - return http_response{ 200, response_body }; - }); - - pplx::task_completion_event<void> tce; - auto websocket_client = std::make_shared<test_websocket_client>(); - websocket_client->set_connect_function([tce](const std::string&, std::function<void(std::exception_ptr)> callback) - { - pplx::task<void>(tce) - .then([callback](pplx::task<void> prev_task) - { - prev_task.get(); - callback(nullptr); - }); - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const signalr_exception & e) - { - ASSERT_STREQ("The server does not support WebSockets which is currently the only transport supported by this client.", e.what()); - } - - tce.set(); -} - -TEST(connection_impl_start, start_fails_if_negotiate_response_does_not_have_transports) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - auto response_body = - url.find("/negotiate") != std::string::npos - ? "{ \"availableTransports\": [ ] }" - : ""; - - return http_response{ 200, response_body }; - }); - - pplx::task_completion_event<void> tce; - auto websocket_client = std::make_shared<test_websocket_client>(); - websocket_client->set_connect_function([tce](const std::string&, std::function<void(std::exception_ptr)> callback) - { - pplx::task<void>(tce) - .then([callback](pplx::task<void> prev_task) - { - prev_task.get(); - callback(nullptr); - }); - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const signalr_exception & e) - { - ASSERT_STREQ("The server does not support WebSockets which is currently the only transport supported by this client.", e.what()); - } - - tce.set(); -} - -TEST(connection_impl_start, start_fails_if_negotiate_response_is_invalid) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - auto response_body = - url.find("/negotiate") != std::string::npos - ? "{ \"availableTransports\": [ " - : ""; - - return http_response{ 200, response_body }; - }); - - pplx::task_completion_event<void> tce; - auto websocket_client = std::make_shared<test_websocket_client>(); - websocket_client->set_connect_function([tce](const std::string&, std::function<void(std::exception_ptr)> callback) - { - pplx::task<void>(tce) - .then([callback](pplx::task<void> prev_task) - { - prev_task.get(); - callback(nullptr); - }); - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const std::exception & e) - { - ASSERT_STREQ("* Line 1, Column 28 Syntax error: Malformed token", e.what()); - } - - tce.set(); -} - -TEST(connection_impl_start, negotiate_follows_redirect) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - std::string response_body = ""; - if (url.find("/negotiate") != std::string::npos) - { - if (url.find("redirected") != std::string::npos) - { - response_body = "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }"; - } - else - { - response_body = "{ \"url\": \"http://redirected\" }"; - } - } - - return http_response{ 200, response_body }; - }); - - auto websocket_client = std::make_shared<test_websocket_client>(); - - std::string connectUrl; - websocket_client->set_connect_function([&connectUrl](const std::string& url, std::function<void(std::exception_ptr)> callback) - { - connectUrl = url; - callback(nullptr); - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ("ws://redirected/?id=f7707523-307d-4cba-9abf-3eef701241e8", connectUrl); -} - -TEST(connection_impl_start, negotiate_redirect_uses_accessToken) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - std::string accessToken; - - auto http_client = std::make_unique<test_http_client>([&accessToken](const std::string& url, http_request request) - { - std::string response_body = ""; - if (url.find("/negotiate") != std::string::npos) - { - if (url.find("redirected") != std::string::npos) - { - response_body = "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }"; - } - else - { - response_body = "{ \"url\": \"http://redirected\", \"accessToken\": \"secret\" }"; - } - } - - accessToken = request.headers["Authorization"]; - return http_response{ 200, response_body }; - }); - - auto websocket_client = std::make_shared<test_websocket_client>(); - - std::string connectUrl; - websocket_client->set_connect_function([&connectUrl](const std::string& url, std::function<void(std::exception_ptr)> callback) - { - connectUrl = url; - callback(nullptr); - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ("ws://redirected/?id=f7707523-307d-4cba-9abf-3eef701241e8", connectUrl); - ASSERT_EQ("Bearer secret", accessToken); -} - -TEST(connection_impl_start, negotiate_fails_after_too_many_redirects) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - std::string response_body = ""; - if (url.find("/negotiate") != std::string::npos) - { - // infinite redirect - response_body = "{ \"url\": \"http://redirected\" }"; - } - - return http_response{ 200, response_body }; - }); - - auto websocket_client = std::make_shared<test_websocket_client>(); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (signalr_exception e) - { - ASSERT_STREQ("Negotiate redirection limit exceeded.", e.what()); - } -} - -TEST(connection_impl_start, negotiate_fails_if_ProtocolVersion_in_response) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - std::string response_body = ""; - if (url.find("/negotiate") != std::string::npos) - { - response_body = "{\"ProtocolVersion\" : \"\" }"; - } - - return http_response{ 200, response_body }; - }); - - auto websocket_client = std::make_shared<test_websocket_client>(); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - } - catch (signalr_exception e) - { - ASSERT_STREQ("Detected a connection attempt to an ASP.NET SignalR Server. This client only supports connecting to an ASP.NET Core SignalR Server. See https://aka.ms/signalr-core-differences for details.", e.what()); - } -} - -TEST(connection_impl_start, negotiate_redirect_does_not_overwrite_url) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - int redirectCount = 0; - - auto http_client = std::make_unique<test_http_client>([&redirectCount](const std::string& url, http_request) - { - std::string response_body = ""; - if (url.find("/negotiate") != std::string::npos) - { - if (url.find("redirected") != std::string::npos) - { - response_body = "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }"; - } - else - { - response_body = "{ \"url\": \"http://redirected\" }"; - redirectCount++; - } - } - - return http_response{ 200, response_body }; - }); - - auto websocket_client = std::make_shared<test_websocket_client>(); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - ASSERT_EQ(1, redirectCount); - - connection->stop([&mre](std::exception_ptr) - { - mre.set(); - }); - mre.get(); - - connection->start([&mre](std::exception_ptr) - { - mre.set(); - }); - mre.get(); - ASSERT_EQ(2, redirectCount); -} - -TEST(connection_impl_start, negotiate_redirect_uses_own_query_string) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - std::string query_string; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("", std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* send function */ [](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* connect function */[&query_string](const std::string& url, std::function<void(std::exception_ptr)> callback) - { - query_string = url.substr(url.find('?') + 1); - callback(std::make_exception_ptr(web::websockets::client::websocket_exception(_XPLATSTR("connecting failed")))); - }); - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - std::string response_body = ""; - if (url.find("/negotiate") != std::string::npos) - { - if (url.find("redirected") != std::string::npos) - { - response_body = "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }"; - } - else - { - response_body = "{ \"url\": \"http://redirected?customQuery=1\" }"; - } - } - - return http_response{ 200, response_body }; - }); - - auto connection = connection_impl::create(create_uri("a=b&c=d"), trace_level::errors, writer, std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - } - catch (...) - { - } - - ASSERT_EQ("customQuery=1&id=f7707523-307d-4cba-9abf-3eef701241e8", query_string); -} - -TEST(connection_impl_start, start_fails_if_connect_request_times_out) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto http_client = create_test_http_client(); - - pplx::task_completion_event<void> tce; - auto websocket_client = std::make_shared<test_websocket_client>(); - websocket_client->set_connect_function([tce](const std::string&, std::function<void(std::exception_ptr)> callback) - { - pplx::task<void>(tce) - .then([callback](pplx::task<void> prev_task) - { - prev_task.get(); - callback(nullptr); - }); - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::messages, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const signalr_exception &e) - { - ASSERT_STREQ("transport timed out when trying to connect", e.what()); - } - - tce.set(); -} - -TEST(connection_impl_process_response, process_response_logs_messages) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - auto wait_receive = std::make_shared<event>(); - auto websocket_client = create_test_websocket_client( - /* receive function */ [wait_receive](std::function<void(std::string, std::exception_ptr)> callback) - { - wait_receive->set(); - callback("{ }", nullptr); - }); - auto connection = create_connection(websocket_client, writer, trace_level::messages); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - // Need to give the receive loop time to run - std::make_shared<event>()->wait(1000); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_FALSE(log_entries.empty()); - - auto entry = remove_date_from_log_entry(log_entries[0]); - ASSERT_EQ("[message ] processing message: { }\n", entry); -} - -TEST(connection_impl_send, message_sent) -{ - std::string actual_message; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }, - /* send function */ [&actual_message](const std::string& message, std::function<void(std::exception_ptr)> callback) - { - actual_message = message; - callback(nullptr); - }); - - auto connection = create_connection(websocket_client); - - const std::string message{ "Test message" }; - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->send(message, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ(message, actual_message); -} - -TEST(connection_impl_send, send_throws_if_connection_not_connected) -{ - auto connection = - connection_impl::create(create_uri(), trace_level::none, std::make_shared<trace_log_writer>()); - - auto mre = manual_reset_event<void>(); - connection->send("whatever", [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const signalr_exception &e) - { - ASSERT_STREQ("cannot send data when the connection is not in the connected state. current connection state: disconnected", e.what()); - } -} - -TEST(connection_impl_send, exceptions_from_send_logged_and_propagated) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) - { - callback("{}", nullptr); - }, - /* send function */ [](const std::string&, std::function<void(std::exception_ptr)> callback) - { - callback(std::make_exception_ptr(std::runtime_error("error"))); - }); - - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->send("Test message", [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const std::runtime_error &e) - { - ASSERT_STREQ("error", e.what()); - } - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_FALSE(log_entries.empty()); - - auto entry = remove_date_from_log_entry(log_entries[0]); - ASSERT_EQ("[error ] error sending data: error\n", entry); -} - -TEST(connection_impl_set_message_received, callback_invoked_when_message_received) -{ - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "Test", - "release", - "{}" - }; - - call_number = std::min(call_number + 1, 2); - - callback(responses[call_number], nullptr); - }); - - auto connection = create_connection(websocket_client); - - auto message = std::make_shared<std::string>(); - - auto message_received_event = std::make_shared<event>(); - connection->set_message_received([message, message_received_event](const std::string &m) - { - if (m == "Test") - { - *message = m; - } - - if (m == "release") - { - message_received_event->set(); - } - }); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(message_received_event->wait(5000)); - - ASSERT_EQ("Test", *message); -} - -TEST(connection_impl_set_message_received, exception_from_callback_caught_and_logged) -{ - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "throw", - "release", - "{}" - }; - - call_number = std::min(call_number + 1, 2); - - callback(responses[call_number], nullptr); - }); - - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - auto message_received_event = std::make_shared<event>(); - connection->set_message_received([message_received_event](const std::string &m) - { - if (m == "throw") - { - throw std::runtime_error("oops"); - } - - if (m == "release") - { - message_received_event->set(); - } - }); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(message_received_event->wait(5000)); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_FALSE(log_entries.empty()); - - auto entry = remove_date_from_log_entry(log_entries[0]); - ASSERT_EQ("[error ] message_received callback threw an exception: oops\n", entry); -} - -TEST(connection_impl_set_message_received, non_std_exception_from_callback_caught_and_logged) -{ - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "throw", - "release", - "{}" - }; - - call_number = std::min(call_number + 1, 2); - - callback(responses[call_number], nullptr); - }); - - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - auto message_received_event = std::make_shared<event>(); - connection->set_message_received([message_received_event](const std::string &m) - { - if (m == "throw") - { - throw 42; - } - - if (m == "release") - { - message_received_event->set(); - } - }); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(message_received_event->wait(5000)); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_FALSE(log_entries.empty()); - - auto entry = remove_date_from_log_entry(log_entries[0]); - ASSERT_EQ("[error ] message_received callback threw an unknown exception\n", entry); -} - -void can_be_set_only_in_disconnected_state(std::function<void(connection_impl *)> callback, const char* expected_exception_message) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - try - { - callback(connection.get()); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const signalr_exception &e) - { - ASSERT_STREQ(expected_exception_message, e.what()); - } -} - -TEST(connection_impl_set_configuration, set_message_received_callback_can_be_set_only_in_disconnected_state) -{ - can_be_set_only_in_disconnected_state( - [](connection_impl* connection) { connection->set_message_received([](const std::string&){}); }, - "cannot set the callback when the connection is not in the disconnected state. current connection state: connected"); -} - -TEST(connection_impl_set_configuration, set_disconnected_callback_can_be_set_only_in_disconnected_state) -{ - can_be_set_only_in_disconnected_state( - [](connection_impl* connection) { connection->set_disconnected([](){}); }, - "cannot set the disconnected callback when the connection is not in the disconnected state. current connection state: connected"); -} - -TEST(connection_impl_stop, stopping_disconnected_connection_is_no_op) -{ - std::shared_ptr<log_writer> writer{ std::make_shared<memory_log_writer>() }; - auto connection = connection_impl::create(create_uri(), trace_level::all, writer); - auto mre = manual_reset_event<void>(); - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ(connection_state::disconnected, connection->get_connection_state()); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_EQ(2U, log_entries.size()); - ASSERT_EQ("[info ] stopping connection\n", remove_date_from_log_entry(log_entries[0])); - ASSERT_EQ("[info ] acquired lock in shutdown()\n", remove_date_from_log_entry(log_entries[1])); -} - -TEST(connection_impl_stop, stopping_disconnecting_connection_returns_cancelled_task) -{ - event close_event; - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }, - /* send function */ [](const std::string, std::function<void(std::exception_ptr)> callback){ callback(std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* connect function */ [&close_event](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(nullptr); }, - /* close function */ [&close_event](std::function<void(std::exception_ptr)> callback) - { - pplx::create_task([&close_event, callback]() - { - close_event.wait(); - callback(nullptr); - }); - }); - - auto connection = create_connection(websocket_client, writer, trace_level::state_changes); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - auto mre_stop = manual_reset_event<void>(); - connection->stop([&mre_stop](std::exception_ptr exception) - { - mre_stop.set(exception); - }); - - mre_stop.get(); - ASSERT_FALSE(true); // exception expected but not thrown - } - catch (const pplx::task_canceled&) - { } - - close_event.set(); - mre.get(); - - ASSERT_EQ(connection_state::disconnected, connection->get_connection_state()); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_EQ(4U, log_entries.size()); - ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[0])); - ASSERT_EQ("[state change] connecting -> connected\n", remove_date_from_log_entry(log_entries[1])); - ASSERT_EQ("[state change] connected -> disconnecting\n", remove_date_from_log_entry(log_entries[2])); - ASSERT_EQ("[state change] disconnecting -> disconnected\n", remove_date_from_log_entry(log_entries[3])); -} - -TEST(connection_impl_stop, can_start_and_stop_connection) -{ - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client, writer, trace_level::state_changes); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_EQ(4U, log_entries.size()); - ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[0])); - ASSERT_EQ("[state change] connecting -> connected\n", remove_date_from_log_entry(log_entries[1])); - ASSERT_EQ("[state change] connected -> disconnecting\n", remove_date_from_log_entry(log_entries[2])); - ASSERT_EQ("[state change] disconnecting -> disconnected\n", remove_date_from_log_entry(log_entries[3])); -} - -TEST(connection_impl_stop, can_start_and_stop_connection_multiple_times) -{ - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - - { - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client, writer, trace_level::state_changes); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - } - - auto memory_writer = std::dynamic_pointer_cast<memory_log_writer>(writer); - - // The connection_impl will be destroyed when the last reference to shared_ptr holding is released. This can happen - // on a different thread in which case the dtor will be invoked on a different thread so we need to wait for this - // to happen and if it does not the test will fail - for (int wait_time_ms = 5; wait_time_ms < 100 && memory_writer->get_log_entries().size() < 8; wait_time_ms <<= 1) - { - std::this_thread::sleep_for(std::chrono::milliseconds(wait_time_ms)); - } - - auto log_entries = memory_writer->get_log_entries(); - ASSERT_EQ(8U, log_entries.size()); - ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[0])); - ASSERT_EQ("[state change] connecting -> connected\n", remove_date_from_log_entry(log_entries[1])); - ASSERT_EQ("[state change] connected -> disconnecting\n", remove_date_from_log_entry(log_entries[2])); - ASSERT_EQ("[state change] disconnecting -> disconnected\n", remove_date_from_log_entry(log_entries[3])); - ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[4])); - ASSERT_EQ("[state change] connecting -> connected\n", remove_date_from_log_entry(log_entries[5])); - ASSERT_EQ("[state change] connected -> disconnecting\n", remove_date_from_log_entry(log_entries[6])); - ASSERT_EQ("[state change] disconnecting -> disconnected\n", remove_date_from_log_entry(log_entries[7])); -} - -TEST(connection_impl_stop, dtor_stops_the_connection) -{ - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - - { - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) - { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - callback("{ }\x1e", nullptr); - }); - auto connection = create_connection(websocket_client, writer, trace_level::state_changes); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - } - - auto memory_writer = std::dynamic_pointer_cast<memory_log_writer>(writer); - - // The connection_impl will be destroyed when the last reference to shared_ptr holding is released. This can happen - // on a different thread in which case the dtor will be invoked on a different thread so we need to wait for this - // to happen and if it does not the test will fail - for (int wait_time_ms = 5; wait_time_ms < 100 && memory_writer->get_log_entries().size() < 4; wait_time_ms <<= 1) - { - std::this_thread::sleep_for(std::chrono::milliseconds(wait_time_ms)); - } - - auto log_entries = memory_writer->get_log_entries(); - ASSERT_EQ(4U, log_entries.size()); - ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[0])); - ASSERT_EQ("[state change] connecting -> connected\n", remove_date_from_log_entry(log_entries[1])); - ASSERT_EQ("[state change] connected -> disconnecting\n", remove_date_from_log_entry(log_entries[2])); - ASSERT_EQ("[state change] disconnecting -> disconnected\n", remove_date_from_log_entry(log_entries[3])); -} - -TEST(connection_impl_stop, stop_cancels_ongoing_start_request) -{ - auto disconnect_completed_event = std::make_shared<event>(); - - auto websocket_client = create_test_websocket_client( - /* receive function */ [disconnect_completed_event](std::function<void(std::string, std::exception_ptr)> callback) - { - disconnect_completed_event->wait(); - callback("{ }\x1e", nullptr); - }); - - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - auto connection = create_connection(std::make_shared<test_websocket_client>(), writer, trace_level::all); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - connection->stop([disconnect_completed_event](std::exception_ptr) - { - disconnect_completed_event->set(); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const pplx::task_canceled &) - { } - - ASSERT_EQ(connection_state::disconnected, connection->get_connection_state()); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_EQ(5U, log_entries.size()); - ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[0])); - ASSERT_EQ("[info ] stopping connection\n", remove_date_from_log_entry(log_entries[1])); - ASSERT_EQ("[info ] acquired lock in shutdown()\n", remove_date_from_log_entry(log_entries[2])); - ASSERT_EQ("[info ] starting the connection has been canceled.\n", remove_date_from_log_entry(log_entries[3])); - ASSERT_EQ("[state change] connecting -> disconnected\n", remove_date_from_log_entry(log_entries[4])); -} - -TEST(connection_impl_stop, ongoing_start_request_canceled_if_connection_stopped_before_init_message_received) -{ - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - auto response_body = - url.find("/negotiate") != std::string::npos - ? "{ \"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }" - : ""; - - return http_response{ 200, response_body }; - }); - - auto websocket_client = create_test_websocket_client(/*receive function*/ [](std::function<void(std::string, std::exception_ptr)> callback) - { - callback("{}", nullptr); - }); - - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - auto connection = connection_impl::create(create_uri(), trace_level::all, writer, - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - connection->stop([](std::exception_ptr) - { - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const pplx::task_canceled &) - { } - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_EQ(5U, log_entries.size()) << dump_vector(log_entries); - ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[0])); - ASSERT_EQ("[info ] stopping connection\n", remove_date_from_log_entry(log_entries[1])); - ASSERT_EQ("[info ] acquired lock in shutdown()\n", remove_date_from_log_entry(log_entries[2])); - ASSERT_EQ("[info ] starting the connection has been canceled.\n", remove_date_from_log_entry(log_entries[3])); - ASSERT_EQ("[state change] connecting -> disconnected\n", remove_date_from_log_entry(log_entries[4])); -} - -TEST(connection_impl_stop, stop_invokes_disconnected_callback) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client); - - auto disconnected_invoked = false; - connection->set_disconnected([&disconnected_invoked](){ disconnected_invoked = true; }); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_TRUE(disconnected_invoked); -} - -TEST(connection_impl_stop, std_exception_for_disconnected_callback_caught_and_logged) -{ - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{}" - }; - - call_number = std::min(call_number + 1, 1); - - callback(responses[call_number], nullptr); - }); - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - connection->set_disconnected([](){ throw std::runtime_error("exception from disconnected"); }); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_EQ(1U, log_entries.size()); - ASSERT_EQ("[error ] disconnected callback threw an exception: exception from disconnected\n", remove_date_from_log_entry(log_entries[0])); -} - -TEST(connection_impl_stop, exception_for_disconnected_callback_caught_and_logged) -{ - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{}" - }; - - call_number = std::min(call_number + 1, 1); - - callback(responses[call_number], nullptr); - }); - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - connection->set_disconnected([](){ throw 42; }); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_EQ(1U, log_entries.size()); - ASSERT_EQ("[error ] disconnected callback threw an unknown exception\n", remove_date_from_log_entry(log_entries[0])); -} - -TEST(connection_impl_config, custom_headers_set_in_requests) -{ - auto writer = std::shared_ptr<log_writer>{std::make_shared<memory_log_writer>()}; - - auto http_client = std::make_unique<test_http_client>([](const std::string& url, http_request) - { - auto response_body = - url.find("/negotiate") != std::string::npos - ? "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }" - : ""; - - /*auto request = new web_request_stub((unsigned short)200, "OK", response_body); - request->on_get_response = [](web_request_stub& request) - { - auto http_headers = request.m_signalr_client_config.get_http_headers(); - ASSERT_EQ(1U, http_headers.size()); - ASSERT_EQ(_XPLATSTR("42"), http_headers[_XPLATSTR("Answer")]); - };*/ - - return http_response{ 200, response_body }; - }); - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - - auto connection = - connection_impl::create(create_uri(), trace_level::state_changes, - writer, std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - signalr::signalr_client_config signalr_client_config{}; - auto http_headers = signalr_client_config.get_http_headers(); - http_headers[_XPLATSTR("Answer")] = _XPLATSTR("42"); - signalr_client_config.set_http_headers(http_headers); - connection->set_client_config(signalr_client_config); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ(connection_state::disconnected, connection->get_connection_state()); -} - -TEST(connection_impl_set_config, config_can_be_set_only_in_disconnected_state) -{ - can_be_set_only_in_disconnected_state( - [](connection_impl* connection) - { - signalr::signalr_client_config signalr_client_config; - connection->set_client_config(signalr_client_config); - },"cannot set client config when the connection is not in the disconnected state. current connection state: connected"); -} - -TEST(connection_impl_change_state, change_state_logs) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client, writer, trace_level::state_changes); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_FALSE(log_entries.empty()); - - auto entry = remove_date_from_log_entry(log_entries[0]); - ASSERT_EQ("[state change] disconnected -> connecting\n", entry); -} - -TEST(connection_id, connection_id_is_set_if_start_fails_but_negotiate_request_succeeds) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback){ callback("", std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* send function */ [](const std::string, std::function<void(std::exception_ptr)> callback){ callback(std::make_exception_ptr(std::runtime_error("should not be invoked"))); }, - /* connect function */[](const std::string&, std::function<void(std::exception_ptr)> callback) - { - callback(std::make_exception_ptr(web::websockets::client::websocket_exception(_XPLATSTR("connecting failed")))); - }); - - auto connection = create_connection(websocket_client, writer, trace_level::errors); - - ASSERT_EQ("", connection->get_connection_id()); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) { } - - ASSERT_EQ("f7707523-307d-4cba-9abf-3eef701241e8", connection->get_connection_id()); -} - -TEST(connection_id, can_get_connection_id_when_connection_in_connected_state) -{ - auto writer = std::shared_ptr<log_writer>{ std::make_shared<memory_log_writer>() }; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback){ callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client, writer, trace_level::state_changes); - - std::string connection_id; - auto mre = manual_reset_event<void>(); - connection->start([&mre, &connection_id, connection](std::exception_ptr exception) - { - connection_id = connection->get_connection_id(); - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ("f7707523-307d-4cba-9abf-3eef701241e8", connection_id); -} - -TEST(connection_id, can_get_connection_id_after_connection_has_stopped) -{ - auto writer = std::shared_ptr<log_writer>{ std::make_shared<memory_log_writer>() }; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback){ callback("{ }\x1e", nullptr); }); - auto connection = create_connection(websocket_client, writer, trace_level::state_changes); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ("f7707523-307d-4cba-9abf-3eef701241e8", connection->get_connection_id()); -} - -TEST(connection_id, connection_id_reset_when_starting_connection) -{ - auto fail_http_requests = false; - - auto writer = std::shared_ptr<log_writer>{ std::make_shared<memory_log_writer>() }; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback){ callback("{ }\x1e", nullptr); }); - - auto http_client = std::make_unique<test_http_client>([&fail_http_requests](const std::string& url, http_request) - { - if (!fail_http_requests) { - auto response_body = - url.find("/negotiate") != std::string::npos - ? "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }" - : ""; - - return http_response{ 200, response_body }; - } - - return http_response{ 500, "" }; - }); - - auto connection = - connection_impl::create(create_uri(), trace_level::none, std::make_shared<trace_log_writer>(), - std::move(http_client), std::make_unique<test_transport_factory>(websocket_client)); - - auto mre = manual_reset_event<void>(); - connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ("f7707523-307d-4cba-9abf-3eef701241e8", connection->get_connection_id()); - - fail_http_requests = true; - - connection->start([&mre](std::exception_ptr) - { - mre.set(); - }); - - mre.get(); - - ASSERT_EQ("", connection->get_connection_id()); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/http_sender_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/http_sender_tests.cpp deleted file mode 100644 index 683687f0dc63a8a45f46eeaaf9203b7b1c4a5b8b..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/http_sender_tests.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "cpprest/details/basic_types.h" -#include "cpprest/asyncrt_utils.h" -#include "signalrclient/web_exception.h" -#include "http_sender.h" -#include "web_request_stub.h" -#include "test_web_request_factory.h" - -TEST(http_sender_get_response, request_sent_using_get_method) -{ - std::string response_body{ "response body" }; - - auto web_request_factory = std::make_unique<test_web_request_factory>([response_body](const std::string &) -> std::unique_ptr<web_request> - { - auto request = new web_request_stub((unsigned short)200, "OK", response_body); - request->on_get_response = [](web_request_stub& request) { ASSERT_EQ("GET", request.m_method); }; - - return std::unique_ptr<web_request>(request); - }); - - ASSERT_EQ(response_body, http_sender::get(*web_request_factory, "url").get()); -} - -TEST(http_sender_get_response, exception_thrown_if_status_code_not_200) -{ - std::string response_phrase("Custom Not Found"); - - auto web_request_factory = std::make_unique<test_web_request_factory>([response_phrase](const std::string &) -> std::unique_ptr<web_request> - { - return std::unique_ptr<web_request>(new web_request_stub((unsigned short)404, response_phrase)); - }); - - try - { - http_sender::get(*web_request_factory, "url").get(); - ASSERT_TRUE(false); // exception not thrown - } - catch (const web_exception &e) - { - ASSERT_EQ( - "web exception - 404 " + response_phrase, - e.what()); - ASSERT_EQ(404, e.status_code()); - } -} - -TEST(http_sender_get_response, user_agent_set) -{ - std::string response_body{ "response body" }; - - auto web_request_factory = std::make_unique<test_web_request_factory>([response_body](const std::string &) -> std::unique_ptr<web_request> - { - auto request = new web_request_stub((unsigned short)200, "OK", response_body); - request->on_get_response = [](web_request_stub& request) - { - ASSERT_EQ("SignalR.Client.Cpp/0.1.0-alpha0", request.m_user_agent_string); - }; - - return std::unique_ptr<web_request>(request); - }); - - ASSERT_EQ(response_body, http_sender::get(*web_request_factory, "url").get()); -} - -TEST(http_sender_get_response, headers_set) -{ - std::string response_body{ "response body" }; - - auto web_request_factory = std::make_unique<test_web_request_factory>([response_body](const std::string &) -> std::unique_ptr<web_request> - { - auto request = new web_request_stub((unsigned short)200, "OK", response_body); - request->on_get_response = [](web_request_stub& request) - { - auto http_headers = request.m_signalr_client_config.get_http_headers(); - ASSERT_EQ(1U, http_headers.size()); - ASSERT_EQ(_XPLATSTR("123"), http_headers[_XPLATSTR("abc")]); - }; - - return std::unique_ptr<web_request>(request); - }); - - signalr::signalr_client_config signalr_client_config; - auto http_headers = signalr_client_config.get_http_headers(); - http_headers[_XPLATSTR("abc")] = _XPLATSTR("123"); - signalr_client_config.set_http_headers(http_headers); - - // ensures that web_request.get_response() was invoked - ASSERT_EQ(response_body, http_sender::get(*web_request_factory, "url", signalr_client_config).get()); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/hub_connection_impl_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/hub_connection_impl_tests.cpp deleted file mode 100644 index 39e146f915dd32097b528ddc552756c15a7f1f84..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/hub_connection_impl_tests.cpp +++ /dev/null @@ -1,980 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_utils.h" -#include "test_transport_factory.h" -#include "test_http_client.h" -#include "hub_connection_impl.h" -#include "trace_log_writer.h" -#include "memory_log_writer.h" -#include "signalrclient/hub_exception.h" -#include "signalrclient/signalr_exception.h" - -using namespace signalr; - -std::shared_ptr<hub_connection_impl> create_hub_connection(std::shared_ptr<websocket_client> websocket_client = create_test_websocket_client(), - std::shared_ptr<log_writer> log_writer = std::make_shared<trace_log_writer>(), trace_level trace_level = trace_level::all) -{ - return hub_connection_impl::create(create_uri(), trace_level, log_writer, - create_test_http_client(), std::make_unique<test_transport_factory>(websocket_client)); -} - -TEST(url, negotiate_appended_to_url) -{ - std::string base_urls[] = { "http://fakeuri", "http://fakeuri/" }; - - for (const auto& base_url : base_urls) - { - std::string requested_url; - auto http_client = std::make_unique<test_http_client>([&requested_url](const std::string& url, http_request) - { - requested_url = url; - return http_response{ 404, "" }; - }); - - auto hub_connection = hub_connection_impl::create(base_url, trace_level::none, - std::make_shared<trace_log_writer>(), std::move(http_client), - std::make_unique<test_transport_factory>(create_test_websocket_client())); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (const std::exception&) {} - - ASSERT_EQ("http://fakeuri/negotiate", requested_url); - } -} - -TEST(start, start_starts_connection) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ(connection_state::connected, hub_connection->get_connection_state()); -} - -TEST(start, start_sends_handshake) -{ - auto message = std::make_shared<std::string>(); - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }, - /* send function */ [message](const std::string& msg, std::function<void(std::exception_ptr)> callback) { *message = msg; callback(nullptr); }); - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ("{\"protocol\":\"json\",\"version\":1}\x1e", *message); - - ASSERT_EQ(connection_state::connected, hub_connection->get_connection_state()); -} - -TEST(start, start_waits_for_handshake_response) -{ - pplx::task_completion_event<void> tce; - pplx::task_completion_event<void> tceWaitForSend; - auto websocket_client = create_test_websocket_client( - /* receive function */ [tce, tceWaitForSend](std::function<void(std::string, std::exception_ptr)> callback) - { - tceWaitForSend.set(); - pplx::task<void>(tce).get(); - callback("{ }\x1e", nullptr); - }); - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - auto done = false; - hub_connection->start([&mre, &done](std::exception_ptr exception) - { - done = true; - mre.set(exception); - }); - - pplx::task<void>(tceWaitForSend).get(); - ASSERT_FALSE(done); - tce.set(); - mre.get(); - - ASSERT_EQ(connection_state::connected, hub_connection->get_connection_state()); -} - -TEST(start, start_fails_for_handshake_response_with_error) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{\"error\":\"bad things\"}\x1e", nullptr); }); - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (const std::exception& ex) - { - ASSERT_STREQ("Received an error during handshake: bad things", ex.what()); - } - - ASSERT_EQ(connection_state::disconnected, hub_connection->get_connection_state()); -} - -TEST(start, start_fails_if_stop_called_before_handshake_response) -{ - pplx::task_completion_event<std::string> tce; - pplx::task_completion_event<void> tceWaitForSend; - auto websocket_client = create_test_websocket_client( - /* receive function */ [tce](std::function<void(std::string, std::exception_ptr)> callback) - { - auto str = pplx::task<std::string>(tce).get(); - callback(str, nullptr); - }, - /* send function */ [tceWaitForSend](const std::string &, std::function<void(std::exception_ptr)> callback) - { - tceWaitForSend.set(); - callback(nullptr); - }); - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - pplx::task<void>(tceWaitForSend).get(); - hub_connection->stop([](std::exception_ptr) {}); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (std::exception ex) - { - ASSERT_STREQ("connection closed while handshake was in progress.", ex.what()); - } - - ASSERT_EQ(connection_state::disconnected, hub_connection->get_connection_state()); -} - -TEST(stop, stop_stops_connection) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ(connection_state::disconnected, hub_connection->get_connection_state()); -} - -TEST(stop, disconnected_callback_called_when_hub_connection_stops) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto hub_connection = create_hub_connection(websocket_client); - - auto disconnected_invoked = false; - hub_connection->set_disconnected([&disconnected_invoked]() { disconnected_invoked = true; }); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_TRUE(disconnected_invoked); -} - -TEST(stop, connection_stopped_when_going_out_of_scope) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - { - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto hub_connection = create_hub_connection(websocket_client, writer, trace_level::state_changes); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - } - - auto memory_writer = std::dynamic_pointer_cast<memory_log_writer>(writer); - - // The underlying connection_impl will be destroyed when the last reference to shared_ptr holding is released. This can happen - // on a different thread in which case the dtor will be invoked on a different thread so we need to wait for this - // to happen and if it does not the test will fail. There is nothing we can block on. - for (int wait_time_ms = 5; wait_time_ms < 100 && memory_writer->get_log_entries().size() < 4; wait_time_ms <<= 1) - { - std::this_thread::sleep_for(std::chrono::milliseconds(wait_time_ms)); - } - - auto log_entries = memory_writer->get_log_entries(); - ASSERT_EQ(4U, log_entries.size()) << dump_vector(log_entries); - ASSERT_EQ("[state change] disconnected -> connecting\n", remove_date_from_log_entry(log_entries[0])); - ASSERT_EQ("[state change] connecting -> connected\n", remove_date_from_log_entry(log_entries[1])); - ASSERT_EQ("[state change] connected -> disconnecting\n", remove_date_from_log_entry(log_entries[2])); - ASSERT_EQ("[state change] disconnecting -> disconnected\n", remove_date_from_log_entry(log_entries[3])); -} - -TEST(stop, stop_cancels_pending_callbacks) -{ - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{}" - }; - - if (call_number < 1) - { - call_number++; - } - - callback(responses[call_number], nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - auto invoke_mre = manual_reset_event<void>(); - hub_connection->invoke("method", json::value::array(), [&invoke_mre](const json::value&, std::exception_ptr exception) - { - invoke_mre.set(exception); - }); - - hub_connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - try - { - invoke_mre.get(); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const signalr_exception& e) - { - ASSERT_STREQ("\"connection was stopped before invocation result was received\"", e.what()); - } -} - -TEST(stop, pending_callbacks_finished_if_hub_connections_goes_out_of_scope) -{ - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{}" - }; - - if (call_number < 1) - { - call_number++; - } - - callback(responses[call_number], nullptr); - }); - - auto invoke_mre = manual_reset_event<void>(); - - { - auto hub_connection = create_hub_connection(websocket_client); - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->invoke("method", json::value::array(), [&invoke_mre](const json::value&, std::exception_ptr exception) - { - invoke_mre.set(exception); - }); - } - - try - { - invoke_mre.get(); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const signalr_exception& e) - { - ASSERT_STREQ("\"connection went out of scope before invocation result was received\"", e.what()); - } -} - -TEST(hub_invocation, hub_connection_invokes_users_code_on_hub_invocations) -{ - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{ \"type\": 1, \"target\": \"BROADcast\", \"arguments\": [ \"message\", 1 ] }\x1e" - }; - - call_number = std::min(call_number + 1, 1); - - callback(responses[call_number], nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - - auto payload = std::make_shared<std::string>(); - auto on_broadcast_event = std::make_shared<event>(); - hub_connection->on("broadCAST", [on_broadcast_event, payload](const json::value& message) - { - *payload = utility::conversions::to_utf8string(message.serialize()); - on_broadcast_event->set(); - }); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - ASSERT_FALSE(on_broadcast_event->wait(5000)); - - ASSERT_EQ("[\"message\",1]", *payload); -} - -TEST(send, creates_correct_payload) -{ - std::string payload; - bool handshakeReceived = false; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }, - /* send function */[&payload, &handshakeReceived](const std::string& m, std::function<void(std::exception_ptr)> callback) - { - if (handshakeReceived) - { - payload = m; - callback(nullptr); - return; - } - handshakeReceived = true; - callback(nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->send("method", json::value::array(), [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ("{\"arguments\":[],\"target\":\"method\",\"type\":1}\x1e", payload); -} - -TEST(send, does_not_wait_for_server_response) -{ - int call_number = -1; - pplx::task_completion_event<void> waitForSend; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [waitForSend, call_number](std::function<void(std::string, std::exception_ptr)> callback) mutable - { - std::string responses[] - { - "{ }\x1e", - "{}" - }; - - call_number = std::min(call_number + 1, 1); - - if (call_number == 1) - { - pplx::task<void>(waitForSend).get(); - } - - callback(responses[call_number], nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - // wont block waiting for server response - hub_connection->send("method", json::value::array(), [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - waitForSend.set(); -} - -TEST(invoke, creates_correct_payload) -{ - std::string payload; - bool handshakeReceived = false; - - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }, - /* send function */[&payload, &handshakeReceived](const std::string& m, std::function<void(std::exception_ptr)> callback) - { - if (handshakeReceived) - { - payload = m; - callback(std::make_exception_ptr(std::runtime_error("error"))); - return; - } - handshakeReceived = true; - callback(nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->invoke("method", json::value::array(), [&mre](const json::value&, std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) - { - // the invoke is not setup to succeed because it's not needed in this test - } - - ASSERT_EQ("{\"arguments\":[],\"invocationId\":\"0\",\"target\":\"method\",\"type\":1}\x1e", payload); -} - -TEST(invoke, callback_not_called_if_send_throws) -{ - bool handshakeReceived = false; - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }, - /* send function */[handshakeReceived](const std::string&, std::function<void(std::exception_ptr)> callback) mutable - { - if (handshakeReceived) - { - callback(std::make_exception_ptr(std::runtime_error("error"))); - return; - } - handshakeReceived = true; - callback(nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->invoke("method", json::value::array(), [&mre](const json::value&, std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const std::runtime_error& e) - { - ASSERT_STREQ("error", e.what()); - } - - // stop completes all outstanding callbacks so if we did not remove a callback when `invoke_void` failed an - // unobserved exception exception would be thrown. Note that this would happen on a different thread and would - // crash the process - hub_connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); -} - -TEST(invoke, invoke_returns_value_returned_from_the_server) -{ - auto callback_registered_event = std::make_shared<event>(); - - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number, callback_registered_event](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{ \"type\": 3, \"invocationId\": \"0\", \"result\": \"abc\" }\x1e" - }; - - call_number = std::min(call_number + 1, 1); - - if (call_number > 0) - { - callback_registered_event->wait(); - } - - callback(responses[call_number], nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - auto invoke_mre = manual_reset_event<json::value>(); - hub_connection->invoke("method", json::value::array(), [&invoke_mre](const json::value& message, std::exception_ptr exception) - { - if (exception) - { - invoke_mre.set(exception); - } - else - { - invoke_mre.set(message); - } - }); - - callback_registered_event->set(); - - auto result = invoke_mre.get(); - - ASSERT_EQ(_XPLATSTR("\"abc\""), result.serialize()); -} - -TEST(invoke, invoke_propagates_errors_from_server_as_hub_exceptions) -{ - auto callback_registered_event = std::make_shared<event>(); - - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number, callback_registered_event](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{ \"type\": 3, \"invocationId\": \"0\", \"error\": \"Ooops\" }\x1e" - }; - - call_number = std::min(call_number + 1, 1); - - if (call_number > 0) - { - callback_registered_event->wait(); - } - - callback(responses[call_number], nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->invoke("method", json::value::array(), [&mre](const json::value&, std::exception_ptr exception) - { - mre.set(exception); - }); - - callback_registered_event->set(); - - try - { - mre.get(); - - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const hub_exception& e) - { - ASSERT_STREQ("\"Ooops\"", e.what()); - } -} - -TEST(invoke, unblocks_task_when_server_completes_call) -{ - auto callback_registered_event = std::make_shared<event>(); - - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number, callback_registered_event](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{ \"type\": 3, \"invocationId\": \"0\" }\x1e" - }; - - call_number = std::min(call_number + 1, 1); - - if (call_number > 0) - { - callback_registered_event->wait(); - } - - callback(responses[call_number], nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->invoke("method", json::value::array(), [&mre](const json::value&, std::exception_ptr exception) - { - mre.set(exception); - }); - - callback_registered_event->set(); - - mre.get(); - - // should not block - ASSERT_TRUE(true); -} - -TEST(receive, logs_if_callback_for_given_id_not_found) -{ - auto message_received_event = std::make_shared<event>(); - auto handshake_sent = std::make_shared<event>(); - - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number, message_received_event, handshake_sent](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{ \"type\": 3, \"invocationId\": \"0\" }\x1e", - "{}" - }; - - handshake_sent->wait(1000); - - call_number = std::min(call_number + 1, 2); - - if (call_number > 1) - { - message_received_event->set(); - } - - callback(responses[call_number], nullptr); - }, - [handshake_sent](const std::string&, std::function<void(std::exception_ptr)> callback) - { - handshake_sent->set(); - callback(nullptr); - }); - - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - auto hub_connection = create_hub_connection(websocket_client, writer, trace_level::info); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_FALSE(message_received_event->wait(5000)); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_TRUE(log_entries.size() > 1); - - auto entry = remove_date_from_log_entry(log_entries[2]); - ASSERT_EQ("[info ] no callback found for id: 0\n", entry) << dump_vector(log_entries); -} - -TEST(invoke_void, invoke_creates_runtime_error) -{ - auto callback_registered_event = std::make_shared<event>(); - - int call_number = -1; - auto websocket_client = create_test_websocket_client( - /* receive function */ [call_number, callback_registered_event](std::function<void(std::string, std::exception_ptr)> callback) - mutable { - std::string responses[] - { - "{ }\x1e", - "{ \"type\": 3, \"invocationId\": \"0\", \"error\": \"Ooops\" }\x1e" - }; - - call_number = std::min(call_number + 1, 1); - - if (call_number > 0) - { - callback_registered_event->wait(); - } - - callback(responses[call_number], nullptr); - }); - - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->invoke("method", json::value::array(), [&mre](const json::value&, std::exception_ptr exception) - { - mre.set(exception); - }); - - callback_registered_event->set(); - - try - { - mre.get(); - - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const hub_exception & e) - { - ASSERT_STREQ("\"Ooops\"", e.what()); - ASSERT_FALSE(callback_registered_event->wait(0)); - } -} - -TEST(connection_id, can_get_connection_id) -{ - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto hub_connection = create_hub_connection(websocket_client); - - ASSERT_EQ("", hub_connection->get_connection_id()); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - auto connection_id = hub_connection->get_connection_id(); - - hub_connection->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_EQ("f7707523-307d-4cba-9abf-3eef701241e8", connection_id); - ASSERT_EQ("f7707523-307d-4cba-9abf-3eef701241e8", hub_connection->get_connection_id()); -} - -TEST(on, event_name_must_not_be_empty_string) -{ - auto hub_connection = create_hub_connection(); - try - { - hub_connection->on("", [](const json::value&) {}); - - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const std::invalid_argument& e) - { - ASSERT_STREQ("event_name cannot be empty", e.what()); - } -} - -TEST(on, cannot_register_multiple_handlers_for_event) -{ - auto hub_connection = create_hub_connection(); - hub_connection->on("ping", [](const json::value&) {}); - - try - { - hub_connection->on("ping", [](const json::value&) {}); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const signalr_exception& e) - { - ASSERT_STREQ("an action for this event has already been registered. event name: ping", e.what()); - } -} - -TEST(on, cannot_register_handler_if_connection_not_in_disconnected_state) -{ - try - { - auto websocket_client = create_test_websocket_client( - /* receive function */ [](std::function<void(std::string, std::exception_ptr)> callback) { callback("{ }\x1e", nullptr); }); - auto hub_connection = create_hub_connection(websocket_client); - - auto mre = manual_reset_event<void>(); - hub_connection->start([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - hub_connection->on("myfunc", [](const web::json::value&) {}); - - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const signalr_exception& e) - { - ASSERT_STREQ("can't register a handler if the connection is in a disconnected state", e.what()); - } -} - -TEST(invoke, invoke_throws_when_the_underlying_connection_is_not_valid) -{ - auto hub_connection = create_hub_connection(); - - auto mre = manual_reset_event<void>(); - hub_connection->invoke("method", json::value::array(), [&mre](const json::value&, std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const signalr_exception& e) - { - ASSERT_STREQ("cannot send data when the connection is not in the connected state. current connection state: disconnected", e.what()); - } -} - -TEST(invoke, send_throws_when_the_underlying_connection_is_not_valid) -{ - auto hub_connection = create_hub_connection(); - - auto mre = manual_reset_event<void>(); - hub_connection->invoke("method", json::value::array(), [&mre](const json::value&, std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); // exception expected but not thrown - } - catch (const signalr_exception& e) - { - ASSERT_STREQ("cannot send data when the connection is not in the connected state. current connection state: disconnected", e.what()); - } -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/hub_exception_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/hub_exception_tests.cpp deleted file mode 100644 index c7952066bd867c6a2ca761b93ff2bb5f3850dbf2..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/hub_exception_tests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "signalrclient/hub_exception.h" - -using namespace signalr; - -TEST(hub_exception_initialization, hub_exception_initialized_correctly) -{ - auto e = hub_exception{ "error" }; - - ASSERT_STREQ("error", e.what()); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/logger_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/logger_tests.cpp deleted file mode 100644 index d3f5760ab45411e3a4d1e58c7a10357002fc3da4..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/logger_tests.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_utils.h" -#include "cpprest/asyncrt_utils.h" -#include "trace_log_writer.h" -#include "logger.h" -#include "memory_log_writer.h" - -using namespace signalr; -TEST(logger_write, entry_added_if_trace_level_set) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - logger l(writer, trace_level::messages); - l.log(trace_level::messages, "message"); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - - ASSERT_EQ(1U, log_entries.size()); -} - -TEST(logger_write, entry_not_added_if_trace_level_not_set) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - logger l(writer, trace_level::messages); - l.log(trace_level::events, "event"); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - - ASSERT_TRUE(log_entries.empty()); -} - -TEST(logger_write, entries_added_for_combined_trace_level) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - logger l(writer, trace_level::messages | trace_level::state_changes | trace_level::events | trace_level::errors | trace_level::info); - l.log(trace_level::messages, "message"); - l.log(trace_level::events, "event"); - l.log(trace_level::state_changes, "state_change"); - l.log(trace_level::errors, "error"); - l.log(trace_level::info, "info"); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - - ASSERT_EQ(5U, log_entries.size()); -} - -TEST(logger_write, entries_formatted_correctly) -{ - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - logger l(writer, trace_level::all); - l.log(trace_level::messages, "message"); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_FALSE(log_entries.empty()); - - auto entry = log_entries[0]; - - auto date_str = entry.substr(0, entry.find_first_of("Z") + 1); - auto date = utility::datetime::from_string(utility::conversions::to_string_t(date_str), utility::datetime::ISO_8601); - ASSERT_EQ(date_str, utility::conversions::to_utf8string(date.to_string(utility::datetime::ISO_8601))); - - ASSERT_EQ("[message ] message\n", remove_date_from_log_entry(entry)); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.cpp deleted file mode 100644 index e8a2ff29f58eb04e94815941dfc724c7e277879c..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in t - -#include "stdafx.h" -#include "memory_log_writer.h" - -void memory_log_writer::write(const std::string& entry) -{ - std::lock_guard<std::mutex> lock(m_entries_lock); - m_log_entries.push_back(entry); -} - -std::vector<std::string> memory_log_writer::get_log_entries() -{ - std::lock_guard<std::mutex> lock(m_entries_lock); - return m_log_entries; -} \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.h b/src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.h deleted file mode 100644 index e98882d7da80498e0420c7fd2b56eb0d14ca1daa..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/memory_log_writer.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <vector> -#include <mutex> -#include "signalrclient/log_writer.h" - -using namespace signalr; - -class memory_log_writer : public log_writer -{ -public: - void __cdecl write(const std::string &entry) override; - std::vector<std::string> get_log_entries(); - -private: - std::vector<std::string> m_log_entries; - std::mutex m_entries_lock; -}; \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/negotiate_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/negotiate_tests.cpp deleted file mode 100644 index bc69936b33b2cc23c5fddcf902abc3e632a788e3..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/negotiate_tests.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "negotiate.h" -#include "test_http_client.h" - -using namespace signalr; - -TEST(negotiate, request_created_with_correct_url) -{ - std::string requested_url; - auto http_client = test_http_client([&requested_url](const std::string& url, http_request request) - { - std::string response_body( - "{ \"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [] }"); - - requested_url = url; - return http_response(200, response_body); - }); - - negotiate::negotiate(http_client, "http://fake/signalr").get(); - - ASSERT_EQ("http://fake/signalr/negotiate", requested_url); -} - -TEST(negotiate, negotiation_request_sent_and_response_serialized) -{ - auto request_factory = test_http_client([](const std::string&, http_request request) - { - std::string response_body( - "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] }," - "{ \"transport\": \"ServerSentEvents\", \"transferFormats\": [ \"Text\" ] } ] }"); - - return http_response(200, response_body); - }); - - auto response = negotiate::negotiate(request_factory, "http://fake/signalr").get(); - - ASSERT_EQ("f7707523-307d-4cba-9abf-3eef701241e8", response.connectionId); - ASSERT_EQ(2u, response.availableTransports.size()); - ASSERT_EQ(2u, response.availableTransports[0].transfer_formats.size()); - ASSERT_EQ("Text", response.availableTransports[0].transfer_formats[0]); - ASSERT_EQ("Binary", response.availableTransports[0].transfer_formats[1]); - ASSERT_EQ(1u, response.availableTransports[1].transfer_formats.size()); - ASSERT_EQ("Text", response.availableTransports[1].transfer_formats[0]); -} - -TEST(negotiate, negotiation_response_with_redirect) -{ - auto request_factory = test_http_client([](const std::string&, http_request request) - { - std::string response_body( - "{\"url\" : \"http://redirect\", " - "\"accessToken\" : \"secret\" }"); - - return http_response(200, response_body); - }); - - auto response = negotiate::negotiate(request_factory, "http://fake/signalr").get(); - - ASSERT_EQ("http://redirect", response.url); - ASSERT_EQ("secret", response.accessToken); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/signalrclienttests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/signalrclienttests.cpp deleted file mode 100644 index 6449644e2a6364ff1cccc9e2413ab7c231aa6323..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/signalrclienttests.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" - -#if defined(_WIN32) -int wmain(int argc, wchar_t* argv[]) -#else -int main(int argc, char* argv[]) -#endif -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/stdafx.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/stdafx.cpp deleted file mode 100644 index bd7a85614cfe19b82fec4f1be1f0738d8a0079d0..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/stdafx.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/stdafx.h b/src/SignalR/clients/cpp/test/signalrclienttests/stdafx.h deleted file mode 100644 index 59e3b5ec7c98352ba12314fe67e38b96ee7e9254..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/stdafx.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#ifdef _WIN32 -// prevents from defining min/max macros that conflict with std::min()/std::max() functions -#define NOMINMAX -#endif - -#include "gtest/gtest.h" -#include "../../src/signalrclient/event.h" -#include "../../src/signalrclient/make_unique.h" -#include <thread> \ No newline at end of file diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/targetver.h b/src/SignalR/clients/cpp/test/signalrclienttests/targetver.h deleted file mode 100644 index 742612c0c0cc1d39876aeca51f849fffadbf39d0..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/targetver.h +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <SDKDDKVer.h> diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_http_client.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_http_client.cpp deleted file mode 100644 index 9fd9c11f0e01e0394be3e306fe9faa5694ce163d..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_http_client.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_http_client.h" - -test_http_client::test_http_client(std::function<http_response(const std::string& url, http_request request)> create_http_response_fn) - : m_http_response(create_http_response_fn) -{ -} - -void test_http_client::send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback) -{ - http_response response; - std::exception_ptr exception; - try - { - response = m_http_response(url, request); - } - catch (...) - { - exception = std::current_exception(); - } - - callback(std::move(response), exception); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_http_client.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_http_client.h deleted file mode 100644 index 74f0d4d8bb933716ef798f08c6293277be762ea7..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_http_client.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "signalrclient/http_client.h" - -using namespace signalr; - -class test_http_client : public http_client -{ -public: - test_http_client(std::function<http_response(const std::string& url, http_request request)> create_http_response_fn); - void send(std::string url, http_request request, std::function<void(http_response, std::exception_ptr)> callback) override; -private: - std::function<http_response(const std::string& url, http_request request)> m_http_response; -}; diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.cpp deleted file mode 100644 index 1406dce8595ffd92bc4fe3b81eaf6e8ed7e73c20..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_transport_factory.h" -#include "websocket_transport.h" - -test_transport_factory::test_transport_factory(const std::shared_ptr<websocket_client>& websocket_client) - : m_websocket_client(websocket_client) -{ } - -std::shared_ptr<transport> test_transport_factory::create_transport(transport_type transport_type, const logger& logger, - const signalr_client_config&) -{ - if (transport_type == signalr::transport_type::websockets) - { - return websocket_transport::create([&](){ return m_websocket_client; }, logger); - } - - throw std::runtime_error("not supported"); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.h deleted file mode 100644 index f4fdc47619209d825c91d7e155ec9ae03263f8f3..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_transport_factory.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "transport_factory.h" -#include "signalrclient/websocket_client.h" - -using namespace signalr; - -class test_transport_factory : public transport_factory -{ -public: - test_transport_factory(const std::shared_ptr<websocket_client>& websocket_client); - - std::shared_ptr<transport> create_transport(transport_type transport_type, const logger& logger, - const signalr_client_config& signalr_client_config) override; - -private: - std::shared_ptr<websocket_client> m_websocket_client; -}; diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_utils.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_utils.cpp deleted file mode 100644 index 0863492fc577994ebd93128dd67db62628d1bbbc..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_utils.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_utils.h" -#include "test_websocket_client.h" -#include "test_web_request_factory.h" -#include "test_http_client.h" - -using namespace signalr; - -std::string remove_date_from_log_entry(const std::string &log_entry) -{ - // dates are ISO 8601 (e.g. `2014-11-13T06:05:29.452066Z`) - auto date_end_index = log_entry.find_first_of("Z") + 1; - - // date is followed by a whitespace hence +1 - return log_entry.substr(date_end_index + 1); -} - -std::shared_ptr<websocket_client> create_test_websocket_client(std::function<void(std::function<void(std::string, std::exception_ptr)>)> receive_function, - std::function<void(const std::string& msg, std::function<void(std::exception_ptr)>)> send_function, - std::function<void(const std::string&, std::function<void(std::exception_ptr)>)> connect_function, - std::function<void(std::function<void(std::exception_ptr)>)> close_function) -{ - auto websocket_client = std::make_shared<test_websocket_client>(); - websocket_client->set_receive_function(receive_function); - websocket_client->set_send_function(send_function); - websocket_client->set_connect_function(connect_function); - websocket_client->set_close_function(close_function); - - return websocket_client; -} - -std::unique_ptr<web_request_factory> create_test_web_request_factory() -{ - return std::make_unique<test_web_request_factory>([](const std::string& url) - { - auto response_body = - url.find_first_of("/negotiate") != 0 - ? "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }" - : ""; - - return std::unique_ptr<web_request>(new web_request_stub((unsigned short)200, "OK", response_body)); - }); -} - -std::unique_ptr<http_client> create_test_http_client() -{ - return std::make_unique<test_http_client>([](const std::string & url, http_request request) - { - auto response_body = - url.find_first_of("/negotiate") != 0 - ? "{\"connectionId\" : \"f7707523-307d-4cba-9abf-3eef701241e8\", " - "\"availableTransports\" : [ { \"transport\": \"WebSockets\", \"transferFormats\": [ \"Text\", \"Binary\" ] } ] }" - : ""; - - return http_response{ 200, response_body }; - }); -} - -std::string create_uri() -{ - auto unit_test = ::testing::UnitTest::GetInstance(); - - // unit test will be null if this function is not called in a test - _ASSERTE(unit_test); - - return std::string("http://") - .append(unit_test->current_test_info()->name()); -} - -std::string create_uri(const std::string& query_string) -{ - auto unit_test = ::testing::UnitTest::GetInstance(); - - // unit test will be null if this function is not called in a test - _ASSERTE(unit_test); - - return std::string("http://") - .append(unit_test->current_test_info()->name()) - .append("?" + query_string); -} - -std::vector<std::string> filter_vector(const std::vector<std::string>& source, const std::string& string) -{ - std::vector<std::string> filtered_entries; - std::copy_if(source.begin(), source.end(), std::back_inserter(filtered_entries), [&string](const std::string &e) - { - return e.find(string) != std::string::npos; - }); - return filtered_entries; -} - -std::string dump_vector(const std::vector<std::string>& source) -{ - std::stringstream ss; - ss << "Number of entries: " << source.size() << std::endl; - for (const auto& e : source) - { - ss << e; - if (e.back() != '\n') - { - ss << std::endl; - } - } - - return ss.str(); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_utils.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_utils.h deleted file mode 100644 index bc3daf8d7dec7c3f8c4f316917b5af8e5050b124..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_utils.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "cpprest/details/basic_types.h" -#include "signalrclient/websocket_client.h" -#include "signalrclient/http_client.h" -#include <future> - -std::string remove_date_from_log_entry(const std::string &log_entry); - -std::shared_ptr<signalr::websocket_client> create_test_websocket_client( - std::function<void(std::function<void(std::string, std::exception_ptr)>)> receive_function = [](std::function<void(std::string, std::exception_ptr)> callback) { callback("", nullptr); }, - std::function<void(const std::string& msg, std::function<void(std::exception_ptr)>)> send_function = [](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(nullptr); }, - std::function<void(const std::string&, std::function<void(std::exception_ptr)>)> connect_function = [](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(nullptr); }, - std::function<void(std::function<void(std::exception_ptr)>)> close_function = [](std::function<void(std::exception_ptr)> callback) { callback(nullptr); }); - -std::unique_ptr<signalr::http_client> create_test_http_client(); -std::string create_uri(); -std::string create_uri(const std::string& query_string); -std::vector<std::string> filter_vector(const std::vector<std::string>& source, const std::string& string); -std::string dump_vector(const std::vector<std::string>& source); - -template <typename T> -class manual_reset_event -{ -public: - void set(T value) - { - m_promise.set_value(value); - } - - void set(const std::exception& exception) - { - m_promise.set_exception(std::make_exception_ptr(exception)); - } - - void set(std::exception_ptr exception) - { - m_promise.set_exception(exception); - } - - T get() - { - // TODO: timeout - try - { - auto ret = m_promise.get_future().get(); - m_promise = std::promise<T>(); - return ret; - } - catch (...) - { - m_promise = std::promise<T>(); - std::rethrow_exception(std::current_exception()); - } - } -private: - std::promise<T> m_promise; -}; - -template <> -class manual_reset_event<void> -{ -public: - void set() - { - m_promise.set_value(); - } - - void set(const std::exception& exception) - { - m_promise.set_exception(std::make_exception_ptr(exception)); - } - - void set(std::exception_ptr exception) - { - if (exception != nullptr) - { - m_promise.set_exception(exception); - } - else - { - m_promise.set_value(); - } - } - - void get() - { - try - { - m_promise.get_future().get(); - } - catch (...) - { - m_promise = std::promise<void>(); - std::rethrow_exception(std::current_exception()); - } - - m_promise = std::promise<void>(); - } -private: - std::promise<void> m_promise; -}; diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.cpp deleted file mode 100644 index e1b0d785b38555558f9db9e6256c800166c1f97c..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_web_request_factory.h" - -using namespace signalr; - -test_web_request_factory::test_web_request_factory(std::function<std::unique_ptr<web_request>(const std::string& url)> create_web_request_fn) - : m_create_web_request_fn(create_web_request_fn) -{ } - -std::unique_ptr<web_request> test_web_request_factory::create_web_request(const std::string& url) -{ - return m_create_web_request_fn(url); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.h deleted file mode 100644 index d96ab5286ca2f29117f80481da65db27da7e5aea..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_web_request_factory.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "web_request_factory.h" -#include "web_request_stub.h" - -using namespace signalr; - -class test_web_request_factory : public web_request_factory -{ -public: - explicit test_web_request_factory(std::function<std::unique_ptr<web_request>(const std::string& url)> create_web_request_fn); - - virtual std::unique_ptr<web_request> create_web_request(const std::string& url) override; - -private: - std::function<std::unique_ptr<web_request>(const std::string& url)> m_create_web_request_fn; -}; diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.cpp deleted file mode 100644 index d24b7724a62ccc18107b6eb52fd6ee0542d503c4..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_websocket_client.h" -#include "pplx/pplxtasks.h" - -test_websocket_client::test_websocket_client() - : m_connect_function([](const std::string&, std::function<void(std::exception_ptr)> callback) { callback(nullptr); }), - m_send_function([](const std::string msg, std::function<void(std::exception_ptr)> callback) { callback(nullptr); }), - m_receive_function([](std::function<void(std::string, std::exception_ptr)> callback) { callback("", nullptr); }), - m_close_function([](std::function<void(std::exception_ptr)> callback) { callback(nullptr); }) -{ } - -void test_websocket_client::start(std::string url, transfer_format, std::function<void(std::exception_ptr)> callback) -{ - pplx::create_task([url, callback, this]() - { - m_connect_function(url, callback); - }); -} - -void test_websocket_client::stop(std::function<void(std::exception_ptr)> callback) -{ - pplx::create_task([callback, this]() - { - m_close_function(callback); - }); -} - -void test_websocket_client::send(std::string payload, std::function<void(std::exception_ptr)> callback) -{ - pplx::create_task([payload, callback, this]() - { - m_send_function(payload, callback); - }); -} - -void test_websocket_client::receive(std::function<void(std::string, std::exception_ptr)> callback) -{ - pplx::create_task([callback, this]() - { - m_receive_function(callback); - }); -} - -void test_websocket_client::set_connect_function(std::function<void(const std::string&, std::function<void(std::exception_ptr)>)> connect_function) -{ - m_connect_function = connect_function; -} - -void test_websocket_client::set_send_function(std::function<void(const std::string& msg, std::function<void(std::exception_ptr)>)> send_function) -{ - m_send_function = send_function; -} - -void test_websocket_client::set_receive_function(std::function<void(std::function<void(std::string, std::exception_ptr)>)> receive_function) -{ - m_receive_function = receive_function; -} - -void test_websocket_client::set_close_function(std::function<void(std::function<void(std::exception_ptr)>)> close_function) -{ - m_close_function = close_function; -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.h b/src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.h deleted file mode 100644 index 85ec4e46001423c7e393d0c7657cd3dd688e0ff6..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/test_websocket_client.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include <functional> -#include "signalrclient/websocket_client.h" - -using namespace signalr; - -class test_websocket_client : public websocket_client -{ -public: - test_websocket_client(); - - void start(std::string url, transfer_format format, std::function<void(std::exception_ptr)> callback) override; - - void stop(std::function<void(std::exception_ptr)> callback) override; - - void send(std::string payload, std::function<void(std::exception_ptr)> callback) override; - - void receive(std::function<void(std::string, std::exception_ptr)> callback) override; - - void set_connect_function(std::function<void(const std::string&, std::function<void(std::exception_ptr)>)> connect_function); - - void set_send_function(std::function<void(const std::string& msg, std::function<void(std::exception_ptr)>)> send_function); - - void set_receive_function(std::function<void(std::function<void(std::string, std::exception_ptr)>)> receive_function); - - void set_close_function(std::function<void(std::function<void(std::exception_ptr)>)> close_function); - -private: - std::function<void(const std::string&, std::function<void(std::exception_ptr)>)> m_connect_function; - - std::function<void(const std::string&, std::function<void(std::exception_ptr)>)> m_send_function; - - std::function<void(std::function<void(std::string, std::exception_ptr)>)> m_receive_function; - - std::function<void(std::function<void(std::exception_ptr)>)> m_close_function; -}; diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/url_builder_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/url_builder_tests.cpp deleted file mode 100644 index 6e4d04cc252f615e11c07c5edd0dac7b4c83c69b..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/url_builder_tests.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "url_builder.h" - -using namespace signalr; - -TEST(url_builder_negotiate, url_correct_if_query_string_empty) -{ - ASSERT_EQ( - "http://fake/negotiate", - url_builder::build_negotiate("http://fake/")); -} - -TEST(url_builder_negotiate, url_correct_if_query_string_not_empty) -{ - ASSERT_EQ( - "http://fake/negotiate?q1=1&q2=2", - url_builder::build_negotiate("http://fake/?q1=1&q2=2")); -} - -TEST(url_builder_connect_webSockets, url_correct_if_query_string_not_empty) -{ - ASSERT_EQ( - "ws://fake/?q1=1&q2=2", - url_builder::build_connect("http://fake/", transport_type::websockets, "q1=1&q2=2")); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.cpp deleted file mode 100644 index a2633b6ec6d8c3db605a3914c2595a73d7a41937..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "web_request_stub.h" - -web_request_stub::web_request_stub(unsigned short status_code, const std::string& reason_phrase, const std::string& response_body) - : web_request(""), m_status_code(status_code), m_reason_phrase(reason_phrase), m_response_body(response_body) -{ } - -void web_request_stub::set_method(const std::string &method) -{ - m_method = method; -} - -void web_request_stub::set_user_agent(const std::string &user_agent_string) -{ - m_user_agent_string = user_agent_string; -} - -void web_request_stub::set_client_config(const signalr_client_config& config) -{ - m_signalr_client_config = config; -} - -pplx::task<web_response> web_request_stub::get_response() -{ - on_get_response(*this); - - return pplx::task_from_result<web_response>( - web_response{ m_status_code, m_reason_phrase, pplx::task_from_result<std::string>(m_response_body) }); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.h b/src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.h deleted file mode 100644 index 23c37be88fef18a1764b9691bdd7bbfd120a23dc..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/web_request_stub.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#pragma once - -#include "web_request.h" -#include "web_response.h" - -using namespace signalr; - -struct web_request_stub : public web_request -{ - unsigned short m_status_code; - std::string m_reason_phrase; - std::string m_response_body; - std::string m_method; - std::string m_user_agent_string; - signalr_client_config m_signalr_client_config; - std::function<void(web_request_stub&)> on_get_response = [](web_request_stub&){}; - - web_request_stub(unsigned short status_code, const std::string& reason_phrase, const std::string& response_body = ""); - - virtual void set_method(const std::string &method) override; - virtual void set_user_agent(const std::string &user_agent_string) override; - virtual void set_client_config(const signalr_client_config& client_config) override; - - virtual pplx::task<web_response> get_response() override; -}; diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/web_request_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/web_request_tests.cpp deleted file mode 100644 index d7e789b04d6dfcf0e5e42065974a77b2911003e5..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/web_request_tests.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "cpprest/http_listener.h" -#include "web_request.h" - -using namespace web; -using namespace signalr; - -TEST(web_request_get_response, DISABLED_sends_request_receives_response) -{ - std::string url("http://localhost:56000/web_request_test"); - auto request_received = false; - std::string user_agent_string; - - http::experimental::listener::http_listener listener(utility::conversions::to_string_t(url)); - listener.support(http::methods::GET, [&request_received, &user_agent_string](http::http_request request) - { - request_received = true; - user_agent_string = utility::conversions::to_utf8string(request.headers()[_XPLATSTR("User-Agent")]); - request.reply(http::status_codes::OK, "response"); - }); - - listener.open() - .then([&url]() - { - web_request request(url); - request.set_method(utility::conversions::to_utf8string(http::methods::GET)); - request.set_user_agent("007"); - request.get_response() - .then([](web_response response) - { - ASSERT_EQ((unsigned short)200, response.status_code); - ASSERT_EQ("OK", response.reason_phrase); - ASSERT_EQ("response", response.body.get()); - }).wait(); - }).wait(); - - listener.close(); - - ASSERT_TRUE(request_received); - ASSERT_EQ("007", user_agent_string); -} diff --git a/src/SignalR/clients/cpp/test/signalrclienttests/websocket_transport_tests.cpp b/src/SignalR/clients/cpp/test/signalrclienttests/websocket_transport_tests.cpp deleted file mode 100644 index 543329347ddc9492bcd64024de0b21483d71445d..0000000000000000000000000000000000000000 --- a/src/SignalR/clients/cpp/test/signalrclienttests/websocket_transport_tests.cpp +++ /dev/null @@ -1,579 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -#include "stdafx.h" -#include "test_utils.h" -#include "trace_log_writer.h" -#include "test_websocket_client.h" -#include "websocket_transport.h" -#include "memory_log_writer.h" -#include <future> - -using namespace signalr; - -TEST(websocket_transport_connect, connect_connects_and_starts_receive_loop) -{ - auto connect_called = false; - auto receive_called = std::make_shared<event>(); - auto client = std::make_shared<test_websocket_client>(); - - client->set_connect_function([&connect_called](const std::string&, std::function<void(std::exception_ptr)> callback) - { - connect_called = true; - callback(nullptr); - }); - - client->set_receive_function([receive_called](std::function<void(std::string, std::exception_ptr)> callback) - { - receive_called->set(); - callback("", nullptr); - }); - - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(writer, trace_level::info)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org/connect?param=42", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - mre.get(); - - ASSERT_TRUE(connect_called); - ASSERT_FALSE(receive_called->wait(5000)); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - ASSERT_FALSE(log_entries.empty()); - - auto entry = remove_date_from_log_entry(log_entries[0]); - ASSERT_EQ("[info ] [websocket transport] connecting to: ws://fakeuri.org/connect?param=42\n", entry); -} - -TEST(websocket_transport_connect, connect_propagates_exceptions) -{ - auto client = std::make_shared<test_websocket_client>(); - client->set_connect_function([](const std::string&, std::function<void(std::exception_ptr)> callback) - { - callback(std::make_exception_ptr(web::websockets::client::websocket_exception(_XPLATSTR("connecting failed")))); - }); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - try - { - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - ASSERT_TRUE(false); - } - catch (const std::exception &e) - { - ASSERT_EQ(_XPLATSTR("connecting failed"), utility::conversions::to_string_t(e.what())); - } -} - -TEST(websocket_transport_connect, connect_logs_exceptions) -{ - auto client = std::make_shared<test_websocket_client>(); - client->set_connect_function([](const std::string&, std::function<void(std::exception_ptr)> callback) - { - callback(std::make_exception_ptr(web::websockets::client::websocket_exception(_XPLATSTR("connecting failed")))); - }); - - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(writer, trace_level::errors)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - try - { - mre.get(); - } - catch (...) {} - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - - ASSERT_FALSE(log_entries.empty()); - - auto entry = remove_date_from_log_entry(log_entries[0]); - - ASSERT_EQ( - "[error ] [websocket transport] exception when connecting to the server: connecting failed\n", - entry); -} - -TEST(websocket_transport_connect, cannot_call_connect_on_already_connected_transport) -{ - auto client = std::make_shared<test_websocket_client>(); - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - try - { - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - ASSERT_TRUE(false); - } - catch (const std::exception &e) - { - ASSERT_EQ(_XPLATSTR("transport already connected"), utility::conversions::to_string_t(e.what())); - } -} - -TEST(websocket_transport_connect, can_connect_after_disconnecting) -{ - auto client = std::make_shared<test_websocket_client>(); - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ws_transport->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); -} - -TEST(websocket_transport_send, send_creates_and_sends_websocket_messages) -{ - bool send_called = false; - - auto client = std::make_shared<test_websocket_client>(); - - client->set_send_function([&send_called](const std::string&, std::function<void(std::exception_ptr)> callback) - { - send_called = true; - callback(nullptr); - }); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://url", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ws_transport->send("ABC", [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ASSERT_TRUE(send_called); -} - -TEST(websocket_transport_disconnect, disconnect_closes_websocket) -{ - bool close_called = false; - - auto client = std::make_shared<test_websocket_client>(); - - client->set_close_function([&close_called](std::function<void(std::exception_ptr)> callback) - { - close_called = true; - callback(nullptr); - }); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://url", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ws_transport->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ASSERT_TRUE(close_called); -} - -TEST(websocket_transport_stop, propogates_exception_from_close) -{ - auto client = std::make_shared<test_websocket_client>(); - - bool close_called = false; - client->set_close_function([&close_called](std::function<void(std::exception_ptr)> callback) - { - close_called = true; - callback(std::make_exception_ptr(std::exception())); - }); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://url", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ws_transport->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) { } - - ASSERT_TRUE(close_called); -} - -TEST(websocket_transport_disconnect, disconnect_logs_exceptions) -{ - auto client = std::make_shared<test_websocket_client>(); - client->set_close_function([](std::function<void(std::exception_ptr)> callback) - { - callback(std::make_exception_ptr(web::websockets::client::websocket_exception(_XPLATSTR("connection closing failed")))); - }); - - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(writer, trace_level::errors)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://url", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ws_transport->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - - try - { - mre.get(); - ASSERT_TRUE(false); - } - catch (...) {} - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - - ASSERT_FALSE(log_entries.empty()); - - // disconnect cancels the receive loop by setting the cancellation token source to cancelled which results in writing - // to the log. Exceptions from close are also logged but this happens on a different thread. As a result the order - // of messages in the log is not deterministic and therefore we just use the "contains" idiom to find the message. - ASSERT_NE(std::find_if(log_entries.begin(), log_entries.end(), [](const std::string& entry) - { - return remove_date_from_log_entry(entry) == - "[error ] [websocket transport] exception when closing websocket: connection closing failed\n"; - }), - log_entries.end()); -} - -TEST(websocket_transport_disconnect, receive_not_called_after_disconnect) -{ - auto client = std::make_shared<test_websocket_client>(); - - pplx::task_completion_event<std::string> receive_task_tce; - pplx::task_completion_event<void> receive_task_started_tce; - - // receive_task_tce is captured by reference since we assign it a new value after the first disconnect. This is - // safe here because we are blocking on disconnect and therefore we won't get into a state where we would be using - // an invalid reference because the tce went out of scope and was destroyed. - client->set_close_function([&receive_task_tce](std::function<void(std::exception_ptr)> callback) - { - // unblock receive - receive_task_tce.set(std::string("")); - callback(nullptr); - }); - - int num_called = 0; - client->set_receive_function([&receive_task_tce, &receive_task_started_tce, &num_called](std::function<void(std::string, std::exception_ptr)> callback) - { - num_called++; - receive_task_started_tce.set(); - pplx::create_task(receive_task_tce) - .then([callback](pplx::task<std::string> prev) - { - prev.get(); - callback("", nullptr); - }); - }); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr) - { - mre.set(); - }); - mre.get(); - - pplx::create_task(receive_task_started_tce).get(); - - ws_transport->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - receive_task_tce = pplx::task_completion_event<std::string>(); - receive_task_started_tce = pplx::task_completion_event<void>(); - - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - pplx::create_task(receive_task_started_tce).get(); - - ws_transport->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ASSERT_EQ(2, num_called); -} - -TEST(websocket_transport_disconnect, disconnect_is_no_op_if_transport_not_started) -{ - auto client = std::make_shared<test_websocket_client>(); - - auto close_called = false; - - client->set_close_function([&close_called](std::function<void(std::exception_ptr)> callback) - { - close_called = true; - callback(nullptr); - }); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - auto mre = manual_reset_event<void>(); - ws_transport->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ASSERT_FALSE(close_called); -} - -TEST(websocket_transport_disconnect, exceptions_from_outstanding_receive_task_observed_after_websocket_transport_disconnected) -{ - auto client = std::make_shared<test_websocket_client>(); - - auto receive_event = std::make_shared<event>(); - client->set_receive_function([receive_event](std::function<void(std::string, std::exception_ptr)> callback) - { - pplx::create_task([receive_event, callback]() - { - receive_event->wait(); - callback("", std::make_exception_ptr(std::runtime_error("exception from receive"))); - }); - }); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - ws_transport->stop([&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - // at this point the cancellation token that closes the receive loop is set to cancelled so - // we can unblock the the receive task which throws an exception that should be observed otwherwise the test will crash - receive_event->set(); -} - -template<typename T> -void receive_loop_logs_exception_runner(const T& e, const std::string& expected_message, trace_level trace_level); - -TEST(websocket_transport_receive_loop, receive_loop_logs_websocket_exceptions) -{ - receive_loop_logs_exception_runner( - web::websockets::client::websocket_exception(_XPLATSTR("receive failed")), - "[error ] [websocket transport] error receiving response from websocket: receive failed\n", - trace_level::errors); -} - -TEST(websocket_transport_receive_loop, receive_loop_logs_if_receive_task_canceled) -{ - receive_loop_logs_exception_runner( - pplx::task_canceled("canceled"), - "[error ] [websocket transport] error receiving response from websocket: canceled\n", - trace_level::errors); -} - -TEST(websocket_transport_receive_loop, receive_loop_logs_std_exception) -{ - receive_loop_logs_exception_runner( - std::runtime_error("exception"), - "[error ] [websocket transport] error receiving response from websocket: exception\n", - trace_level::errors); -} - -template<typename T> -void receive_loop_logs_exception_runner(const T& e, const std::string& expected_message, trace_level trace_level) -{ - event receive_event; - auto client = std::make_shared<test_websocket_client>(); - - client->set_receive_function([&receive_event, &e](std::function<void(std::string, std::exception_ptr)> callback) - { - callback("", std::make_exception_ptr(e)); - receive_event.set(); - }); - - std::shared_ptr<log_writer> writer(std::make_shared<memory_log_writer>()); - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(writer, trace_level)); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://url", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - receive_event.wait(); - - // this is race'y but there is nothing we can block on - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - auto log_entries = std::dynamic_pointer_cast<memory_log_writer>(writer)->get_log_entries(); - - ASSERT_NE(std::find_if(log_entries.begin(), log_entries.end(), - [&expected_message](std::string entry) { return remove_date_from_log_entry(entry) == expected_message; }), - log_entries.end()) << dump_vector(log_entries); -} - -TEST(websocket_transport_receive_loop, process_response_callback_called_when_message_received) -{ - auto client = std::make_shared<test_websocket_client>(); - client->set_receive_function([](std::function<void(std::string, std::exception_ptr)> callback) - { - callback("msg", nullptr); - }); - - auto process_response_event = std::make_shared<event>(); - auto msg = std::make_shared<std::string>(); - - auto process_response = [msg, process_response_event](const std::string& message, std::exception_ptr exception) - { - ASSERT_FALSE(exception); - *msg = message; - process_response_event->set(); - }; - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - ws_transport->on_receive(process_response); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - process_response_event->wait(1000); - - ASSERT_EQ(std::string("msg"), *msg); -} - -TEST(websocket_transport_receive_loop, error_callback_called_when_exception_thrown) -{ - auto client = std::make_shared<test_websocket_client>(); - client->set_receive_function([](std::function<void(std::string, std::exception_ptr)> callback) - { - callback("", std::make_exception_ptr(std::runtime_error("error"))); - }); - - auto close_invoked = std::make_shared<bool>(false); - client->set_close_function([close_invoked](std::function<void(std::exception_ptr)> callback) - { - *close_invoked = true; - callback(nullptr); - }); - - auto error_event = std::make_shared<event>(); - auto exception_msg = std::make_shared<std::string>(); - - auto error_callback = [exception_msg, error_event](std::exception_ptr exception) - { - try - { - std::rethrow_exception(exception); - } - catch (const std::exception& e) - { - *exception_msg = e.what(); - } - error_event->set(); - }; - - auto ws_transport = websocket_transport::create([&](){ return client; }, logger(std::make_shared<trace_log_writer>(), trace_level::none)); - ws_transport->on_close(error_callback); - - auto mre = manual_reset_event<void>(); - ws_transport->start("ws://fakeuri.org", transfer_format::text, [&mre](std::exception_ptr exception) - { - mre.set(exception); - }); - mre.get(); - - error_event->wait(1000); - - ASSERT_STREQ("error", exception_msg->c_str()); - ASSERT_TRUE(*close_invoked); -} - -TEST(websocket_transport_get_transport_type, get_transport_type_returns_websockets) -{ - auto ws_transport = websocket_transport::create( - [](){ return std::make_shared<default_websocket_client>(); }, - logger(std::make_shared<trace_log_writer>(), trace_level::none)); - - ASSERT_EQ(transport_type::websockets, ws_transport->get_transport_type()); -}