From 13253c95cf747af860d0a307ef464dc43f3f0522 Mon Sep 17 00:00:00 2001 From: Sewer 56 Date: Tue, 5 Jul 2022 15:05:52 +0100 Subject: [PATCH 001/261] Added .NET5+ Member Trimming Annotations --- LiteNetLib.sln | 35 +++++++- LiteNetLib/LiteNetLib.csproj | 5 +- LiteNetLib/NatPunchModule.cs | 7 +- LiteNetLib/Trimming.cs | 12 +++ LiteNetLib/Utils/NetPacketProcessor.cs | 80 ++++++++++++++---- LiteNetLib/Utils/NetSerializer.cs | 37 ++++++-- LiteNetLibSampleUnity/Assets/LiteNetLib.dll | Bin 103424 -> 103424 bytes LiteNetLibSampleUnity/Assets/LiteNetLib.xml | 5 ++ .../LiteNetLib.Trim.Dummy.csproj | 20 +++++ Trimming/LiteNetLib.Trim.Dummy/Program.cs | 3 + 10 files changed, 179 insertions(+), 25 deletions(-) create mode 100644 LiteNetLib/Trimming.cs create mode 100644 Trimming/LiteNetLib.Trim.Dummy/LiteNetLib.Trim.Dummy.csproj create mode 100644 Trimming/LiteNetLib.Trim.Dummy/Program.cs diff --git a/LiteNetLib.sln b/LiteNetLib.sln index 9956f9cf..c1498e66 100644 --- a/LiteNetLib.sln +++ b/LiteNetLib.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29519.181 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32611.2 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LiteNetLib.Tests", "LiteNetLib.Tests\LiteNetLib.Tests.csproj", "{6B591E33-E71F-4A37-A08D-B56DD47EDE3F}" EndProject @@ -14,6 +14,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibSample", "LibSample\LibSample.csproj", "{6499F9B4-0814-42EE-90A5-119AEA07E7EE}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Trimming", "Trimming", "{526AD654-856E-420E-8E32-438BB41E56F2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiteNetLib.Trim.Dummy", "Trimming\LiteNetLib.Trim.Dummy\LiteNetLib.Trim.Dummy.csproj", "{86C518B8-2ACF-4120-8B8C-7B8040081B0F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -102,10 +106,37 @@ Global {6499F9B4-0814-42EE-90A5-119AEA07E7EE}.Release|x64.Build.0 = Release|Any CPU {6499F9B4-0814-42EE-90A5-119AEA07E7EE}.Release|x86.ActiveCfg = Release|Any CPU {6499F9B4-0814-42EE-90A5-119AEA07E7EE}.Release|x86.Build.0 = Release|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Debug|ARM.ActiveCfg = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Debug|ARM.Build.0 = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Debug|x64.ActiveCfg = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Debug|x64.Build.0 = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Debug|x86.ActiveCfg = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Debug|x86.Build.0 = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.DebugUnsafe|Any CPU.ActiveCfg = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.DebugUnsafe|Any CPU.Build.0 = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.DebugUnsafe|ARM.ActiveCfg = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.DebugUnsafe|ARM.Build.0 = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.DebugUnsafe|x64.ActiveCfg = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.DebugUnsafe|x64.Build.0 = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.DebugUnsafe|x86.ActiveCfg = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.DebugUnsafe|x86.Build.0 = Debug|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Release|Any CPU.Build.0 = Release|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Release|ARM.ActiveCfg = Release|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Release|ARM.Build.0 = Release|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Release|x64.ActiveCfg = Release|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Release|x64.Build.0 = Release|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Release|x86.ActiveCfg = Release|Any CPU + {86C518B8-2ACF-4120-8B8C-7B8040081B0F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {86C518B8-2ACF-4120-8B8C-7B8040081B0F} = {526AD654-856E-420E-8E32-438BB41E56F2} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3629F29B-A78F-4AB0-8502-FEF6799FFBB9} EndGlobalSection diff --git a/LiteNetLib/LiteNetLib.csproj b/LiteNetLib/LiteNetLib.csproj index 03f0b170..0be10a89 100644 --- a/LiteNetLib/LiteNetLib.csproj +++ b/LiteNetLib/LiteNetLib.csproj @@ -7,11 +7,14 @@ net471;net6.0;net5.0;netstandard2.0;netstandard2.1;netcoreapp3.1 true Library - 7.3 + 9.0 true 1701;1702;1705;1591 1.0.0-rc.3 + + true + true diff --git a/LiteNetLib/NatPunchModule.cs b/LiteNetLib/NatPunchModule.cs index bab2fca0..bc577432 100644 --- a/LiteNetLib/NatPunchModule.cs +++ b/LiteNetLib/NatPunchModule.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; using System.Net; using LiteNetLib.Utils; @@ -111,7 +112,11 @@ public void Init(INatPunchListener listener) _natPunchListener = listener; } - private void Send(T packet, IPEndPoint target) where T : class, new() + private void Send< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(T packet, IPEndPoint target) where T : class, new() { _cacheWriter.Reset(); _cacheWriter.Put((byte)PacketProperty.NatMessage); diff --git a/LiteNetLib/Trimming.cs b/LiteNetLib/Trimming.cs new file mode 100644 index 00000000..6c575b65 --- /dev/null +++ b/LiteNetLib/Trimming.cs @@ -0,0 +1,12 @@ +#if NET5_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +using static System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes; + +namespace LiteNetLib +{ + internal static class Trimming + { + internal const DynamicallyAccessedMemberTypes SerializerMemberTypes = PublicProperties | NonPublicProperties; + } +} +#endif diff --git a/LiteNetLib/Utils/NetPacketProcessor.cs b/LiteNetLib/Utils/NetPacketProcessor.cs index 007d5207..c8fb53fe 100644 --- a/LiteNetLib/Utils/NetPacketProcessor.cs +++ b/LiteNetLib/Utils/NetPacketProcessor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace LiteNetLib.Utils { @@ -118,7 +119,11 @@ public void ReadPacket(NetDataReader reader) ReadPacket(reader, null); } - public void Send(NetPeer peer, T packet, DeliveryMethod options) where T : class, new() + public void Send< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(NetPeer peer, T packet, DeliveryMethod options) where T : class, new() { _netDataWriter.Reset(); Write(_netDataWriter, packet); @@ -132,7 +137,11 @@ public void SendNetSerializable(NetPeer peer, ref T packet, DeliveryMethod op peer.Send(_netDataWriter, options); } - public void Send(NetManager manager, T packet, DeliveryMethod options) where T : class, new() + public void Send< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(NetManager manager, T packet, DeliveryMethod options) where T : class, new() { _netDataWriter.Reset(); Write(_netDataWriter, packet); @@ -146,7 +155,11 @@ public void SendNetSerializable(NetManager manager, ref T packet, DeliveryMet manager.SendToAll(_netDataWriter, options); } - public void Write(NetDataWriter writer, T packet) where T : class, new() + public void Write< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(NetDataWriter writer, T packet) where T : class, new() { WriteHash(writer); _netSerializer.Serialize(writer, packet); @@ -175,15 +188,24 @@ public void ReadPacket(NetDataReader reader, object userData) /// event that will be called when packet deserialized with ReadPacket method /// Method that constructs packet instead of slow Activator.CreateInstance /// 's fields are not supported, or it has no fields - public void Subscribe(Action onReceive, Func packetConstructor) where T : class, new() + public void Subscribe< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(Action onReceive, Func packetConstructor) where T : class, new() { _netSerializer.Register(); - _callbacks[GetHash()] = (reader, userData) => + _callbacks[GetHash()] = Callback; + +#if NET5_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091", Justification = "Captured Type T in lambda is preserved via parent method.")] +#endif + void Callback(NetDataReader reader, object userData) { var reference = packetConstructor(); _netSerializer.Deserialize(reader, reference); onReceive(reference); - }; + } } /// @@ -192,15 +214,24 @@ public void ReadPacket(NetDataReader reader, object userData) /// event that will be called when packet deserialized with ReadPacket method /// Method that constructs packet instead of slow Activator.CreateInstance /// 's fields are not supported, or it has no fields - public void Subscribe(Action onReceive, Func packetConstructor) where T : class, new() + public void Subscribe< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T, TUserData>(Action onReceive, Func packetConstructor) where T : class, new() { _netSerializer.Register(); - _callbacks[GetHash()] = (reader, userData) => + _callbacks[GetHash()] = Callback; + +#if NET5_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091", Justification = "Captured Type T in lambda is preserved via parent method.")] +#endif + void Callback(NetDataReader reader, object userData) { var reference = packetConstructor(); _netSerializer.Deserialize(reader, reference); onReceive(reference, (TUserData)userData); - }; + } } /// @@ -209,15 +240,25 @@ public void ReadPacket(NetDataReader reader, object userData) /// /// event that will be called when packet deserialized with ReadPacket method /// 's fields are not supported, or it has no fields - public void SubscribeReusable(Action onReceive) where T : class, new() + public void SubscribeReusable< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(Action onReceive) where T : class, new() { _netSerializer.Register(); var reference = new T(); - _callbacks[GetHash()] = (reader, userData) => + _callbacks[GetHash()] = Callback; + +#if NET5_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091", Justification = "Captured Type T in lambda is preserved via parent method.")] +#endif + void Callback(NetDataReader reader, object userData) { _netSerializer.Deserialize(reader, reference); onReceive(reference); - }; + } + } /// @@ -226,15 +267,24 @@ public void ReadPacket(NetDataReader reader, object userData) /// /// event that will be called when packet deserialized with ReadPacket method /// 's fields are not supported, or it has no fields - public void SubscribeReusable(Action onReceive) where T : class, new() + public void SubscribeReusable< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T, TUserData>(Action onReceive) where T : class, new() { _netSerializer.Register(); var reference = new T(); - _callbacks[GetHash()] = (reader, userData) => + _callbacks[GetHash()] = Callback; + +#if NET5_0_OR_GREATER + [UnconditionalSuppressMessage("ReflectionAnalysis", "IL2091", Justification = "Captured Type T in lambda is preserved via parent method.")] +#endif + void Callback(NetDataReader reader, object userData) { _netSerializer.Deserialize(reader, reference); onReceive(reference, (TUserData)userData); - }; + } } public void SubscribeNetSerializable( diff --git a/LiteNetLib/Utils/NetSerializer.cs b/LiteNetLib/Utils/NetSerializer.cs index 63f6cd67..6de97e3c 100644 --- a/LiteNetLib/Utils/NetSerializer.cs +++ b/LiteNetLib/Utils/NetSerializer.cs @@ -1,6 +1,7 @@ using System; using System.Reflection; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net; using System.Runtime.Serialization; @@ -568,7 +569,11 @@ public NetSerializer(int maxStringLength) _maxStringLength = maxStringLength; } - private ClassInfo RegisterInternal() + private ClassInfo RegisterInternal< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>() { if (ClassInfo.Instance != null) return ClassInfo.Instance; @@ -663,7 +668,11 @@ private ClassInfo RegisterInternal() } /// 's fields are not supported, or it has no fields - public void Register() + public void Register< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>() { RegisterInternal(); } @@ -674,7 +683,11 @@ public void Register() /// NetDataReader with packet /// Returns packet if packet in reader is matched type /// 's fields are not supported, or it has no fields - public T Deserialize(NetDataReader reader) where T : class, new() + public T Deserialize< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(NetDataReader reader) where T : class, new() { var info = RegisterInternal(); var result = new T(); @@ -696,7 +709,11 @@ public void Register() /// Deserialization target /// Returns true if packet in reader is matched type /// 's fields are not supported, or it has no fields - public bool Deserialize(NetDataReader reader, T target) where T : class, new() + public bool Deserialize< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(NetDataReader reader, T target) where T : class, new() { var info = RegisterInternal(); try @@ -716,7 +733,11 @@ public void Register() /// Serialization target NetDataWriter /// Object to serialize /// 's fields are not supported, or it has no fields - public void Serialize(NetDataWriter writer, T obj) where T : class, new() + public void Serialize< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(NetDataWriter writer, T obj) where T : class, new() { RegisterInternal().Write(obj, writer); } @@ -726,7 +747,11 @@ public void Register() /// /// Object to serialize /// byte array with serialized data - public byte[] Serialize(T obj) where T : class, new() + public byte[] Serialize< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(Trimming.SerializerMemberTypes)] +#endif + T>(T obj) where T : class, new() { if (_writer == null) _writer = new NetDataWriter(); diff --git a/LiteNetLibSampleUnity/Assets/LiteNetLib.dll b/LiteNetLibSampleUnity/Assets/LiteNetLib.dll index 42658f40217281593a2047edc94e6378123c0c3e..881116f3b501ffb7c8aa425634022f739c359a88 100644 GIT binary patch delta 40961 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 R(P}xBW7yA#1<{%r^#_oXITHW? diff --git a/LiteNetLibSampleUnity/Assets/LiteNetLib.xml b/LiteNetLibSampleUnity/Assets/LiteNetLib.xml index 5413607f..0f09954a 100644 --- a/LiteNetLibSampleUnity/Assets/LiteNetLib.xml +++ b/LiteNetLibSampleUnity/Assets/LiteNetLib.xml @@ -707,6 +707,11 @@ Maximum packet pool size (increase if you have tons of packets sending) + + + Maximum packets count that will be processed in Manual PollEvents + + Start logic thread and listening on selected port diff --git a/Trimming/LiteNetLib.Trim.Dummy/LiteNetLib.Trim.Dummy.csproj b/Trimming/LiteNetLib.Trim.Dummy/LiteNetLib.Trim.Dummy.csproj new file mode 100644 index 00000000..95165f1c --- /dev/null +++ b/Trimming/LiteNetLib.Trim.Dummy/LiteNetLib.Trim.Dummy.csproj @@ -0,0 +1,20 @@ + + + + Exe + net6.0 + enable + enable + + true + + link + + + + + + + + + diff --git a/Trimming/LiteNetLib.Trim.Dummy/Program.cs b/Trimming/LiteNetLib.Trim.Dummy/Program.cs new file mode 100644 index 00000000..b49dd580 --- /dev/null +++ b/Trimming/LiteNetLib.Trim.Dummy/Program.cs @@ -0,0 +1,3 @@ +// I'm a dummy for assembly trimming since the built-in analyzer isn't perfect yet. +// Please build me with `dotnet publish -c Release -r win-x64` (or similar) and test for warnings. +Console.WriteLine("Hello, World!"); From ca6afdc050191881e9f7a603b56c9aad3a401959 Mon Sep 17 00:00:00 2001 From: Torque Date: Tue, 23 Aug 2022 10:04:42 -0700 Subject: [PATCH 002/261] Update BroadcastTest.cs - typo typo fix --- LibSample/BroadcastTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LibSample/BroadcastTest.cs b/LibSample/BroadcastTest.cs index 1f44b478..d08bc114 100644 --- a/LibSample/BroadcastTest.cs +++ b/LibSample/BroadcastTest.cs @@ -86,9 +86,9 @@ public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelN public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) { Console.WriteLine("[Server] ReceiveUnconnected {0}. From: {1}. Data: {2}", messageType, remoteEndPoint, reader.GetString(100)); - NetDataWriter wrtier = new NetDataWriter(); - wrtier.Put("SERVER DISCOVERY RESPONSE"); - Server.SendUnconnectedMessage(wrtier, remoteEndPoint); + NetDataWriter writer = new NetDataWriter(); + writer.Put("SERVER DISCOVERY RESPONSE"); + Server.SendUnconnectedMessage(writer, remoteEndPoint); } public void OnNetworkLatencyUpdate(NetPeer peer, int latency) From a85bf7d45ac8e6ffd0ec4679cb69dac3b56b3771 Mon Sep 17 00:00:00 2001 From: Mewiof <105601570+Mewiof@users.noreply.github.com> Date: Tue, 23 Aug 2022 20:19:34 +0300 Subject: [PATCH 003/261] Writer & reader cleanup "PutBytesWithLength" / "PutSBytesWithLength" length is now limited to ushort.MaxValue, like the rest of PutArray --- LiteNetLib/Utils/NetDataReader.cs | 206 ++++++++++++++---------------- LiteNetLib/Utils/NetDataWriter.cs | 52 ++++---- 2 files changed, 124 insertions(+), 134 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 70222653..3703afd5 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -1,6 +1,6 @@ using System; using System.Net; -using System.Text; +using System.Runtime.CompilerServices; namespace LiteNetLib.Utils { @@ -11,19 +11,46 @@ public class NetDataReader protected int _dataSize; private int _offset; - public byte[] RawData => _data; - public int RawDataSize => _dataSize; - public int UserDataOffset => _offset; - public int UserDataSize => _dataSize - _offset; - public bool IsNull => _data == null; - public int Position => _position; - public bool EndOfData => _position == _dataSize; - public int AvailableBytes => _dataSize - _position; - - // Cache encoding instead of creating it with BinaryWriter each time - // 1000 readers before: 1MB GC, 30ms - // 1000 readers after: .8MB GC, 18ms - private static readonly UTF8Encoding _uTF8Encoding = new UTF8Encoding(false, true); + public byte[] RawData + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _data; + } + public int RawDataSize + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _dataSize; + } + public int UserDataOffset + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _offset; + } + public int UserDataSize + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _dataSize - _offset; + } + public bool IsNull + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _data == null; + } + public int Position + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _position; + } + public bool EndOfData + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _position == _dataSize; + } + public int AvailableBytes + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _dataSize - _position; + } public void SkipBytes(int count) { @@ -90,123 +117,91 @@ public IPEndPoint GetNetEndPoint() public byte GetByte() { byte res = _data[_position]; - _position += 1; + _position++; return res; } public sbyte GetSByte() { - var b = (sbyte)_data[_position]; - _position++; - return b; + return (sbyte)GetByte(); } - public bool[] GetBoolArray() + public T[] GetArray(ushort size) { - ushort size = BitConverter.ToUInt16(_data, _position); + ushort length = BitConverter.ToUInt16(_data, _position); _position += 2; - var arr = new bool[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size); - _position += size; - return arr; + T[] result = new T[length]; + length *= size; + Buffer.BlockCopy(_data, _position, result, 0, length); + _position += length; + return result; + } + + public bool[] GetBoolArray() + { + return GetArray(1); } public ushort[] GetUShortArray() { - ushort size = BitConverter.ToUInt16(_data, _position); - _position += 2; - var arr = new ushort[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size * 2); - _position += size * 2; - return arr; + return GetArray(2); } public short[] GetShortArray() { - ushort size = BitConverter.ToUInt16(_data, _position); - _position += 2; - var arr = new short[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size * 2); - _position += size * 2; - return arr; + return GetArray(2); } - public long[] GetLongArray() + public int[] GetIntArray() { - ushort size = BitConverter.ToUInt16(_data, _position); - _position += 2; - var arr = new long[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size * 8); - _position += size * 8; - return arr; + return GetArray(4); } - public ulong[] GetULongArray() + public uint[] GetUIntArray() { - ushort size = BitConverter.ToUInt16(_data, _position); - _position += 2; - var arr = new ulong[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size * 8); - _position += size * 8; - return arr; + return GetArray(4); } - public int[] GetIntArray() + public float[] GetFloatArray() { - ushort size = BitConverter.ToUInt16(_data, _position); - _position += 2; - var arr = new int[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size * 4); - _position += size * 4; - return arr; + return GetArray(4); } - public uint[] GetUIntArray() + public double[] GetDoubleArray() { - ushort size = BitConverter.ToUInt16(_data, _position); - _position += 2; - var arr = new uint[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size * 4); - _position += size * 4; - return arr; + return GetArray(8); } - public float[] GetFloatArray() + public long[] GetLongArray() { - ushort size = BitConverter.ToUInt16(_data, _position); - _position += 2; - var arr = new float[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size * 4); - _position += size * 4; - return arr; + return GetArray(8); } - public double[] GetDoubleArray() + public ulong[] GetULongArray() { - ushort size = BitConverter.ToUInt16(_data, _position); - _position += 2; - var arr = new double[size]; - Buffer.BlockCopy(_data, _position, arr, 0, size * 8); - _position += size * 8; - return arr; + return GetArray(8); } public string[] GetStringArray() { - ushort arraySize = GetUShort(); - var arr = new string[arraySize]; - for (int i = 0; i < arraySize; i++) + ushort length = GetUShort(); + string[] arr = new string[length]; + for (int i = 0; i < length; i++) { arr[i] = GetString(); } return arr; } + /// + /// Note that "maxStringLength" only limits the number of characters in a string, not its size in bytes. + /// Strings that exceed this parameter are returned as empty + /// public string[] GetStringArray(int maxStringLength) { - ushort arraySize = GetUShort(); - var arr = new string[arraySize]; - for (int i = 0; i < arraySize; i++) + ushort length = GetUShort(); + string[] arr = new string[length]; + for (int i = 0; i < length; i++) { arr[i] = GetString(maxStringLength); } @@ -215,9 +210,7 @@ public string[] GetStringArray(int maxStringLength) public bool GetBool() { - bool res = _data[_position] > 0; - _position += 1; - return res; + return GetByte() == 1; } public char GetChar() @@ -301,9 +294,9 @@ public string GetString(int maxLength) ArraySegment data = GetBytesSegment(actualSize); - return (maxLength > 0 && _uTF8Encoding.GetCharCount(data.Array, data.Offset, data.Count) > maxLength) ? + return (maxLength > 0 && NetDataWriter.uTF8Encoding.GetCharCount(data.Array, data.Offset, data.Count) > maxLength) ? string.Empty : - _uTF8Encoding.GetString(data.Array, data.Offset, data.Count); + NetDataWriter.uTF8Encoding.GetString(data.Array, data.Offset, data.Count); } public string GetString() @@ -322,7 +315,7 @@ public string GetString() ArraySegment data = GetBytesSegment(actualSize); - return _uTF8Encoding.GetString(data.Array, data.Offset, data.Count); + return NetDataWriter.uTF8Encoding.GetString(data.Array, data.Offset, data.Count); } public ArraySegment GetBytesSegment(int count) @@ -368,20 +361,12 @@ public void GetBytes(byte[] destination, int count) public sbyte[] GetSBytesWithLength() { - int length = GetInt(); - sbyte[] outgoingData = new sbyte[length]; - Buffer.BlockCopy(_data, _position, outgoingData, 0, length); - _position += length; - return outgoingData; + return GetArray(1); } public byte[] GetBytesWithLength() { - int length = GetInt(); - byte[] outgoingData = new byte[length]; - Buffer.BlockCopy(_data, _position, outgoingData, 0, length); - _position += length; - return outgoingData; + return GetArray(1); } #endregion @@ -399,7 +384,7 @@ public sbyte PeekSByte() public bool PeekBool() { - return _data[_position] > 0; + return _data[_position] == 1; } public char PeekChar() @@ -447,6 +432,9 @@ public double PeekDouble() return BitConverter.ToDouble(_data, _position); } + /// + /// Note that "maxLength" only limits the number of characters in a string, not its size in bytes. + /// public string PeekString(int maxLength) { ushort size = PeekUShort(); @@ -461,9 +449,9 @@ public string PeekString(int maxLength) return null; } - return (maxLength > 0 && _uTF8Encoding.GetCharCount(_data, _position + 2, actualSize) > maxLength) ? + return (maxLength > 0 && NetDataWriter.uTF8Encoding.GetCharCount(_data, _position + 2, actualSize) > maxLength) ? string.Empty : - _uTF8Encoding.GetString(_data, _position + 2, actualSize); + NetDataWriter.uTF8Encoding.GetString(_data, _position + 2, actualSize); } public string PeekString() @@ -480,7 +468,7 @@ public string PeekString() return null; } - return _uTF8Encoding.GetString(_data, _position + 2, actualSize); + return NetDataWriter.uTF8Encoding.GetString(_data, _position + 2, actualSize); } #endregion @@ -634,9 +622,7 @@ public bool TryGetString(out string result) public bool TryGetStringArray(out string[] result) { - ushort strArrayLength; - if (!TryGetUShort(out strArrayLength)) - { + if (!TryGetUShort(out ushort strArrayLength)) { result = null; return false; } @@ -656,10 +642,10 @@ public bool TryGetStringArray(out string[] result) public bool TryGetBytesWithLength(out byte[] result) { - if (AvailableBytes >= 4) + if (AvailableBytes >= 2) { - var length = PeekInt(); - if (length >= 0 && AvailableBytes >= length + 4) + ushort length = PeekUShort(); + if (length >= 0 && AvailableBytes >= 2 + length) { result = GetBytesWithLength(); return true; diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 1c9d724c..c60d571c 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -12,14 +12,26 @@ public class NetDataWriter private const int InitialSize = 64; private readonly bool _autoResize; - public int Capacity => _data.Length; - public byte[] Data => _data; - public int Length => _position; + public int Capacity + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _data.Length; + } + public byte[] Data + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _data; + } + public int Length + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _position; + } // Cache encoding instead of creating it with BinaryWriter each time // 1000 readers before: 1MB GC, 30ms // 1000 readers after: .8MB GC, 18ms - private static readonly UTF8Encoding _uTF8Encoding = new UTF8Encoding(false, true); + public static readonly UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true); public const int StringBufferMaxLength = 1024 * 32; // <- short.MaxValue + 1 private readonly byte[] _stringBuffer = new byte[StringBufferMaxLength]; @@ -222,40 +234,32 @@ public void Put(byte[] data) _position += data.Length; } - public void PutSBytesWithLength(sbyte[] data, int offset, int length) + public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) { if (_autoResize) - ResizeIfNeed(_position + length + 4); + ResizeIfNeed(_position + 2 + length); FastBitConverter.GetBytes(_data, _position, length); - Buffer.BlockCopy(data, offset, _data, _position + 4, length); - _position += length + 4; + Buffer.BlockCopy(data, offset, _data, _position + 2, length); + _position += 2 + length; } public void PutSBytesWithLength(sbyte[] data) { - if (_autoResize) - ResizeIfNeed(_position + data.Length + 4); - FastBitConverter.GetBytes(_data, _position, data.Length); - Buffer.BlockCopy(data, 0, _data, _position + 4, data.Length); - _position += data.Length + 4; + PutArray(data, 1); } - public void PutBytesWithLength(byte[] data, int offset, int length) + public void PutBytesWithLength(byte[] data, int offset, ushort length) { if (_autoResize) - ResizeIfNeed(_position + length + 4); + ResizeIfNeed(_position + 2 + length); FastBitConverter.GetBytes(_data, _position, length); - Buffer.BlockCopy(data, offset, _data, _position + 4, length); - _position += length + 4; + Buffer.BlockCopy(data, offset, _data, _position + 2, length); + _position += 2 + length; } public void PutBytesWithLength(byte[] data) { - if (_autoResize) - ResizeIfNeed(_position + data.Length + 4); - FastBitConverter.GetBytes(_data, _position, data.Length); - Buffer.BlockCopy(data, 0, _data, _position + 4, data.Length); - _position += data.Length + 4; + PutArray(data, 1); } public void Put(bool value) @@ -263,7 +267,7 @@ public void Put(bool value) Put((byte)(value ? 1 : 0)); } - private void PutArray(Array arr, int sz) + public void PutArray(Array arr, int sz) { ushort length = arr == null ? (ushort) 0 : (ushort)arr.Length; sz *= length; @@ -359,7 +363,7 @@ public void Put(string value, int maxLength) } int length = maxLength > 0 && value.Length > maxLength ? maxLength : value.Length; - int size = _uTF8Encoding.GetBytes(value, 0, length, _stringBuffer, 0); + int size = uTF8Encoding.GetBytes(value, 0, length, _stringBuffer, 0); if (size >= StringBufferMaxLength) { From f5026ea9b7d642cebb1cb12bddeae0e9152aef87 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Fri, 26 Aug 2022 14:39:08 +0300 Subject: [PATCH 004/261] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index ff37c032..b31e37f3 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,10 @@ Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/revx) +`btc:bc1q8tlklzw4r5v7rcndmmk6huq3u7x0cuuvhaff7s` + +`litecoin:LTC1QHZYH9VD3Z2TYKSYMA8CDUZVTGHGXDZTTHGQRK7` + **Discord chat**: [![Discord](https://img.shields.io/discord/501682175930925058.svg)](https://discord.gg/FATFPdy) [OLD BRANCH (and examples) for 0.9.x](https://github.com/RevenantX/LiteNetLib/tree/0.9) From 2c308db4f52def93950eee5695602c14cc4e69bd Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Sat, 27 Aug 2022 01:05:37 +0300 Subject: [PATCH 005/261] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b31e37f3..e0b07f49 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,11 @@ Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/revx) -`btc:bc1q8tlklzw4r5v7rcndmmk6huq3u7x0cuuvhaff7s` +`BTC:3PF6yfBQbtCedjdDx6HAY2PZVUUnuTDFik` -`litecoin:LTC1QHZYH9VD3Z2TYKSYMA8CDUZVTGHGXDZTTHGQRK7` +`LTC:LTEdSyRomuJiMDM4r8rH17HYBHyU4D8sHR` + +`ETH:0x276Bc6F6e36773Eab084479F91FcB184B0B34927` **Discord chat**: [![Discord](https://img.shields.io/discord/501682175930925058.svg)](https://discord.gg/FATFPdy) From 419c55468f47afb543601e953f68b385f985c300 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Sat, 27 Aug 2022 03:30:02 +0300 Subject: [PATCH 006/261] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e0b07f49..60b58ef5 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,11 @@ Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/revx) -`BTC:3PF6yfBQbtCedjdDx6HAY2PZVUUnuTDFik` +`BTC:bc1qn3lwhafsp7ka0r5lew0v7r3qnpj62atqju809n` -`LTC:LTEdSyRomuJiMDM4r8rH17HYBHyU4D8sHR` +`LTC:LTQqo9yjGVWrXahAByqvx9Jo5TaotjDKXJ` -`ETH:0x276Bc6F6e36773Eab084479F91FcB184B0B34927` +`ETH:0x78664986894932bD399B1539D9F65155D0BF55bd` **Discord chat**: [![Discord](https://img.shields.io/discord/501682175930925058.svg)](https://discord.gg/FATFPdy) From 37ad7c615a0a65a469a187d2cfed5e0120493c9e Mon Sep 17 00:00:00 2001 From: Joakim Date: Sat, 1 Oct 2022 08:33:11 +0200 Subject: [PATCH 007/261] Update netserializerusage.md --- docfx_project/articles/netserializerusage.md | 115 ++++++++++++------- 1 file changed, 75 insertions(+), 40 deletions(-) diff --git a/docfx_project/articles/netserializerusage.md b/docfx_project/articles/netserializerusage.md index 20ea8b9b..e18a079b 100644 --- a/docfx_project/articles/netserializerusage.md +++ b/docfx_project/articles/netserializerusage.md @@ -1,13 +1,8 @@ # NetPacketProcessor Fast specialized for network purposes serializer.
-It supports **classes** with **public properties with "get" and "set"** methods or **classes/structs with implemented `INetSerializable`**.
-Serializer adds some overhead in size: 64 bit hash of class name and namespace (8 bytes). All other class fields will be as is in resulting packet. -## Supported property types -```csharp -byte sbyte short ushort int uint long ulong float double bool string char IPEndPoint -``` -Arrays of all this types and custom types also supported
-Enums also supported but work a bit slower than other types +It supports **classes** with **public properties with "get" and "set"** methods or **classes/structs which implements `INetSerializable`**.
+Serializer adds some overhead to packet size: 64 bit hash of class name and namespace (8 bytes). All other class fields will be as is in resulting packet. + ## Serialization speed comparsion Serialization 100000 times of simple structure from [example](https://github.com/RevenantX/LiteNetLib/blob/master/LibSample/SerializerBenchmark.cs) (`NET 4.5`): Serializer|Time|Size @@ -16,29 +11,28 @@ BinaryFormatter|3334 ms|1096 bytes NetSerializer (first run)|45 ms|204 bytes NetSerializer (second run)|37 ms|204 bytes Raw|24 ms|204 bytes -## Packet Example + +## Supported property types ```csharp -class SamplePacket -{ - public string SomeString { get; set; } - public float SomeFloat { get; set; } - public int[] SomeIntArray { get; set; } -} +byte sbyte short ushort int uint long ulong float double bool string char IPEndPoint ``` -## Custom field -NetPacketProcessor doesn't support nested structs or classes.
-But you can register custom type processor.
-That usefull for game engine types such as Vector3 and Quaternion (in Unity3d). +Arrays of all these types (and custom types) are also supported.
+Enums are supported but work a bit slower than other types. + +## Custom types +NetPacketProcessor doesn't support nested structs or classes, but you can register your own custom type processors.
+That useful for game engine types such as Vector3 and Quaternion (in Unity3d). + ```csharp -//Your packet that will be sent over network +// Your packet that will be sent over network class SamplePacket { + // Both property and array are supported public MyType SomeMyType { get; set; } - //Arrays of custom types supported too public MyType[] SomeMyTypes { get; set; } } -//Some custom type (variant 1) +// Some custom type variant 1: Basic struct struct MyType { public int Value1; @@ -60,12 +54,38 @@ struct MyType } ... netPacketProcessor = new NetPacketProcessor(); -netPacketProcessor.RegisterNestedType( MyType.Serialize, MyType.Deserialize ); +netPacketProcessor.RegisterNestedType( MyType.Serialize, MyType.Deserialize ); // Supply Serialization methods +``` + +You can also implement INetSerializable interface: +```csharp +// Some custom type variant 2: INetSerializable struct +struct MyType : INetSerializable +{ + public int Value1; + public string Value2; + + public void Serialize(NetDataWriter writer) + { + writer.Put(Value1); + writer.Put(Value2); + } + + public void Deserialize(NetDataReader reader) + { + Value1 = reader.GetInt(); + Value2 = reader.GetString(); + } +} +... +netPacketProcessor = new NetPacketProcessor(); +netPacketProcessor.RegisterNestedType(); // Serialization handled automatically thanks to INetSerializable ``` -Another variant you can implement INetSerializable interface: + +If you want to use a class instead of a struct you must implement the INetSerializable interface and provide a constructor: ```csharp -//Some custom type (variant 2) -struct SomeMyType : INetSerializable +// Some custom type variant 3: Class, must implement INetSerializable +class MyType : INetSerializable { public int Value1; public string Value2; @@ -84,58 +104,73 @@ struct SomeMyType : INetSerializable } ... netPacketProcessor = new NetPacketProcessor(); -netPacketProcessor.RegisterNestedType(); +netPacketProcessor.RegisterNestedType(() => { return new SomeMyType(); }); // Must provide constructor ``` -Or if you want use struct instead of class (and implement INetSerializable interface) -you must provide constructor: + +## Usage example +For full example look at source [SerializerBenchmark](https://github.com/RevenantX/LiteNetLib/blob/master/LibSample/SerializerBenchmark.cs) + +### Packet ```csharp -netPacketProcessor.RegisterNestedType(() => { return new SomeMyType(); }); +class SamplePacket +{ + // All of these will be automatically serialized and deserialized + public string SomeString { get; set; } + public float SomeFloat { get; set; } + public int[] SomeIntArray { get; set; } +} ``` -## Usage example (for full example look at source [SerializerBenchmark](https://github.com/RevenantX/LiteNetLib/blob/master/LibSample/SerializerBenchmark.cs)) + +### Sending / recieving ```csharp -//First side +// Client class SomeClientListener : INetEventListener { private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(); ... public void OnPeerConnected(NetPeer peer) { - SamplePacket sp = new SamplePacket + // After connection is established you will have the server as a NetPeer + SamplePacket packet = new SamplePacket { SomeFloat = 3.42f, SomeIntArray = new[] {6, 5, 4}, SomeString = "Test String", } - peer.Send(_netPacketProcessor.Write(sp), DeliveryMethod.ReliableOrdered); - //or you can use _netPacketProcessor.Send(peer, sp, DeliveryMethod.ReliableOrdered); + // Serialize the packet with NetSerializer and send it to the peer (server) + peer.Send(_netPacketProcessor.Write(packet), DeliveryMethod.ReliableOrdered); + //You can also use _netPacketProcessor.Send(peer, packet, DeliveryMethod.ReliableOrdered); } } -//Other side +// Server class SomeServerListener : INetEventListener { private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(); public SomeServerListener() { - //Subscribe to packet receiving + // Subscribe to recieving packets. _netPacketProcessor.SubscribeReusable(OnSamplePacketReceived); } + // Handler for SamplePacket, registered in constructor above private void OnSamplePacketReceived(SamplePacket samplePacket, NetPeer peer) { Console.WriteLine("[Server] ReceivedPacket:\n" + samplePacket.SomeString); } + // INetEventListener function. public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod) { Console.WriteLine("[Server] received data. Processing..."); + // Deserializes packet and calls the handler registered in constructor _netPacketProcessor.ReadAllPackets(reader, peer); } } ``` ### Mini FAQ - -Q: `NetPacketProcessor` throws "`Undefined packet in NetDataReader`" but all packets registered
-A: check that registered packet classes in same namespace (and better use shared code for packets) \ No newline at end of file +Q: `NetPacketProcessor` throws "`Undefined packet in NetDataReader`" but all packets are registered.
+A: This can happen when packet definitions resides in different namespaces. Check that registered packet classes/structs are in the same namespace on both ends. +To avoid this error altogether, use shared code/-assembly for packets. From a4c61341b90f475b058cd14188d145eaa40544ed Mon Sep 17 00:00:00 2001 From: RevenantX Date: Sat, 1 Oct 2022 12:18:30 +0300 Subject: [PATCH 008/261] update docs --- docs/articles/netserializerusage.html | 101 ++++++++++++++++---------- docs/manifest.json | 4 +- 2 files changed, 66 insertions(+), 39 deletions(-) diff --git a/docs/articles/netserializerusage.html b/docs/articles/netserializerusage.html index 324badfb..3e5cdfef 100644 --- a/docs/articles/netserializerusage.html +++ b/docs/articles/netserializerusage.html @@ -70,12 +70,8 @@

NetPacketProcessor

Fast specialized for network purposes serializer.
-It supports classes with public properties with "get" and "set" methods or classes/structs with implemented INetSerializable.
-Serializer adds some overhead in size: 64 bit hash of class name and namespace (8 bytes). All other class fields will be as is in resulting packet.

-

Supported property types

-
byte sbyte short ushort int uint long ulong float double bool string char IPEndPoint
-

Arrays of all this types and custom types also supported
-Enums also supported but work a bit slower than other types

+It supports classes with public properties with "get" and "set" methods or classes/structs which implements INetSerializable.
+Serializer adds some overhead to packet size: 64 bit hash of class name and namespace (8 bytes). All other class fields will be as is in resulting packet.

Serialization speed comparsion

Serialization 100000 times of simple structure from example (NET 4.5):

@@ -109,26 +105,22 @@

Serialization speed comparsion

-

Packet Example

-
class SamplePacket
-{
-    public string SomeString { get; set; }
-    public float SomeFloat { get; set; }
-    public int[] SomeIntArray { get; set; }
-}
-

Custom field

-

NetPacketProcessor doesn't support nested structs or classes.
-But you can register custom type processor.
-That usefull for game engine types such as Vector3 and Quaternion (in Unity3d).

-
//Your packet that will be sent over network
+

Supported property types

+
byte sbyte short ushort int uint long ulong float double bool string char IPEndPoint
+

Arrays of all these types (and custom types) are also supported.
+Enums are supported but work a bit slower than other types.

+

Custom types

+

NetPacketProcessor doesn't support nested structs or classes, but you can register your own custom type processors.
+That useful for game engine types such as Vector3 and Quaternion (in Unity3d).

+
// Your packet that will be sent over network
 class SamplePacket
 {
+    // Both property and array are supported
     public MyType SomeMyType { get; set; }
-    //Arrays of custom types supported too
     public MyType[] SomeMyTypes { get; set; } 
 }
 
-//Some custom type (variant 1)
+// Some custom type variant 1: Basic struct
 struct MyType
 {
     public int Value1;
@@ -150,10 +142,32 @@ 

Packet Example

} ... netPacketProcessor = new NetPacketProcessor(); -netPacketProcessor.RegisterNestedType( MyType.Serialize, MyType.Deserialize ); -

Another variant you can implement INetSerializable interface:

-
//Some custom type (variant 2)
-struct SomeMyType : INetSerializable
+netPacketProcessor.RegisterNestedType( MyType.Serialize, MyType.Deserialize ); // Supply Serialization methods
+

You can also implement INetSerializable interface:

+
// Some custom type variant 2: INetSerializable struct
+struct MyType : INetSerializable
+{
+    public int Value1;
+    public string Value2;
+
+    public void Serialize(NetDataWriter writer)
+    {
+        writer.Put(Value1);
+        writer.Put(Value2);
+    }
+
+    public void Deserialize(NetDataReader reader)
+    {
+        Value1 = reader.GetInt();
+        Value2 = reader.GetString();
+    }
+}
+...
+netPacketProcessor = new NetPacketProcessor();
+netPacketProcessor.RegisterNestedType<MyType>(); // Serialization handled automatically thanks to INetSerializable
+

If you want to use a class instead of a struct you must implement the INetSerializable interface and provide a constructor:

+
// Some custom type variant 3: Class, must implement INetSerializable
+class MyType : INetSerializable
 {
     public int Value1;
     public string Value2;
@@ -172,54 +186,67 @@ 

Packet Example

} ... netPacketProcessor = new NetPacketProcessor(); -netPacketProcessor.RegisterNestedType<SomeMyType>(); -

Or if you want use struct instead of class (and implement INetSerializable interface) -you must provide constructor:

-
netPacketProcessor.RegisterNestedType<SomeMyType>(() => { return new SomeMyType(); });
-

Usage example (for full example look at source SerializerBenchmark)

-
//First side
+netPacketProcessor.RegisterNestedType<MyType>(() => { return new SomeMyType(); }); // Must provide constructor
+

Usage example

+

For full example look at source SerializerBenchmark

+

Packet

+
class SamplePacket
+{
+    // All of these will be automatically serialized and deserialized
+    public string SomeString { get; set; }
+    public float SomeFloat { get; set; }
+    public int[] SomeIntArray { get; set; }
+}
+

Sending / recieving

+
// Client
 class SomeClientListener : INetEventListener
 {
    private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor();
 ...
    public void OnPeerConnected(NetPeer peer)
    {
-       SamplePacket sp = new SamplePacket
+        // After connection is established you will have the server as a NetPeer
+       SamplePacket packet = new SamplePacket
        {
            SomeFloat = 3.42f,
            SomeIntArray = new[] {6, 5, 4},
            SomeString = "Test String",
        }
-       peer.Send(_netPacketProcessor.Write(sp), DeliveryMethod.ReliableOrdered);
-       //or you can use _netPacketProcessor.Send(peer, sp, DeliveryMethod.ReliableOrdered);
+       // Serialize the packet with NetSerializer and send it to the peer (server)
+       peer.Send(_netPacketProcessor.Write(packet), DeliveryMethod.ReliableOrdered);
+       //You can also use _netPacketProcessor.Send(peer, packet, DeliveryMethod.ReliableOrdered);
    }
 }
 
-//Other side 
+// Server 
 class SomeServerListener : INetEventListener
 {
     private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor();
 
     public SomeServerListener()
     {
-        //Subscribe to packet receiving
+        // Subscribe to recieving packets.        
         _netPacketProcessor.SubscribeReusable<SamplePacket, NetPeer>(OnSamplePacketReceived);
     }
 
+    // Handler for SamplePacket, registered in constructor above
     private void OnSamplePacketReceived(SamplePacket samplePacket, NetPeer peer)
     {
         Console.WriteLine("[Server] ReceivedPacket:\n" + samplePacket.SomeString);
     }
 
+    // INetEventListener function.
     public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod)
     {
         Console.WriteLine("[Server] received data. Processing...");
+        // Deserializes packet and calls the handler registered in constructor
         _netPacketProcessor.ReadAllPackets(reader, peer);
     }
 }
 

Mini FAQ

-

Q: NetPacketProcessor throws "Undefined packet in NetDataReader" but all packets registered
-A: check that registered packet classes in same namespace (and better use shared code for packets)

+

Q: NetPacketProcessor throws "Undefined packet in NetDataReader" but all packets are registered.
+A: This can happen when packet definitions resides in different namespaces. Check that registered packet classes/structs are in the same namespace on both ends. +To avoid this error altogether, use shared code/-assembly for packets.

diff --git a/docs/manifest.json b/docs/manifest.json index ef9f9400..a4142af4 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,6 +1,6 @@ { "homepages": [], - "source_base_path": "D:/Projects/LiteNetLib/docfx_project", + "source_base_path": "d:/Projects/LiteNetLib/docfx_project", "xrefmap": "xrefmap.yml", "files": [ { @@ -585,7 +585,7 @@ "output": { ".html": { "relative_path": "articles/netserializerusage.html", - "hash": "oOUQI0iABiQGut/lmxmqrjlo8K0OF3kvqsIGhlCpfT4=" + "hash": "2AuloC57qynbPWwWGVUyC8YNLRE8Lk2MpO2YdDfe5iU=" } }, "is_incremental": false, From 49e6a13bf045636a7fffa70da78afdd7a2690055 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Sun, 27 Nov 2022 13:10:41 +0200 Subject: [PATCH 009/261] move support info to bottom --- README.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 60b58ef5..3f6d3a9b 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,6 @@ Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework [![Made in Ukraine](https://img.shields.io/badge/made_in-ukraine-ffd700.svg?labelColor=0057b7)](https://stand-with-ukraine.pp.ua) -[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/revx) - -`BTC:bc1qn3lwhafsp7ka0r5lew0v7r3qnpj62atqju809n` - -`LTC:LTQqo9yjGVWrXahAByqvx9Jo5TaotjDKXJ` - -`ETH:0x78664986894932bD399B1539D9F65155D0BF55bd` - **Discord chat**: [![Discord](https://img.shields.io/discord/501682175930925058.svg)](https://discord.gg/FATFPdy) [OLD BRANCH (and examples) for 0.9.x](https://github.com/RevenantX/LiteNetLib/tree/0.9) @@ -62,6 +54,13 @@ Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework * Monogame * Godot * Unity 2018.3 (Desktop platforms, Android, iOS, Switch) + +## Support developer +[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/revx) + +USDT TRX:`TQAjksKm6Mg6yivG4CDmvQhejBMkKn9hxv` + +USDT ETH:`0xe1303716ad9f97319FbEeE6616ccb4C4C81F5157` ## Unity notes!!! * Minimal supported Unity is 2018.3. For older Unity versions use [0.9.x library](https://github.com/RevenantX/LiteNetLib/tree/0.9) versions From 053cddc78b72e889fbcb1cdcfba406381a6a89f9 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Tue, 6 Dec 2022 18:32:17 +0200 Subject: [PATCH 010/261] use string interpolation for debug logs --- LiteNetLib/NatPunchModule.cs | 7 +++---- LiteNetLib/NetDebug.cs | 20 ++++++++++---------- LiteNetLib/NetManager.Socket.cs | 2 +- LiteNetLib/NetManager.cs | 17 ++++++----------- LiteNetLib/NetPeer.cs | 33 +++++++++++++-------------------- LiteNetLib/NetUtils.cs | 12 ++++-------- LiteNetLib/ReliableChannel.cs | 6 +++--- 7 files changed, 40 insertions(+), 57 deletions(-) diff --git a/LiteNetLib/NatPunchModule.cs b/LiteNetLib/NatPunchModule.cs index bab2fca0..2310452c 100644 --- a/LiteNetLib/NatPunchModule.cs +++ b/LiteNetLib/NatPunchModule.cs @@ -216,7 +216,7 @@ private void OnNatIntroductionResponse(NatIntroduceResponsePacket req) // send internal punch var punchPacket = new NatPunchPacket {Token = req.Token}; Send(punchPacket, req.Internal); - NetDebug.Write(NetLogLevel.Trace, "[NAT] internal punch sent to " + req.Internal); + NetDebug.Write(NetLogLevel.Trace, $"[NAT] internal punch sent to {req.Internal}"); // hack for some routers _socket.Ttl = 2; @@ -226,15 +226,14 @@ private void OnNatIntroductionResponse(NatIntroduceResponsePacket req) _socket.Ttl = NetConstants.SocketTTL; punchPacket.IsExternal = true; Send(punchPacket, req.External); - NetDebug.Write(NetLogLevel.Trace, "[NAT] external punch sent to " + req.External); + NetDebug.Write(NetLogLevel.Trace, $"[NAT] external punch sent to {req.External}"); } //We got punch and can connect private void OnNatPunch(NatPunchPacket req, IPEndPoint senderEndPoint) { //Read info - NetDebug.Write(NetLogLevel.Trace, "[NAT] punch received from {0} - additional info: {1}", - senderEndPoint, req.Token); + NetDebug.Write(NetLogLevel.Trace, $"[NAT] punch received from {senderEndPoint} - additional info: {req.Token}"); //Release punch success to client; enabling him to Connect() to Sender if token is ok if(UnsyncedEvents) diff --git a/LiteNetLib/NetDebug.cs b/LiteNetLib/NetDebug.cs index a326c0d0..44cb6f3e 100644 --- a/LiteNetLib/NetDebug.cs +++ b/LiteNetLib/NetDebug.cs @@ -61,32 +61,32 @@ private static void WriteLogic(NetLogLevel logLevel, string str, params object[] } [Conditional("DEBUG_MESSAGES")] - internal static void Write(string str, params object[] args) + internal static void Write(string str) { - WriteLogic(NetLogLevel.Trace, str, args); + WriteLogic(NetLogLevel.Trace, str); } [Conditional("DEBUG_MESSAGES")] - internal static void Write(NetLogLevel level, string str, params object[] args) + internal static void Write(NetLogLevel level, string str) { - WriteLogic(level, str, args); + WriteLogic(level, str); } [Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")] - internal static void WriteForce(string str, params object[] args) + internal static void WriteForce(string str) { - WriteLogic(NetLogLevel.Trace, str, args); + WriteLogic(NetLogLevel.Trace, str); } [Conditional("DEBUG_MESSAGES"), Conditional("DEBUG")] - internal static void WriteForce(NetLogLevel level, string str, params object[] args) + internal static void WriteForce(NetLogLevel level, string str) { - WriteLogic(level, str, args); + WriteLogic(level, str); } - internal static void WriteError(string str, params object[] args) + internal static void WriteError(string str) { - WriteLogic(NetLogLevel.Error, str, args); + WriteLogic(NetLogLevel.Error, str); } } } diff --git a/LiteNetLib/NetManager.Socket.cs b/LiteNetLib/NetManager.Socket.cs index 706e8f81..a218231a 100644 --- a/LiteNetLib/NetManager.Socket.cs +++ b/LiteNetLib/NetManager.Socket.cs @@ -606,7 +606,7 @@ internal int SendRaw(byte[] message, int start, int length, IPEndPoint remoteEnd case SocketError.Interrupted: return 0; case SocketError.MessageSize: - NetDebug.Write(NetLogLevel.Trace, "[SRD] 10040, datalen: {0}", length); + NetDebug.Write(NetLogLevel.Trace, $"[SRD] 10040, datalen: {length}"); return 0; case SocketError.HostUnreachable: diff --git a/LiteNetLib/NetManager.cs b/LiteNetLib/NetManager.cs index 1b1cca67..c5f14f0a 100644 --- a/LiteNetLib/NetManager.cs +++ b/LiteNetLib/NetManager.cs @@ -803,8 +803,7 @@ internal NetPeer OnConnectionSolved(ConnectionRequest request, byte[] rejectData AddPeer(netPeer); _peersLock.ExitUpgradeableReadLock(); CreateEvent(NetEvent.EType.Connect, netPeer); - NetDebug.Write(NetLogLevel.Trace, "[NM] Received peer connection Id: {0}, EP: {1}", - netPeer.ConnectTime, netPeer.EndPoint); + NetDebug.Write(NetLogLevel.Trace, $"[NM] Received peer connection Id: {netPeer.ConnectTime}, EP: {netPeer.EndPoint}"); } } @@ -828,11 +827,7 @@ private void ProcessConnectRequest( if (netPeer != null) { var processResult = netPeer.ProcessConnectRequest(connRequest); - NetDebug.Write("ConnectRequest LastId: {0}, NewId: {1}, EP: {2}, Result: {3}", - netPeer.ConnectTime, - connRequest.ConnectionTime, - remoteEndPoint, - processResult); + NetDebug.Write($"ConnectRequest LastId: {netPeer.ConnectTime}, NewId: {connRequest.ConnectionTime}, EP: {remoteEndPoint}, Result: {processResult}"); switch (processResult) { @@ -862,7 +857,7 @@ private void ProcessConnectRequest( } else { - NetDebug.Write("ConnectRequest Id: {0}, EP: {1}", connRequest.ConnectionTime, remoteEndPoint); + NetDebug.Write($"ConnectRequest Id: {connRequest.ConnectionTime}, EP: {remoteEndPoint}"); } ConnectionRequest req; @@ -876,7 +871,7 @@ private void ProcessConnectRequest( req = new ConnectionRequest(remoteEndPoint, connRequest, this); _requestsDict.Add(remoteEndPoint, req); } - NetDebug.Write("[NM] Creating request event: " + connRequest.ConnectionTime); + NetDebug.Write($"[NM] Creating request event: {connRequest.ConnectionTime}"); CreateEvent(NetEvent.EType.ConnectionRequest, connectionRequest: req); } @@ -927,7 +922,7 @@ private void DebugMessageReceived(NetPacket packet, IPEndPoint remoteEndPoint) { if (packet.Size < 48) { - NetDebug.Write(NetLogLevel.Trace, "NTP response too short: {}", packet.Size); + NetDebug.Write(NetLogLevel.Trace, $"NTP response too short: {packet.Size}"); return; } @@ -940,7 +935,7 @@ private void DebugMessageReceived(NetPacket packet, IPEndPoint remoteEndPoint) } catch (InvalidOperationException ex) { - NetDebug.Write(NetLogLevel.Trace, "NTP response error: {}", ex.Message); + NetDebug.Write(NetLogLevel.Trace, $"NTP response error: {ex.Message}"); ntpPacket = null; } diff --git a/LiteNetLib/NetPeer.cs b/LiteNetLib/NetPeer.cs index 922c720e..66906789 100644 --- a/LiteNetLib/NetPeer.cs +++ b/LiteNetLib/NetPeer.cs @@ -613,13 +613,12 @@ private void SendInternal( int packetDataSize = packetFullSize - NetConstants.FragmentHeaderSize; int totalPackets = length / packetDataSize + (length % packetDataSize == 0 ? 0 : 1); - NetDebug.Write("FragmentSend:\n" + - " MTU: {0}\n" + - " headerSize: {1}\n" + - " packetFullSize: {2}\n" + - " packetDataSize: {3}\n" + - " totalPackets: {4}", - mtu, headerSize, packetFullSize, packetDataSize, totalPackets); + NetDebug.Write($@"FragmentSend: + MTU: {mtu} + headerSize: {headerSize} + packetFullSize: {packetFullSize} + packetDataSize: {packetDataSize} + totalPackets: {totalPackets}"); if (totalPackets > ushort.MaxValue) throw new TooBigPacketException("Data was split in " + totalPackets + " fragments, which exceeds " + ushort.MaxValue); @@ -891,7 +890,7 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) { if (p.IsFragmented) { - NetDebug.Write("Fragment. Id: {0}, Part: {1}, Total: {2}", p.FragmentId, p.FragmentPart, p.FragmentsTotal); + NetDebug.Write($"Fragment. Id: {p.FragmentId}, Part: {p.FragmentPart}, Total: {p.FragmentsTotal}"); //Get needed array from dictionary ushort packetFragId = p.FragmentId; byte packetChannelId = p.ChannelId; @@ -942,16 +941,13 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) if (pos+writtenSize > resultingPacket.RawData.Length) { _holdedFragments.Remove(packetFragId); - NetDebug.WriteError("Fragment error pos: {0} >= resultPacketSize: {1} , totalSize: {2}", - pos + writtenSize, - resultingPacket.RawData.Length, - incomingFragments.TotalSize); + NetDebug.WriteError($"Fragment error pos: {pos + writtenSize} >= resultPacketSize: {resultingPacket.RawData.Length} , totalSize: {incomingFragments.TotalSize}"); return; } if (fragment.Size > fragment.RawData.Length) { _holdedFragments.Remove(packetFragId); - NetDebug.WriteError("Fragment error size: {0} > fragment.RawData.Length: {1}", fragment.Size, fragment.RawData.Length); + NetDebug.WriteError($"Fragment error size: {fragment.Size} > fragment.RawData.Length: {fragment.RawData.Length}"); return; } @@ -992,7 +988,7 @@ private void ProcessMtuPacket(NetPacket packet) int endMtuCheck = BitConverter.ToInt32(packet.RawData, packet.Size - 4); if (receivedMtu != packet.Size || receivedMtu != endMtuCheck || receivedMtu > NetConstants.MaxPacketSize) { - NetDebug.WriteError("[MTU] Broken packet. RMTU {0}, EMTU {1}, PSIZE {2}", receivedMtu, endMtuCheck, packet.Size); + NetDebug.WriteError($"[MTU] Broken packet. RMTU {receivedMtu}, EMTU {endMtuCheck}, PSIZE {packet.Size}"); return; } @@ -1131,7 +1127,7 @@ internal void ProcessPacket(NetPacket packet) } Interlocked.Exchange(ref _timeSinceLastPacket, 0); - NetDebug.Write("[RR]PacketProperty: {0}", packet.Property); + NetDebug.Write($"[RR]PacketProperty: {packet.Property}"); switch (packet.Property) { case PacketProperty.Merged: @@ -1176,7 +1172,7 @@ internal void ProcessPacket(NetPacket packet) _remoteDelta = BitConverter.ToInt64(packet.RawData, 3) + (elapsedMs * TimeSpan.TicksPerMillisecond ) / 2 - DateTime.UtcNow.Ticks; UpdateRoundTripTime(elapsedMs); NetManager.ConnectionLatencyUpdated(this, elapsedMs / 2); - NetDebug.Write("[PP]Ping: {0} - {1} - {2}", packet.Sequence, elapsedMs, _remoteDelta); + NetDebug.Write($"[PP]Ping: {packet.Sequence} - {elapsedMs} - {_remoteDelta}"); } NetManager.PoolRecycle(packet); break; @@ -1274,10 +1270,7 @@ internal void Update(int deltaTime) case ConnectionState.Connected: if (_timeSinceLastPacket > NetManager.DisconnectTimeout) { - NetDebug.Write( - "[UPDATE] Disconnect by timeout: {0} > {1}", - _timeSinceLastPacket, - NetManager.DisconnectTimeout); + NetDebug.Write($"[UPDATE] Disconnect by timeout: {_timeSinceLastPacket} > {NetManager.DisconnectTimeout}"); NetManager.DisconnectPeerForce(this, DisconnectReason.Timeout, 0, null); return; } diff --git a/LiteNetLib/NetUtils.cs b/LiteNetLib/NetUtils.cs index d162b2da..3b752e96 100644 --- a/LiteNetLib/NetUtils.cs +++ b/LiteNetLib/NetUtils.cs @@ -119,7 +119,7 @@ public static void GetLocalIpList(IList targetList, LocalAddrType addrTy { //ignored } - + if (targetList.Count == 0) { if(ipv4) @@ -150,7 +150,7 @@ public static string GetLocalIp(LocalAddrType addrType) // =========================================== internal static void PrintInterfaceInfos() { - NetDebug.WriteForce(NetLogLevel.Info, "IPv6Support: {0}", NetManager.IPv6Support); + NetDebug.WriteForce(NetLogLevel.Info, $"IPv6Support: { NetManager.IPv6Support}"); try { foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) @@ -162,18 +162,14 @@ internal static void PrintInterfaceInfos() { NetDebug.WriteForce( NetLogLevel.Info, - "Interface: {0}, Type: {1}, Ip: {2}, OpStatus: {3}", - ni.Name, - ni.NetworkInterfaceType.ToString(), - ip.Address.ToString(), - ni.OperationalStatus.ToString()); + $"Interface: {ni.Name}, Type: {ni.NetworkInterfaceType}, Ip: {ip.Address}, OpStatus: {ni.OperationalStatus}"); } } } } catch (Exception e) { - NetDebug.WriteForce(NetLogLevel.Info, "Error while getting interface infos: {0}", e.ToString()); + NetDebug.WriteForce(NetLogLevel.Info, $"Error while getting interface infos: {e}"); } } diff --git a/LiteNetLib/ReliableChannel.cs b/LiteNetLib/ReliableChannel.cs index f825e37d..98c62250 100644 --- a/LiteNetLib/ReliableChannel.cs +++ b/LiteNetLib/ReliableChannel.cs @@ -33,7 +33,7 @@ public bool TrySend(long currentTime, NetPeer peer) double packetHoldTime = currentTime - _timeStamp; if (packetHoldTime < resendDelay) return true; - NetDebug.Write("[RC]Resend: {0} > {1}", (int)packetHoldTime, resendDelay); + NetDebug.Write($"[RC]Resend: {packetHoldTime} > {resendDelay}"); } _timeStamp = currentTime; _isSent = true; @@ -148,7 +148,7 @@ private void ProcessAck(NetPacket packet) } //Skip false ack - NetDebug.Write("[PA]False ack: {0}", pendingSeq); + NetDebug.Write($"[PA]False ack: {pendingSeq}"); continue; } @@ -160,7 +160,7 @@ private void ProcessAck(NetPacket packet) //clear packet if (_pendingPackets[pendingIdx].Clear(Peer)) - NetDebug.Write("[PA]Removing reliableInOrder ack: {0} - true", pendingSeq); + NetDebug.Write($"[PA]Removing reliableInOrder ack: {pendingSeq} - true"); } } } From 16b97c3a35e5c36652221f507ce58f834a7ce959 Mon Sep 17 00:00:00 2001 From: FirstGearGames Date: Thu, 15 Dec 2022 14:23:40 -0500 Subject: [PATCH 011/261] Fixed NRE Added null check to Socket.CloseSocket. On iOS Socket can go null after !Socket.Start check, resulting in NRE on CloseSocket. --- LiteNetLib/NetManager.Socket.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/NetManager.Socket.cs b/LiteNetLib/NetManager.Socket.cs index a218231a..d5ebdb76 100644 --- a/LiteNetLib/NetManager.Socket.cs +++ b/LiteNetLib/NetManager.Socket.cs @@ -42,7 +42,7 @@ private void OnApplicationPause(bool pause) if (!Socket.Start(BindAddrIPv4, BindAddrIPv6, Port, ManualMode)) { NetDebug.WriteError("[S] Cannot restore connection \"{0}\",\"{1}\" port {2}", BindAddrIPv4, BindAddrIPv6, Port); - Socket.CloseSocket(false); + Socket?.CloseSocket(false); } } } From 20b97bb49fc3a61bcbacd17ed84e5a5800e517d0 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 4 Jan 2023 17:19:10 +0200 Subject: [PATCH 012/261] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 3f6d3a9b..fd07dc6a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework [![Made in Ukraine](https://img.shields.io/badge/made_in-ukraine-ffd700.svg?labelColor=0057b7)](https://stand-with-ukraine.pp.ua) +**HighLevel API Part**: [LiteEntitySystem](https://github.com/RevenantX/LiteEntitySystem) + **Discord chat**: [![Discord](https://img.shields.io/discord/501682175930925058.svg)](https://discord.gg/FATFPdy) [OLD BRANCH (and examples) for 0.9.x](https://github.com/RevenantX/LiteNetLib/tree/0.9) From 7c29fbc3d8ab4da332c73f9760efb37d315945dc Mon Sep 17 00:00:00 2001 From: Marc Johnson Date: Sun, 12 Feb 2023 13:03:13 -0600 Subject: [PATCH 013/261] Update inline variables in NetManager.Socket.cs Resolves build error "No overload for method 'WriteError' takes 4 arguments". Tested on Mac M2, Unity 2022.2.6f1 / IOS build. --- LiteNetLib/NetManager.Socket.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/NetManager.Socket.cs b/LiteNetLib/NetManager.Socket.cs index d5ebdb76..295f11fb 100644 --- a/LiteNetLib/NetManager.Socket.cs +++ b/LiteNetLib/NetManager.Socket.cs @@ -41,7 +41,7 @@ private void OnApplicationPause(bool pause) { if (!Socket.Start(BindAddrIPv4, BindAddrIPv6, Port, ManualMode)) { - NetDebug.WriteError("[S] Cannot restore connection \"{0}\",\"{1}\" port {2}", BindAddrIPv4, BindAddrIPv6, Port); + NetDebug.WriteError($"[S] Cannot restore connection \"{BindAddrIPv4}\",\"{BindAddrIPv6}\" port {Port}"); Socket?.CloseSocket(false); } } From f4d3f779d435f6701f7c4012fc90042108fac5ee Mon Sep 17 00:00:00 2001 From: FirstGearGames Date: Sat, 4 Mar 2023 12:58:26 -0500 Subject: [PATCH 014/261] NetManager.Socket -> PausedSocketFix Implementation --- LiteNetLib/NetManager.Socket.cs | 69 ++------------------------------- 1 file changed, 4 insertions(+), 65 deletions(-) diff --git a/LiteNetLib/NetManager.Socket.cs b/LiteNetLib/NetManager.Socket.cs index 295f11fb..e17c5b7f 100644 --- a/LiteNetLib/NetManager.Socket.cs +++ b/LiteNetLib/NetManager.Socket.cs @@ -1,8 +1,4 @@ -#if UNITY_IOS && !UNITY_EDITOR -using UnityEngine; -#endif using System.Runtime.InteropServices; - using System; using System.Collections.Generic; using System.Net; @@ -12,42 +8,6 @@ namespace LiteNetLib { -#if UNITY_IOS && !UNITY_EDITOR - public class UnitySocketFix : MonoBehaviour - { - internal IPAddress BindAddrIPv4; - internal IPAddress BindAddrIPv6; - internal int Port; - internal bool Paused; - internal NetManager Socket; - internal bool ManualMode; - - private void Update() - { - if (Socket == null) - Destroy(gameObject); - } - - private void OnApplicationPause(bool pause) - { - if (Socket == null) - return; - if (pause) - { - Paused = true; - Socket.CloseSocket(true); - } - else if (Paused) - { - if (!Socket.Start(BindAddrIPv4, BindAddrIPv6, Port, ManualMode)) - { - NetDebug.WriteError($"[S] Cannot restore connection \"{BindAddrIPv4}\",\"{BindAddrIPv6}\" port {Port}"); - Socket?.CloseSocket(false); - } - } - } - } -#endif public partial class NetManager { @@ -59,6 +19,7 @@ public partial class NetManager private Thread _threadv6; private IPEndPoint _bufferEndPointv4; private IPEndPoint _bufferEndPointv6; + private PausedSocketFix _pausedSocketFix; #if !LITENETLIB_UNSAFE [ThreadStatic] private static byte[] _sendToBuffer; @@ -70,9 +31,6 @@ public partial class NetManager private const int SioUdpConnreset = -1744830452; //SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12 private static readonly IPAddress MulticastAddressV6 = IPAddress.Parse("ff02::1"); public static readonly bool IPv6Support; -#if UNITY_IOS && !UNITY_EDITOR - private UnitySocketFix _unitySocketFix; -#endif ///
/// Maximum packets count that will be processed in Manual PollEvents @@ -111,11 +69,6 @@ static NetManager() private bool IsActive() { -#if UNITY_IOS && !UNITY_EDITOR - var unitySocketFix = _unitySocketFix; //save for multithread - if (unitySocketFix != null && unitySocketFix.Paused) - return false; -#endif return IsRunning; } @@ -304,23 +257,9 @@ public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool m LocalPort = ((IPEndPoint) _udpSocketv4.LocalEndPoint).Port; -#if UNITY_IOS && !UNITY_EDITOR - if (_unitySocketFix == null) - { - var unityFixObj = new GameObject("LiteNetLib_UnitySocketFix"); - GameObject.DontDestroyOnLoad(unityFixObj); - _unitySocketFix = unityFixObj.AddComponent(); - _unitySocketFix.Socket = this; - _unitySocketFix.BindAddrIPv4 = addressIPv4; - _unitySocketFix.BindAddrIPv6 = addressIPv6; - _unitySocketFix.Port = LocalPort; - _unitySocketFix.ManualMode = _manualMode; - } - else - { - _unitySocketFix.Paused = false; - } -#endif + if (_pausedSocketFix == null) + _pausedSocketFix = new PausedSocketFix(this, addressIPv4, addressIPv6, port, manualMode); + if (dualMode) _udpSocketv6 = _udpSocketv4; From c8bbcdb6fba6c19e8a6b396b88df95dba5a8124e Mon Sep 17 00:00:00 2001 From: FirstGearGames Date: Sat, 4 Mar 2023 12:59:03 -0500 Subject: [PATCH 015/261] Create PausedSocketFix.cs --- LiteNetLib/PausedSocketFix.cs | 73 +++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 LiteNetLib/PausedSocketFix.cs diff --git a/LiteNetLib/PausedSocketFix.cs b/LiteNetLib/PausedSocketFix.cs new file mode 100644 index 00000000..147cb3ea --- /dev/null +++ b/LiteNetLib/PausedSocketFix.cs @@ -0,0 +1,73 @@ + +using System.Net; + +namespace LiteNetLib +{ + + public class PausedSocketFix + { + public bool ApplicationFocused { get; private set; } + + private NetManager _netManager; + private IPAddress _ipv4; + private IPAddress _ipv6; + private int _port; + private bool _manualMode; + + + public PausedSocketFix() + { + UnityEngine.Application.focusChanged += Application_focusChanged; + } + public PausedSocketFix(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) : this() + { + Initialize(netManager, ipv4, ipv6, port, manualMode); + } + + ~PausedSocketFix() + { + UnityEngine.Application.focusChanged -= Application_focusChanged; + } + + public void Initialize(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) + { + _netManager = netManager; + _ipv4 = ipv4; + _ipv6 = ipv6; + _port = port; + _manualMode = manualMode; + } + + + private void Application_focusChanged(bool focused) + { + ApplicationFocused = focused; + //If coming back into focus see if a reconnect is needed. + if (focused) + TryReconnect(); + } + + + private void TryReconnect() + { + if (_netManager == null) + return; + //Was intentionally disconnected at some point. + if (!_netManager.IsRunning) + return; + //Socket is still running. + if (_netManager.SocketActive(false) || _netManager.SocketActive(true)) + return; + + //Socket isn't running but should be. Try to start again. + if (!_netManager.Start(_ipv4, _ipv6, _port, _manualMode)) + { + NetDebug.WriteError($"[S] Cannot restore connection. Ipv4 {_ipv4}, Ipv6 {_ipv6}, Port {_port}, ManualMode {_manualMode}"); + _netManager.CloseSocket(false); + } + } + + + } + +} From 5d5043cff23a6097af7bc88526fbb1e144af3b46 Mon Sep 17 00:00:00 2001 From: FirstGearGames Date: Sat, 4 Mar 2023 13:01:24 -0500 Subject: [PATCH 016/261] NetManager expose socket active state. --- LiteNetLib/NetManager.Socket.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/LiteNetLib/NetManager.Socket.cs b/LiteNetLib/NetManager.Socket.cs index e17c5b7f..552ae41a 100644 --- a/LiteNetLib/NetManager.Socket.cs +++ b/LiteNetLib/NetManager.Socket.cs @@ -11,6 +11,22 @@ namespace LiteNetLib public partial class NetManager { + public bool SocketActive(bool ipv4) + { + if (ipv4) + { + if (_udpSocketv4 != null) + return _udpSocketv4.Connected; + return false; + } + else + { + if (_udpSocketv6 != null) + return _udpSocketv6.Connected; + return false; + } + } + private const int ReceivePollingTime = 500000; //0.5 second private Socket _udpSocketv4; From 891a8c38dcf8726e7dd85d9ca4ca03d37dc49493 Mon Sep 17 00:00:00 2001 From: FirstGearGames Date: Sat, 4 Mar 2023 13:23:25 -0500 Subject: [PATCH 017/261] PausedSocketFix > Add defines. --- LiteNetLib/PausedSocketFix.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/LiteNetLib/PausedSocketFix.cs b/LiteNetLib/PausedSocketFix.cs index 147cb3ea..b97447e5 100644 --- a/LiteNetLib/PausedSocketFix.cs +++ b/LiteNetLib/PausedSocketFix.cs @@ -1,4 +1,4 @@ - + using System.Net; namespace LiteNetLib @@ -6,6 +6,7 @@ namespace LiteNetLib public class PausedSocketFix { +#if UNITY_32 || UNITY_64 || UNITY_EDITOR public bool ApplicationFocused { get; private set; } private NetManager _netManager; @@ -67,7 +68,7 @@ private void TryReconnect() } } - +#endif } } From 8020d8dc2e9994c6a4769a6e8d92a7d2de421492 Mon Sep 17 00:00:00 2001 From: FirstGearGames Date: Sun, 5 Mar 2023 10:04:40 -0500 Subject: [PATCH 018/261] Fixed compilation errors for non-Unity platforms. --- LiteNetLib/NetManager.cs | 2 ++ LiteNetLib/PausedSocketFix.cs | 36 ++++++++++++++++++++++++++--------- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/LiteNetLib/NetManager.cs b/LiteNetLib/NetManager.cs index c5f14f0a..1d8fc72c 100644 --- a/LiteNetLib/NetManager.cs +++ b/LiteNetLib/NetManager.cs @@ -1584,6 +1584,8 @@ public void Stop(bool sendDisconnectMessages) return; NetDebug.Write("[NM] Stop"); + _pausedSocketFix.Deinitialize(); + //Send last disconnect for(var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) netPeer.Shutdown(null, 0, 0, !sendDisconnectMessages); diff --git a/LiteNetLib/PausedSocketFix.cs b/LiteNetLib/PausedSocketFix.cs index b97447e5..45ee3cdc 100644 --- a/LiteNetLib/PausedSocketFix.cs +++ b/LiteNetLib/PausedSocketFix.cs @@ -1,4 +1,8 @@  +#if UNITY_64 || UNITY_EDITOR || UNITY_STANDALONE || UNITY_WII || UNITY_IOS || UNITY_ANDROID || UNITY_WSA || UNITY_WEBGL || UNITY_32 +#define UNITY +#endif + using System.Net; namespace LiteNetLib @@ -6,20 +10,17 @@ namespace LiteNetLib public class PausedSocketFix { -#if UNITY_32 || UNITY_64 || UNITY_EDITOR - public bool ApplicationFocused { get; private set; } + public bool ApplicationFocused { get; private set; } = true; private NetManager _netManager; private IPAddress _ipv4; private IPAddress _ipv6; private int _port; private bool _manualMode; + private bool _initialized; + + public PausedSocketFix() { } - - public PausedSocketFix() - { - UnityEngine.Application.focusChanged += Application_focusChanged; - } public PausedSocketFix(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) : this() { Initialize(netManager, ipv4, ipv6, port, manualMode); @@ -27,18 +28,34 @@ public PausedSocketFix(NetManager netManager, IPAddress ipv4, IPAddress ipv6, in ~PausedSocketFix() { - UnityEngine.Application.focusChanged -= Application_focusChanged; + Deinitialize(); } public void Initialize(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) { +#if UNITY _netManager = netManager; _ipv4 = ipv4; _ipv6 = ipv6; _port = port; _manualMode = manualMode; + + if (!_initialized) + UnityEngine.Application.focusChanged += Application_focusChanged; + + _initialized = true; +#endif } + public void Deinitialize() + { +#if UNITY + if (_initialized) + UnityEngine.Application.focusChanged -= Application_focusChanged; + + _initialized = false; +#endif + } private void Application_focusChanged(bool focused) { @@ -51,6 +68,8 @@ private void Application_focusChanged(bool focused) private void TryReconnect() { + if (!_initialized) + return; if (_netManager == null) return; //Was intentionally disconnected at some point. @@ -68,7 +87,6 @@ private void TryReconnect() } } -#endif } } From 762a4353c46aafb6b849e1f439f3e697c6ad2d31 Mon Sep 17 00:00:00 2001 From: FirstGearGames Date: Sun, 5 Mar 2023 10:13:36 -0500 Subject: [PATCH 019/261] Added auto-cleanup on NetManager null. --- LiteNetLib/PausedSocketFix.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/LiteNetLib/PausedSocketFix.cs b/LiteNetLib/PausedSocketFix.cs index 45ee3cdc..306c920c 100644 --- a/LiteNetLib/PausedSocketFix.cs +++ b/LiteNetLib/PausedSocketFix.cs @@ -70,8 +70,17 @@ private void TryReconnect() { if (!_initialized) return; + + /* If initialized and networkmanager + * went null then soemthing did not + * go right. It's possible the netmanager + * was destroyed without calling deinitialize. + * When this occurs deinitialize this instance. */ if (_netManager == null) + { + Deinitialize(); return; + } //Was intentionally disconnected at some point. if (!_netManager.IsRunning) return; From bfc59fb933420f7a79362d51f9557db0bafce308 Mon Sep 17 00:00:00 2001 From: FirstGearGames Date: Sun, 5 Mar 2023 12:13:37 -0500 Subject: [PATCH 020/261] Define change to be simplier. --- LiteNetLib/PausedSocketFix.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/PausedSocketFix.cs b/LiteNetLib/PausedSocketFix.cs index 306c920c..c5c86441 100644 --- a/LiteNetLib/PausedSocketFix.cs +++ b/LiteNetLib/PausedSocketFix.cs @@ -1,5 +1,5 @@  -#if UNITY_64 || UNITY_EDITOR || UNITY_STANDALONE || UNITY_WII || UNITY_IOS || UNITY_ANDROID || UNITY_WSA || UNITY_WEBGL || UNITY_32 +#if UNITY_2018_3_OR_NEWER #define UNITY #endif From ea38e6af0fb16b2e1137a7d482042a6befebb1df Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Sun, 5 Mar 2023 20:05:39 +0200 Subject: [PATCH 021/261] allow correct restart (with different ip/ports) for PausedSocketFix. Remove unused constructor. Simplify --- LiteNetLib/NetManager.Socket.cs | 4 ++ LiteNetLib/NetManager.cs | 3 + LiteNetLib/PausedSocketFix.cs | 101 ++++++++++++-------------------- 3 files changed, 43 insertions(+), 65 deletions(-) diff --git a/LiteNetLib/NetManager.Socket.cs b/LiteNetLib/NetManager.Socket.cs index 552ae41a..103b61ab 100644 --- a/LiteNetLib/NetManager.Socket.cs +++ b/LiteNetLib/NetManager.Socket.cs @@ -35,7 +35,9 @@ public bool SocketActive(bool ipv4) private Thread _threadv6; private IPEndPoint _bufferEndPointv4; private IPEndPoint _bufferEndPointv6; +#if UNITY_2018_3_OR_NEWER private PausedSocketFix _pausedSocketFix; +#endif #if !LITENETLIB_UNSAFE [ThreadStatic] private static byte[] _sendToBuffer; @@ -273,8 +275,10 @@ public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool m LocalPort = ((IPEndPoint) _udpSocketv4.LocalEndPoint).Port; +#if UNITY_2018_3_OR_NEWER if (_pausedSocketFix == null) _pausedSocketFix = new PausedSocketFix(this, addressIPv4, addressIPv6, port, manualMode); +#endif if (dualMode) _udpSocketv6 = _udpSocketv4; diff --git a/LiteNetLib/NetManager.cs b/LiteNetLib/NetManager.cs index 1d8fc72c..f1e46f2c 100644 --- a/LiteNetLib/NetManager.cs +++ b/LiteNetLib/NetManager.cs @@ -1584,7 +1584,10 @@ public void Stop(bool sendDisconnectMessages) return; NetDebug.Write("[NM] Stop"); +#if UNITY_2018_3_OR_NEWER _pausedSocketFix.Deinitialize(); + _pausedSocketFix = null; +#endif //Send last disconnect for(var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) diff --git a/LiteNetLib/PausedSocketFix.cs b/LiteNetLib/PausedSocketFix.cs index c5c86441..5e27dbd0 100644 --- a/LiteNetLib/PausedSocketFix.cs +++ b/LiteNetLib/PausedSocketFix.cs @@ -1,60 +1,35 @@ - -#if UNITY_2018_3_OR_NEWER -#define UNITY -#endif - +#if UNITY_2018_3_OR_NEWER using System.Net; namespace LiteNetLib { - public class PausedSocketFix { public bool ApplicationFocused { get; private set; } = true; - private NetManager _netManager; - private IPAddress _ipv4; - private IPAddress _ipv6; - private int _port; - private bool _manualMode; + private readonly NetManager _netManager; + private readonly IPAddress _ipv4; + private readonly IPAddress _ipv6; + private readonly int _port; + private readonly bool _manualMode; private bool _initialized; - public PausedSocketFix() { } - - public PausedSocketFix(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) : this() - { - Initialize(netManager, ipv4, ipv6, port, manualMode); - } - - ~PausedSocketFix() + public PausedSocketFix(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) { - Deinitialize(); - } - - public void Initialize(NetManager netManager, IPAddress ipv4, IPAddress ipv6, int port, bool manualMode) - { -#if UNITY _netManager = netManager; _ipv4 = ipv4; _ipv6 = ipv6; _port = port; _manualMode = manualMode; - - if (!_initialized) - UnityEngine.Application.focusChanged += Application_focusChanged; - + UnityEngine.Application.focusChanged += Application_focusChanged; _initialized = true; -#endif } public void Deinitialize() { -#if UNITY if (_initialized) UnityEngine.Application.focusChanged -= Application_focusChanged; - _initialized = false; -#endif } private void Application_focusChanged(bool focused) @@ -62,40 +37,36 @@ private void Application_focusChanged(bool focused) ApplicationFocused = focused; //If coming back into focus see if a reconnect is needed. if (focused) - TryReconnect(); - } - - - private void TryReconnect() - { - if (!_initialized) - return; - - /* If initialized and networkmanager - * went null then soemthing did not - * go right. It's possible the netmanager - * was destroyed without calling deinitialize. - * When this occurs deinitialize this instance. */ - if (_netManager == null) { - Deinitialize(); - return; - } - //Was intentionally disconnected at some point. - if (!_netManager.IsRunning) - return; - //Socket is still running. - if (_netManager.SocketActive(false) || _netManager.SocketActive(true)) - return; - - //Socket isn't running but should be. Try to start again. - if (!_netManager.Start(_ipv4, _ipv6, _port, _manualMode)) - { - NetDebug.WriteError($"[S] Cannot restore connection. Ipv4 {_ipv4}, Ipv6 {_ipv6}, Port {_port}, ManualMode {_manualMode}"); - _netManager.CloseSocket(false); + //try reconnect + if (!_initialized) + return; + + /* If initialized and networkmanager + * went null then soemthing did not + * go right. It's possible the netmanager + * was destroyed without calling deinitialize. + * When this occurs deinitialize this instance. */ + if (_netManager == null) + { + Deinitialize(); + return; + } + //Was intentionally disconnected at some point. + if (!_netManager.IsRunning) + return; + //Socket is still running. + if (_netManager.SocketActive(false) || _netManager.SocketActive(true)) + return; + + //Socket isn't running but should be. Try to start again. + if (!_netManager.Start(_ipv4, _ipv6, _port, _manualMode)) + { + NetDebug.WriteError($"[S] Cannot restore connection. Ipv4 {_ipv4}, Ipv6 {_ipv6}, Port {_port}, ManualMode {_manualMode}"); + _netManager.CloseSocket(false); + } } } - } - } +#endif From 2f9eefcbcec9d3f8243d2d8d5e757d2133aafcbe Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Sun, 2 Apr 2023 09:40:52 +0300 Subject: [PATCH 022/261] remove NetDataWriter from NetPacketProcessor to avoid multithreading "issues". Add Get to NetDataReader for structs and separate method for classes with constructor argument to avoid Activator.CreateInstance slow call --- LibSample/PacketProcessorExample.cs | 8 +++---- LiteNetLib/Utils/NetDataReader.cs | 11 ++++++++-- LiteNetLib/Utils/NetPacketProcessor.cs | 29 -------------------------- 3 files changed, 13 insertions(+), 35 deletions(-) diff --git a/LibSample/PacketProcessorExample.cs b/LibSample/PacketProcessorExample.cs index 44411a71..46ad36ee 100644 --- a/LibSample/PacketProcessorExample.cs +++ b/LibSample/PacketProcessorExample.cs @@ -37,6 +37,7 @@ class PacketProcessorExample : IExample private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(); private NetManager _client; private NetManager _server; + private NetDataWriter _writer = new NetDataWriter(); public void Run() { @@ -65,10 +66,9 @@ public void Run() new CustomStruct {X = 5, Y = -28}, new CustomStruct {X = -114, Y = 65535} }; - _netPacketProcessor.Send( - peer, - new ArgumentsForLogin {Password = "pass", SomeInt = 5, UserId = "someUser", SomeList = testList}, - DeliveryMethod.ReliableOrdered); + _writer.Reset(); + _netPacketProcessor.Write(_writer, new ArgumentsForLogin { Password = "pass", SomeInt = 5, UserId = "someUser", SomeList = testList }); + peer.Send(_writer, DeliveryMethod.ReliableOrdered); }; //start client/server diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 3703afd5..544bf55f 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -332,9 +332,16 @@ public ArraySegment GetRemainingBytesSegment() return segment; } - public T Get() where T : INetSerializable, new() + public T Get() where T : struct, INetSerializable { - var obj = new T(); + var obj = default(T); + obj.Deserialize(this); + return obj; + } + + public T Get(Func constructor) where T : INetSerializable + { + var obj = constructor(); obj.Deserialize(this); return obj; } diff --git a/LiteNetLib/Utils/NetPacketProcessor.cs b/LiteNetLib/Utils/NetPacketProcessor.cs index 007d5207..f3d1493e 100644 --- a/LiteNetLib/Utils/NetPacketProcessor.cs +++ b/LiteNetLib/Utils/NetPacketProcessor.cs @@ -26,7 +26,6 @@ static HashCache() protected delegate void SubscribeDelegate(NetDataReader reader, object userData); private readonly NetSerializer _netSerializer; private readonly Dictionary _callbacks = new Dictionary(); - private readonly NetDataWriter _netDataWriter = new NetDataWriter(); public NetPacketProcessor() { @@ -118,34 +117,6 @@ public void ReadPacket(NetDataReader reader) ReadPacket(reader, null); } - public void Send(NetPeer peer, T packet, DeliveryMethod options) where T : class, new() - { - _netDataWriter.Reset(); - Write(_netDataWriter, packet); - peer.Send(_netDataWriter, options); - } - - public void SendNetSerializable(NetPeer peer, ref T packet, DeliveryMethod options) where T : INetSerializable - { - _netDataWriter.Reset(); - WriteNetSerializable(_netDataWriter, ref packet); - peer.Send(_netDataWriter, options); - } - - public void Send(NetManager manager, T packet, DeliveryMethod options) where T : class, new() - { - _netDataWriter.Reset(); - Write(_netDataWriter, packet); - manager.SendToAll(_netDataWriter, options); - } - - public void SendNetSerializable(NetManager manager, ref T packet, DeliveryMethod options) where T : INetSerializable - { - _netDataWriter.Reset(); - WriteNetSerializable(_netDataWriter, ref packet); - manager.SendToAll(_netDataWriter, options); - } - public void Write(NetDataWriter writer, T packet) where T : class, new() { WriteHash(writer); From 50b01faa11e8fc57ba8f4b827cf034484f0871f6 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Sun, 2 Apr 2023 13:16:31 +0300 Subject: [PATCH 023/261] add more precise definition to T in NetDataReader.Get --- LiteNetLib/Utils/NetDataReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 544bf55f..b0dfbfd1 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -339,7 +339,7 @@ public T Get() where T : struct, INetSerializable return obj; } - public T Get(Func constructor) where T : INetSerializable + public T Get(Func constructor) where T : class, INetSerializable { var obj = constructor(); obj.Deserialize(this); From d53cf9ce30d60583199ba94b582d39b6de7806fe Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Sun, 2 Apr 2023 13:18:32 +0300 Subject: [PATCH 024/261] update docs --- docs/api/LiteNetLib.ConnectionRequest.html | 135 +- docs/api/LiteNetLib.ConnectionState.html | 53 +- docs/api/LiteNetLib.DeliveryMethod.html | 53 +- docs/api/LiteNetLib.DisconnectInfo.html | 71 +- docs/api/LiteNetLib.DisconnectReason.html | 53 +- ...LiteNetLib.EventBasedNatPunchListener.html | 81 +- .../api/LiteNetLib.EventBasedNetListener.html | 221 ++- .../LiteNetLib.IDeliveryEventListener.html | 59 +- docs/api/LiteNetLib.INatPunchListener.html | 65 +- docs/api/LiteNetLib.INetEventListener.html | 95 +- docs/api/LiteNetLib.INetLogger.html | 59 +- docs/api/LiteNetLib.INtpEventListener.html | 59 +- docs/api/LiteNetLib.IPv6Mode.html | 53 +- .../LiteNetLib.InvalidPacketException.html | 61 +- docs/api/LiteNetLib.Layers.Crc32cLayer.html | 73 +- .../LiteNetLib.Layers.PacketLayerBase.html | 81 +- .../LiteNetLib.Layers.XorEncryptLayer.html | 97 +- docs/api/LiteNetLib.Layers.html | 51 +- docs/api/LiteNetLib.LocalAddrType.html | 53 +- docs/api/LiteNetLib.NatAddressType.html | 53 +- docs/api/LiteNetLib.NatPunchModule.html | 97 +- docs/api/LiteNetLib.NetConstants.html | 125 +- docs/api/LiteNetLib.NetDebug.html | 59 +- docs/api/LiteNetLib.NetLogLevel.html | 53 +- ...teNetLib.NetManager.NetPeerEnumerator.html | 99 +- docs/api/LiteNetLib.NetManager.html | 623 ++++--- docs/api/LiteNetLib.NetPacketReader.html | 59 +- docs/api/LiteNetLib.NetPeer.html | 267 ++- docs/api/LiteNetLib.NetStatistics.html | 139 +- docs/api/LiteNetLib.NetUtils.html | 93 +- .../api/LiteNetLib.TooBigPacketException.html | 61 +- .../LiteNetLib.UnconnectedMessageType.html | 53 +- docs/api/LiteNetLib.Utils.CRC32C.html | 67 +- .../LiteNetLib.Utils.FastBitConverter.html | 59 +- .../LiteNetLib.Utils.INetSerializable.html | 65 +- ...LiteNetLib.Utils.InvalidTypeException.html | 61 +- docs/api/LiteNetLib.Utils.NetDataReader.html | 567 +++--- docs/api/LiteNetLib.Utils.NetDataWriter.html | 365 ++-- .../LiteNetLib.Utils.NetPacketProcessor.html | 247 ++- docs/api/LiteNetLib.Utils.NetSerializer.html | 121 +- .../LiteNetLib.Utils.NtpLeapIndicator.html | 53 +- docs/api/LiteNetLib.Utils.NtpMode.html | 53 +- docs/api/LiteNetLib.Utils.NtpPacket.html | 409 ++++- docs/api/LiteNetLib.Utils.ParseException.html | 61 +- docs/api/LiteNetLib.Utils.html | 55 +- docs/api/LiteNetLib.html | 57 +- docs/api/index.html | 41 +- docs/api/toc.html | 8 +- docs/articles/netserializerusage.html | 41 +- docs/articles/toc.html | 2 +- docs/index.html | 39 +- docs/manifest.json | 201 +-- docs/styles/docfx.css | 6 +- docs/styles/docfx.js | 6 +- docs/styles/docfx.vendor.css | 1519 +---------------- docs/styles/docfx.vendor.js | 39 +- docs/styles/search-worker.min.js | 52 + docs/toc.html | 2 +- docs/xrefmap.yml | 548 +++--- 59 files changed, 3338 insertions(+), 4660 deletions(-) create mode 100644 docs/styles/search-worker.min.js diff --git a/docs/api/LiteNetLib.ConnectionRequest.html b/docs/api/LiteNetLib.ConnectionRequest.html index 84481e72..a9aae3f9 100644 --- a/docs/api/LiteNetLib.ConnectionRequest.html +++ b/docs/api/LiteNetLib.ConnectionRequest.html @@ -1,23 +1,22 @@  - + - - Class ConnectionRequest - - - - + + Class ConnectionRequest + + + - - - - - - + + + + + + @@ -25,7 +24,7 @@
- + - +

Fields -

+ @@ -117,7 +116,7 @@

Fields

- + - +
- + diff --git a/docs/api/LiteNetLib.DeliveryMethod.html b/docs/api/LiteNetLib.DeliveryMethod.html index 7b0e130d..2c2ad372 100644 --- a/docs/api/LiteNetLib.DeliveryMethod.html +++ b/docs/api/LiteNetLib.DeliveryMethod.html @@ -1,23 +1,22 @@  - + - - Enum DeliveryMethod - - - - + + Enum DeliveryMethod + + + - - - - - - + + + + + + @@ -25,7 +24,7 @@
- + - +
@@ -278,7 +259,7 @@
In This Article
- + diff --git a/docs/index.html b/docs/index.html index 76f33c8d..ea6e98b2 100644 --- a/docs/index.html +++ b/docs/index.html @@ -10,7 +10,7 @@ - + @@ -66,7 +66,8 @@

LiteNetLib

Little Game Example on Unity

Features

    -
  • Lightweight
      +
    • Lightweight +
      • Small CPU and RAM usage
      • Small packet size overhead ( 1 byte for unreliable, 3 bytes for reliable packets )
      @@ -75,7 +76,8 @@

      Features

    • Peer to peer connections
    • Helper classes for sending and reading messages
    • Multiple data channels
    • -
    • Different send mechanics
        +
      • Different send mechanics +
        • Reliable with order
        • Reliable without order
        • Reliable sequenced (realiable only last packet)
        • @@ -94,7 +96,8 @@

          Features

        • Connection statisitcs (need DEBUG or STATS_ENABLED flag)
        • Multicasting (for discovering hosts in local network)
        • Unity support
        • -
        • Supported platforms:
            +
          • Supported platforms: +
            • Windows/Mac/Linux (.NET Framework, Mono, .NET Core)
            • Android (Unity)
            • iOS (Unity)
            • @@ -126,7 +129,8 @@

              Client

              } client.Stop(); -

              Server

              + +

              Server

              EventBasedNetListener listener = new EventBasedNetListener();
               NetManager server = new NetManager(listener);
               server.Start(9050 /* port */);
              @@ -153,75 +157,90 @@ 

              Client

              Thread.Sleep(15); } server.Stop(); -

              NetManager settings description

              + +

              NetManager settings description

              +
                +
              • UnconnectedMessagesEnabled
                  -
                • UnconnectedMessagesEnabled
                  • enable messages receiving without connection. (with SendUnconnectedMessage method)
                  • default value: false
                • -
                • NatPunchEnabled
                    +
                  • NatPunchEnabled +
                    • enable NAT punch messages
                    • default value: false
                  • -
                  • UpdateTime
                      +
                    • UpdateTime +
                      • library logic update (and send) period in milliseconds
                      • default value: 15 msec.
                    • -
                    • PingInterval
                        +
                      • PingInterval +
                        • Interval for latency detection and checking connection
                        • default value: 1000 msec.
                      • -
                      • DisconnectTimeout
                          -
                        • if client or server doesn't receive any packet from remote peer during this time then connection will be closed
                        • +
                        • DisconnectTimeout +
                            +
                          • if client or server doesn't receive any packet from remote peer during this time then connection will be closed
                          • (including library internal keepalive packets)
                          • default value: 5000 msec.
                        • -
                        • SimulatePacketLoss
                            +
                          • SimulatePacketLoss +
                            • simulate packet loss by dropping random amout of packets. (Works only in DEBUG mode)
                            • default value: false
                          • -
                          • SimulateLatency
                              +
                            • SimulateLatency +
                              • simulate latency by holding packets for random time. (Works only in DEBUG mode)
                              • default value: false
                            • -
                            • SimulationPacketLossChance
                                +
                              • SimulationPacketLossChance +
                                • chance of packet loss when simulation enabled. value in percents.
                                • default value: 10 (%)
                              • -
                              • SimulationMinLatency
                                  +
                                • SimulationMinLatency +
                                  • minimum simulated latency
                                  • default value: 30 msec
                                • -
                                • SimulationMaxLatency
                                    +
                                  • SimulationMaxLatency +
                                    • maximum simulated latency
                                    • default value: 100 msec
                                  • -
                                  • BroadcastEnabled
                                      +
                                    • BroadcastEnabled +
                                      • Allows receive Broadcast packets
                                      • default value: false
                                    • -
                                    • ReconnectDelay
                                        +
                                      • ReconnectDelay +
                                        • delay betwen connection attempts
                                        • default value: 500 msec
                                      • -
                                      • MaxConnectAttempts
                                          +
                                        • MaxConnectAttempts +
                                          • maximum connection attempts before client stops and call disconnect event.
                                          • default value: 10
                                        • -
                                        • UnsyncedEvents
                                            +
                                          • UnsyncedEvents +
                                            • Experimental feature. Events automatically will be called without PollEvents method from another thread
                                            • default value: false
                                            @@ -259,7 +278,7 @@
                                            In This Article
                                            - + diff --git a/docs/manifest.json b/docs/manifest.json index 4fd4a407..2a4a8307 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,6 +1,6 @@ { "homepages": [], - "source_base_path": "D:/Projects/LiteNetLib/docfx_project", + "source_base_path": "E:/Projects/LiteNetLib/docfx_project", "xrefmap": "xrefmap.yml", "files": [ { @@ -8,8 +8,7 @@ "source_relative_path": "api/LiteNetLib.ConnectionRequest.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.ConnectionRequest.html", - "hash": "zMxlUhJlmsU12GJkGyhzdiBRfB7nUuxut5zZDlkuodk=" + "relative_path": "api/LiteNetLib.ConnectionRequest.html" } }, "version": "" @@ -19,8 +18,7 @@ "source_relative_path": "api/LiteNetLib.ConnectionState.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.ConnectionState.html", - "hash": "gdVF/fgDhDBUuIzqGWsr22bjcPJxMrYS9r/1dnvnLvk=" + "relative_path": "api/LiteNetLib.ConnectionState.html" } }, "version": "" @@ -30,8 +28,7 @@ "source_relative_path": "api/LiteNetLib.DeliveryMethod.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.DeliveryMethod.html", - "hash": "n6pJJudeHOZsaaq74AcMsrofklamMM4SVWewfZSv99Q=" + "relative_path": "api/LiteNetLib.DeliveryMethod.html" } }, "version": "" @@ -41,8 +38,7 @@ "source_relative_path": "api/LiteNetLib.DisconnectInfo.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.DisconnectInfo.html", - "hash": "m5qcDmNGu3iuwlx00Bf00medEQAzG7GIPVnUel6m9oc=" + "relative_path": "api/LiteNetLib.DisconnectInfo.html" } }, "version": "" @@ -52,8 +48,7 @@ "source_relative_path": "api/LiteNetLib.DisconnectReason.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.DisconnectReason.html", - "hash": "2sYqK2fAs98BK4bzM4nanQQP1OXYqJOTBOJ3pfsrcOg=" + "relative_path": "api/LiteNetLib.DisconnectReason.html" } }, "version": "" @@ -63,8 +58,7 @@ "source_relative_path": "api/LiteNetLib.EventBasedNatPunchListener.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.EventBasedNatPunchListener.html", - "hash": "0wQ+bEy0dqNRCCZO0YttszIMYVrWiybLGuCtKlyODX4=" + "relative_path": "api/LiteNetLib.EventBasedNatPunchListener.html" } }, "version": "" @@ -74,8 +68,7 @@ "source_relative_path": "api/LiteNetLib.EventBasedNetListener.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.EventBasedNetListener.html", - "hash": "hP47sGCGGNXfXwMDO9teIhFcLiPbUV5fxeIeh/BFSg4=" + "relative_path": "api/LiteNetLib.EventBasedNetListener.html" } }, "version": "" @@ -85,8 +78,7 @@ "source_relative_path": "api/LiteNetLib.IDeliveryEventListener.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.IDeliveryEventListener.html", - "hash": "aJg1zlJN0FUxBLyiKV/zoE5QBfTWZ00rFvT+aylpU4Y=" + "relative_path": "api/LiteNetLib.IDeliveryEventListener.html" } }, "version": "" @@ -96,8 +88,7 @@ "source_relative_path": "api/LiteNetLib.INatPunchListener.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.INatPunchListener.html", - "hash": "z8Mevoa/+J/f17SdrqLrGHrFefM2vPPdUbxzueBwWcg=" + "relative_path": "api/LiteNetLib.INatPunchListener.html" } }, "version": "" @@ -107,8 +98,7 @@ "source_relative_path": "api/LiteNetLib.INetEventListener.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.INetEventListener.html", - "hash": "B3bO9ob6+fWCF3FSmfu7iBLf36PIkbkcyjo0ladkHhU=" + "relative_path": "api/LiteNetLib.INetEventListener.html" } }, "version": "" @@ -118,8 +108,7 @@ "source_relative_path": "api/LiteNetLib.INetLogger.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.INetLogger.html", - "hash": "goOaU4Wa7b24TT27/pO7CS57l/K/RFpMMaaFKkpUfZI=" + "relative_path": "api/LiteNetLib.INetLogger.html" } }, "version": "" @@ -129,8 +118,17 @@ "source_relative_path": "api/LiteNetLib.INtpEventListener.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.INtpEventListener.html", - "hash": "oCbORPOqMvy2SoUAzk/5w0feO4sisdJ6AFax3Boc7pg=" + "relative_path": "api/LiteNetLib.INtpEventListener.html" + } + }, + "version": "" + }, + { + "type": "ManagedReference", + "source_relative_path": "api/LiteNetLib.IPeerAddressChangedListener.yml", + "output": { + ".html": { + "relative_path": "api/LiteNetLib.IPeerAddressChangedListener.html" } }, "version": "" @@ -140,8 +138,7 @@ "source_relative_path": "api/LiteNetLib.IPv6Mode.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.IPv6Mode.html", - "hash": "kUKsqsZSToI8Uv9VnAlPLcQxCdO8Q/ra2zPQueAO2Ec=" + "relative_path": "api/LiteNetLib.IPv6Mode.html" } }, "version": "" @@ -151,8 +148,7 @@ "source_relative_path": "api/LiteNetLib.InvalidPacketException.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.InvalidPacketException.html", - "hash": "N/WSagdJS8+eM1Bnjw3wzsLOr3KJJFsJsQ38AAugxHk=" + "relative_path": "api/LiteNetLib.InvalidPacketException.html" } }, "version": "" @@ -162,8 +158,7 @@ "source_relative_path": "api/LiteNetLib.Layers.Crc32cLayer.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Layers.Crc32cLayer.html", - "hash": "Cb9S6Z1Wh6RpjzE3Kx63/6OBlJhVrqm1451Rwqa5tMA=" + "relative_path": "api/LiteNetLib.Layers.Crc32cLayer.html" } }, "version": "" @@ -173,8 +168,7 @@ "source_relative_path": "api/LiteNetLib.Layers.PacketLayerBase.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Layers.PacketLayerBase.html", - "hash": "nKHawTaxL7vuQkjq+xypimYnUA0LsOQKCQZ+TgJjjO4=" + "relative_path": "api/LiteNetLib.Layers.PacketLayerBase.html" } }, "version": "" @@ -184,8 +178,7 @@ "source_relative_path": "api/LiteNetLib.Layers.XorEncryptLayer.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Layers.XorEncryptLayer.html", - "hash": "Dnfu2e/XkhZULbN+MB46JR2gaRbcJyvAyAxuo59Uj3Y=" + "relative_path": "api/LiteNetLib.Layers.XorEncryptLayer.html" } }, "version": "" @@ -195,8 +188,7 @@ "source_relative_path": "api/LiteNetLib.Layers.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Layers.html", - "hash": "f69V68KebJEM6aZykqnoyTcT5Q0k1JBEX1vQ2nCPLRE=" + "relative_path": "api/LiteNetLib.Layers.html" } }, "version": "" @@ -206,8 +198,7 @@ "source_relative_path": "api/LiteNetLib.LocalAddrType.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.LocalAddrType.html", - "hash": "c5cJ7fKEr4oKd5YrvSzk5GOfk/RSc9JXUQkSNmsOBd8=" + "relative_path": "api/LiteNetLib.LocalAddrType.html" } }, "version": "" @@ -217,8 +208,7 @@ "source_relative_path": "api/LiteNetLib.NatAddressType.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NatAddressType.html", - "hash": "EsrDSASB7J4HE2TWm5wqo77GH6nBGb4shrniQU2fBYU=" + "relative_path": "api/LiteNetLib.NatAddressType.html" } }, "version": "" @@ -228,8 +218,7 @@ "source_relative_path": "api/LiteNetLib.NatPunchModule.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NatPunchModule.html", - "hash": "rodx7ieoK80M9HhrOdJ1c+ePIoOsynaiWPLWS3MB4fI=" + "relative_path": "api/LiteNetLib.NatPunchModule.html" } }, "version": "" @@ -239,8 +228,7 @@ "source_relative_path": "api/LiteNetLib.NetConstants.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetConstants.html", - "hash": "ElcUpIG6uijlYoNz4CnARMEbSK/cZixlhGGc2yrOYJc=" + "relative_path": "api/LiteNetLib.NetConstants.html" } }, "version": "" @@ -250,8 +238,7 @@ "source_relative_path": "api/LiteNetLib.NetDebug.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetDebug.html", - "hash": "SEt5cs+AZ2CTZxRyEkd4zDLsrg+jtQVJogplLrbZ3oE=" + "relative_path": "api/LiteNetLib.NetDebug.html" } }, "version": "" @@ -261,8 +248,7 @@ "source_relative_path": "api/LiteNetLib.NetLogLevel.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetLogLevel.html", - "hash": "WwSM1KQzTRd8pUwqmV9ow/sn7aG7JG8ejfxt0A9nA28=" + "relative_path": "api/LiteNetLib.NetLogLevel.html" } }, "version": "" @@ -272,8 +258,7 @@ "source_relative_path": "api/LiteNetLib.NetManager.NetPeerEnumerator.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetManager.NetPeerEnumerator.html", - "hash": "AyJOm//vC3CsELKLpMFu9pPWmotC/0w+rV/TFfHdqeg=" + "relative_path": "api/LiteNetLib.NetManager.NetPeerEnumerator.html" } }, "version": "" @@ -283,8 +268,7 @@ "source_relative_path": "api/LiteNetLib.NetManager.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetManager.html", - "hash": "RiCLfALNjEBgv/i8ZTJBp8PGqHZ16UgRCp2y9pV0/Dc=" + "relative_path": "api/LiteNetLib.NetManager.html" } }, "version": "" @@ -294,8 +278,7 @@ "source_relative_path": "api/LiteNetLib.NetPacketReader.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetPacketReader.html", - "hash": "kmLMnomdJ3poicTIfvo/D22KwV1C1MUP1UEbaK6gwt8=" + "relative_path": "api/LiteNetLib.NetPacketReader.html" } }, "version": "" @@ -305,8 +288,7 @@ "source_relative_path": "api/LiteNetLib.NetPeer.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetPeer.html", - "hash": "wZb/IyzmnwbrSZH/GSW0+7PaFlfdYwLr44ZPFIRGfnU=" + "relative_path": "api/LiteNetLib.NetPeer.html" } }, "version": "" @@ -316,8 +298,7 @@ "source_relative_path": "api/LiteNetLib.NetStatistics.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetStatistics.html", - "hash": "Aa4mY0evmbt8+k+JNroNcERRFrXmpSb1SVlfYbJGiho=" + "relative_path": "api/LiteNetLib.NetStatistics.html" } }, "version": "" @@ -327,8 +308,17 @@ "source_relative_path": "api/LiteNetLib.NetUtils.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.NetUtils.html", - "hash": "lph55jUogEnOW7I2kzaj9yUNrWIAMC8wqv41XWovUT4=" + "relative_path": "api/LiteNetLib.NetUtils.html" + } + }, + "version": "" + }, + { + "type": "ManagedReference", + "source_relative_path": "api/LiteNetLib.PooledPacket.yml", + "output": { + ".html": { + "relative_path": "api/LiteNetLib.PooledPacket.html" } }, "version": "" @@ -338,8 +328,7 @@ "source_relative_path": "api/LiteNetLib.TooBigPacketException.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.TooBigPacketException.html", - "hash": "hxrkGQlAlKS2XmVaydPNhBbJl0XcaYoxn97ct9c+B6U=" + "relative_path": "api/LiteNetLib.TooBigPacketException.html" } }, "version": "" @@ -349,8 +338,7 @@ "source_relative_path": "api/LiteNetLib.UnconnectedMessageType.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.UnconnectedMessageType.html", - "hash": "GMOzjiP5cFmF3urCHXP3ZZuNXuFl2urHnM7kr/NKoXs=" + "relative_path": "api/LiteNetLib.UnconnectedMessageType.html" } }, "version": "" @@ -360,8 +348,7 @@ "source_relative_path": "api/LiteNetLib.Utils.CRC32C.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.CRC32C.html", - "hash": "I/ZamzQmpdS8SyiZtaaaCRq/az7G8SgpLkwG8y3ibaU=" + "relative_path": "api/LiteNetLib.Utils.CRC32C.html" } }, "version": "" @@ -371,8 +358,7 @@ "source_relative_path": "api/LiteNetLib.Utils.FastBitConverter.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.FastBitConverter.html", - "hash": "rbe297MQKc0UMNbv/rULBtSBckSICSGiIzrkFDF8SwQ=" + "relative_path": "api/LiteNetLib.Utils.FastBitConverter.html" } }, "version": "" @@ -382,8 +368,7 @@ "source_relative_path": "api/LiteNetLib.Utils.INetSerializable.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.INetSerializable.html", - "hash": "qFbeAvnzuR+FJmIHHMPHAOmWqpJQ16q/cZwKAMGyqZQ=" + "relative_path": "api/LiteNetLib.Utils.INetSerializable.html" } }, "version": "" @@ -393,8 +378,7 @@ "source_relative_path": "api/LiteNetLib.Utils.InvalidTypeException.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.InvalidTypeException.html", - "hash": "6RHb4dC7camu1yadFu5SYJPrqzB6kUdXQFy+o2/96a8=" + "relative_path": "api/LiteNetLib.Utils.InvalidTypeException.html" } }, "version": "" @@ -404,8 +388,7 @@ "source_relative_path": "api/LiteNetLib.Utils.NetDataReader.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.NetDataReader.html", - "hash": "CysEryd9iSsCTacup2JXdN0k5bxG7UtTNWbXfd1p2bg=" + "relative_path": "api/LiteNetLib.Utils.NetDataReader.html" } }, "version": "" @@ -415,8 +398,7 @@ "source_relative_path": "api/LiteNetLib.Utils.NetDataWriter.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.NetDataWriter.html", - "hash": "JW//Tee90vuZAlVGJ9LTX/dsMHzXxDvB3YAK4H4ABsQ=" + "relative_path": "api/LiteNetLib.Utils.NetDataWriter.html" } }, "version": "" @@ -426,8 +408,7 @@ "source_relative_path": "api/LiteNetLib.Utils.NetPacketProcessor.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.NetPacketProcessor.html", - "hash": "f3ielxIp4ZRsFkskKZ/rYTwid6IOJugldWcQZ1FHJ8A=" + "relative_path": "api/LiteNetLib.Utils.NetPacketProcessor.html" } }, "version": "" @@ -437,8 +418,7 @@ "source_relative_path": "api/LiteNetLib.Utils.NetSerializer.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.NetSerializer.html", - "hash": "qeFaa5bWhc6UHXGNIpmNXGU5uoeN14fXmBjCX0XrWaQ=" + "relative_path": "api/LiteNetLib.Utils.NetSerializer.html" } }, "version": "" @@ -448,8 +428,7 @@ "source_relative_path": "api/LiteNetLib.Utils.NtpLeapIndicator.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.NtpLeapIndicator.html", - "hash": "Z17dwn9pYu9+y8ex+pU0wWf/c5Bi8BZ4Zig5jxWsaF0=" + "relative_path": "api/LiteNetLib.Utils.NtpLeapIndicator.html" } }, "version": "" @@ -459,8 +438,7 @@ "source_relative_path": "api/LiteNetLib.Utils.NtpMode.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.NtpMode.html", - "hash": "yYc3NVwBu+rJNdWHboVDUqux45UfrLMMAD0nV2blGTU=" + "relative_path": "api/LiteNetLib.Utils.NtpMode.html" } }, "version": "" @@ -470,8 +448,7 @@ "source_relative_path": "api/LiteNetLib.Utils.NtpPacket.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.NtpPacket.html", - "hash": "fABxHHmEIKkRxLnXUZLChiM1vbSgnbqiEQM8ngILVaI=" + "relative_path": "api/LiteNetLib.Utils.NtpPacket.html" } }, "version": "" @@ -481,8 +458,7 @@ "source_relative_path": "api/LiteNetLib.Utils.ParseException.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.ParseException.html", - "hash": "d0qFzD7iONlNXIaRJpQdJVyxe63Ks0OAf2PXGQefQTQ=" + "relative_path": "api/LiteNetLib.Utils.ParseException.html" } }, "version": "" @@ -492,8 +468,7 @@ "source_relative_path": "api/LiteNetLib.Utils.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.Utils.html", - "hash": "I1LqQWkOneuGRmE2wqDMvq5qxaXDSuxNflR8e0+WEgY=" + "relative_path": "api/LiteNetLib.Utils.html" } }, "version": "" @@ -503,8 +478,7 @@ "source_relative_path": "api/LiteNetLib.yml", "output": { ".html": { - "relative_path": "api/LiteNetLib.html", - "hash": "lGAtdWqWMdrz8g8HMhV/lcRDVenqtiZasz0jKsu+330=" + "relative_path": "api/LiteNetLib.html" } }, "version": "" @@ -514,8 +488,7 @@ "source_relative_path": "api/index.md", "output": { ".html": { - "relative_path": "api/index.html", - "hash": "6dXGzyRr+xdUl1QHkcWP7Sp0ROx7N7lm8kxNhHCyL9E=" + "relative_path": "api/index.html" } }, "version": "" @@ -525,8 +498,7 @@ "source_relative_path": "api/toc.yml", "output": { ".html": { - "relative_path": "api/toc.html", - "hash": "kQJ/3m7JXLpbOWFK1CDiaE/vSdWCn9P0hH7TxQup0SA=" + "relative_path": "api/toc.html" } }, "version": "" @@ -536,8 +508,7 @@ "source_relative_path": "articles/netserializerusage.md", "output": { ".html": { - "relative_path": "articles/netserializerusage.html", - "hash": "xPHK/lSc7BZ3+gG9qwy6RaKEbluZHa+ijHlAp54y5pM=" + "relative_path": "articles/netserializerusage.html" } }, "version": "" @@ -547,8 +518,7 @@ "source_relative_path": "articles/toc.yml", "output": { ".html": { - "relative_path": "articles/toc.html", - "hash": "y/FVN/Xj7B5+aOXYz3bJLeDw0TsHGJpaC/WGEw/Vpzk=" + "relative_path": "articles/toc.html" } }, "version": "" @@ -558,8 +528,7 @@ "source_relative_path": "index.md", "output": { ".html": { - "relative_path": "index.html", - "hash": "1m1kz/nYww3C1p/unSx037J1aTd/lx+b79+gzN+hLJc=" + "relative_path": "index.html" } }, "version": "" @@ -569,8 +538,7 @@ "source_relative_path": "toc.yml", "output": { ".html": { - "relative_path": "toc.html", - "hash": "k59T7WJQ29zQ5+PLa89yz49KKtfbhg+49Eev0+ZqVOw=" + "relative_path": "toc.html" } }, "version": "" diff --git a/docs/styles/docfx.js b/docs/styles/docfx.js index cfacda88..16bafe8c 100644 --- a/docs/styles/docfx.js +++ b/docs/styles/docfx.js @@ -51,7 +51,7 @@ $(function () { // Styling for tables in conceptual documents using Bootstrap. // See http://getbootstrap.com/css/#tables function renderTables() { - $('table').addClass('table table-bordered table-striped table-condensed').wrap('
                                            '); + $('table').addClass('table table-bordered table-condensed').wrap('
                                            '); } // Styling for alerts. diff --git a/docs/styles/docfx.vendor.min.css b/docs/styles/docfx.vendor.min.css new file mode 100644 index 00000000..b809553e --- /dev/null +++ b/docs/styles/docfx.vendor.min.css @@ -0,0 +1,25 @@ +html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*,*:before,*:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:Glyphicons Halflings;src:url(./glyphicons-halflings-regular-PIHUWCJO.eot);src:url(./glyphicons-halflings-regular-PIHUWCJO.eot?#iefix) format("embedded-opentype"),url(./glyphicons-halflings-regular-W4DYDFZM.woff2) format("woff2"),url(./glyphicons-halflings-regular-JOUF32XT.woff) format("woff"),url(./glyphicons-halflings-regular-ACNUA6UY.ttf) format("truetype"),url(./glyphicons-halflings-regular-QXYEM3FU.svg#glyphicons_halflingsregular) format("svg")}.glyphicon{position:relative;top:1px;display:inline-block;font-family:Glyphicons Halflings;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"*"}.glyphicon-plus:before{content:"+"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\a5"}.glyphicon-jpy:before{content:"\a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eeeeee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width: 768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover,a.text-primary:focus{color:#286090}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover,a.bg-primary:focus{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eeeeee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width: 768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eeeeee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:"\2014\a0"}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eeeeee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:""}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:"\a0\2014"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Courier New,monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px #00000040}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 768px){.container{width:750px}}@media (min-width: 992px){.container{width:970px}}@media (min-width: 1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.row-no-gutters{margin-right:0;margin-left:0}.row-no-gutters [class*=col-]{padding-right:0;padding-left:0}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width: 768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width: 992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width: 1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:transparent}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width: 767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \ ;line-height:normal}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px #00000013,0 0 8px #66afe999}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio: 0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month]{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \ ;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px #00000013,0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px #00000013,0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px #00000013,0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width: 768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width: 768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width: 768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width: 768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px #00000020}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;background-image:none;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;background-image:none;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;background-image:none;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;background-image:none;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;background-image:none;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \ ;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px #0000002d}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;inset:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid \ }.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width: 768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px #00000020}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child:not(:first-child){border-radius:0 0 4px 4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width: 768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width: 768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width: 768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width: 768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width: 768px){.navbar{border-radius:4px}}@media (min-width: 768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px #ffffff1a;-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width: 768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width: 480px) and (orientation: landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}@media (min-width: 768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width: 768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width: 768px){.navbar-static-top{border-radius:0}}.navbar-brand{float:left;height:50px;padding:15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width: 768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-right:15px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width: 768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width: 767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width: 768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin:8px -15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px #ffffff1a,0 1px #ffffff1a}@media (min-width: 768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width: 767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width: 768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-radius:4px 4px 0 0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width: 768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width: 768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width: 767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width: 767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width: 768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px #0000001a}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px #00000026;-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px #0000000d}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px #0000000d}.well blockquote{border-color:#ddd;border-color:#00000026}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;inset:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out,-o-transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px #00000080;outline:0}.modal-backdrop{position:fixed;inset:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px #00000080}.modal-sm{width:300px}}@media (min-width: 992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:12px;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px #0003}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover>.arrow{border-width:11px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:#00000040;border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:#00000040;border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:#00000040}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:#00000040}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0,0,0);transform:translateZ(0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:#0000;filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#80000000",endColorstr="#00000000",GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#00000000",endColorstr="#80000000",GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;outline:0;filter:alpha(opacity=90);opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \ ;background-color:#0000;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width: 768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width: 767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width: 767px){.visible-xs-block{display:block!important}}@media (max-width: 767px){.visible-xs-inline{display:inline!important}}@media (max-width: 767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-block{display:block!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-inline{display:inline!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-block{display:block!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-inline{display:inline!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width: 1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width: 1200px){.visible-lg-block{display:block!important}}@media (min-width: 1200px){.visible-lg-inline{display:inline!important}}@media (min-width: 1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width: 767px){.hidden-xs{display:none!important}}@media (min-width: 768px) and (max-width: 991px){.hidden-sm{display:none!important}}@media (min-width: 992px) and (max-width: 1199px){.hidden-md{display:none!important}}@media (min-width: 1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0} +/*! Bundled license information: + +@default/bootstrap/dist/css/bootstrap.css: + (*! + * Bootstrap v3.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *) + (*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css *) + (*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css *) + +@default/highlight.js/styles/github.css: + (*! + Theme: GitHub + Description: Light theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-light + Current colors taken from GitHub's CSS + *) +*/ +/*# sourceMappingURL=docfx.vendor.min.css.map */ diff --git a/docs/styles/docfx.vendor.min.css.map b/docs/styles/docfx.vendor.min.css.map new file mode 100644 index 00000000..31cf61ec --- /dev/null +++ b/docs/styles/docfx.vendor.min.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../../node_modules/@default/bootstrap/dist/css/bootstrap.css", "../../node_modules/@default/bootstrap/dist/css/less/normalize.less", "../../node_modules/@default/bootstrap/dist/css/less/print.less", "../../node_modules/@default/bootstrap/dist/css/less/glyphicons.less", "../../node_modules/@default/bootstrap/dist/css/less/scaffolding.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/vendor-prefixes.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/tab-focus.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/image.less", "../../node_modules/@default/bootstrap/dist/css/less/type.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/text-emphasis.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/background-variant.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/text-overflow.less", "../../node_modules/@default/bootstrap/dist/css/less/code.less", "../../node_modules/@default/bootstrap/dist/css/less/grid.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/grid.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/grid-framework.less", "../../node_modules/@default/bootstrap/dist/css/less/tables.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/table-row.less", "../../node_modules/@default/bootstrap/dist/css/less/forms.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/forms.less", "../../node_modules/@default/bootstrap/dist/css/less/buttons.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/buttons.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/opacity.less", "../../node_modules/@default/bootstrap/dist/css/less/component-animations.less", "../../node_modules/@default/bootstrap/dist/css/less/dropdowns.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/nav-divider.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/reset-filter.less", "../../node_modules/@default/bootstrap/dist/css/less/button-groups.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/border-radius.less", "../../node_modules/@default/bootstrap/dist/css/less/input-groups.less", "../../node_modules/@default/bootstrap/dist/css/less/navs.less", "../../node_modules/@default/bootstrap/dist/css/less/navbar.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/nav-vertical-align.less", "../../node_modules/@default/bootstrap/dist/css/less/utilities.less", "../../node_modules/@default/bootstrap/dist/css/less/breadcrumbs.less", "../../node_modules/@default/bootstrap/dist/css/less/pagination.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/pagination.less", "../../node_modules/@default/bootstrap/dist/css/less/pager.less", "../../node_modules/@default/bootstrap/dist/css/less/labels.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/labels.less", "../../node_modules/@default/bootstrap/dist/css/less/badges.less", "../../node_modules/@default/bootstrap/dist/css/less/jumbotron.less", "../../node_modules/@default/bootstrap/dist/css/less/thumbnails.less", "../../node_modules/@default/bootstrap/dist/css/less/alerts.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/alerts.less", "../../node_modules/@default/bootstrap/dist/css/less/progress-bars.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/gradients.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/progress-bar.less", "../../node_modules/@default/bootstrap/dist/css/less/media.less", "../../node_modules/@default/bootstrap/dist/css/less/list-group.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/list-group.less", "../../node_modules/@default/bootstrap/dist/css/less/panels.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/panels.less", "../../node_modules/@default/bootstrap/dist/css/less/responsive-embed.less", "../../node_modules/@default/bootstrap/dist/css/less/wells.less", "../../node_modules/@default/bootstrap/dist/css/less/close.less", "../../node_modules/@default/bootstrap/dist/css/less/modals.less", "../../node_modules/@default/bootstrap/dist/css/less/tooltip.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/reset-text.less", "../../node_modules/@default/bootstrap/dist/css/less/popovers.less", "../../node_modules/@default/bootstrap/dist/css/less/carousel.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/clearfix.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/center-block.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/hide-text.less", "../../node_modules/@default/bootstrap/dist/css/less/responsive-utilities.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/responsive-visibility.less", "../../node_modules/@default/highlight.js/styles/github.css"], + "sourcesContent": ["/*!\n * Bootstrap v3.4.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: none;\n text-decoration: underline;\n text-decoration: underline dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important;\n text-shadow: none !important;\n background: transparent !important;\n box-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: \"Glyphicons Halflings\";\n src: url(\"../fonts/glyphicons-halflings-regular.eot\");\n src: url(\"../fonts/glyphicons-halflings-regular.eot?#iefix\") format(\"embedded-opentype\"), url(\"../fonts/glyphicons-halflings-regular.woff2\") format(\"woff2\"), url(\"../fonts/glyphicons-halflings-regular.woff\") format(\"woff\"), url(\"../fonts/glyphicons-halflings-regular.ttf\") format(\"truetype\"), url(\"../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular\") format(\"svg\");\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: \"Glyphicons Halflings\";\n font-style: normal;\n font-weight: 400;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: 400;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: 700;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: \"\\2014 \\00A0\";\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: \"\";\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: \"\\00A0 \\2014\";\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n color: #333333;\n word-break: break-all;\n word-wrap: break-word;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n.row {\n margin-right: -15px;\n margin-left: -15px;\n}\n.row-no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n.row-no-gutters [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n.col-xs-1,\n.col-sm-1,\n.col-md-1,\n.col-lg-1,\n.col-xs-2,\n.col-sm-2,\n.col-md-2,\n.col-lg-2,\n.col-xs-3,\n.col-sm-3,\n.col-md-3,\n.col-lg-3,\n.col-xs-4,\n.col-sm-4,\n.col-md-4,\n.col-lg-4,\n.col-xs-5,\n.col-sm-5,\n.col-md-5,\n.col-lg-5,\n.col-xs-6,\n.col-sm-6,\n.col-md-6,\n.col-lg-6,\n.col-xs-7,\n.col-sm-7,\n.col-md-7,\n.col-lg-7,\n.col-xs-8,\n.col-sm-8,\n.col-md-8,\n.col-lg-8,\n.col-xs-9,\n.col-sm-9,\n.col-md-9,\n.col-lg-9,\n.col-xs-10,\n.col-sm-10,\n.col-md-10,\n.col-lg-10,\n.col-xs-11,\n.col-sm-11,\n.col-md-11,\n.col-lg-11,\n.col-xs-12,\n.col-sm-12,\n.col-md-12,\n.col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n.col-xs-1,\n.col-xs-2,\n.col-xs-3,\n.col-xs-4,\n.col-xs-5,\n.col-xs-6,\n.col-xs-7,\n.col-xs-8,\n.col-xs-9,\n.col-xs-10,\n.col-xs-11,\n.col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1,\n .col-sm-2,\n .col-sm-3,\n .col-sm-4,\n .col-sm-5,\n .col-sm-6,\n .col-sm-7,\n .col-sm-8,\n .col-sm-9,\n .col-sm-10,\n .col-sm-11,\n .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1,\n .col-md-2,\n .col-md-3,\n .col-md-4,\n .col-md-5,\n .col-md-6,\n .col-md-7,\n .col-md-8,\n .col-md-9,\n .col-md-10,\n .col-md-11,\n .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1,\n .col-lg-2,\n .col-lg-3,\n .col-lg-4,\n .col-lg-5,\n .col-lg-6,\n .col-lg-7,\n .col-lg-8,\n .col-lg-9,\n .col-lg-10,\n .col-lg-11,\n .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ntable col[class*=\"col-\"] {\n position: static;\n display: table-column;\n float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n display: table-cell;\n float: none;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n min-height: 0.01%;\n overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: 700;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n -webkit-appearance: none;\n appearance: none;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: 400;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-top: 4px \\9;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: 400;\n vertical-align: middle;\n cursor: pointer;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\n.form-control-static {\n min-height: 34px;\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-right: 0;\n padding-left: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n background-color: #f2dede;\n border-color: #a94442;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n padding-top: 7px;\n margin-top: 0;\n margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n padding-top: 7px;\n margin-bottom: 0;\n text-align: right;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n outline: 0;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n filter: alpha(opacity=65);\n opacity: 0.65;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n background-image: none;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n background-image: none;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n background-image: none;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n background-image: none;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n background-image: none;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n background-image: none;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n font-weight: 400;\n color: #337ab7;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n font-size: 14px;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: 400;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n color: #262626;\n text-decoration: none;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n background-color: #337ab7;\n outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n content: \"\";\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n right: 0;\n left: auto;\n }\n .navbar-right .dropdown-menu-left {\n right: auto;\n left: 0;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-right: 8px;\n padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-right: 12px;\n padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n display: table-cell;\n float: none;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-right: 0;\n padding-left: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: 400;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n cursor: default;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n padding-right: 15px;\n padding-left: 15px;\n overflow-x: visible;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-right: 0;\n padding-left: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-brand {\n float: left;\n height: 50px;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n padding: 9px 10px;\n margin-right: 15px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n padding: 10px 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n padding-top: 0;\n padding-bottom: 0;\n margin-right: 0;\n margin-left: 0;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-right: 15px;\n margin-left: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n color: #fff;\n background-color: #080808;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n padding: 0 5px;\n color: #ccc;\n content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n margin-left: -1px;\n line-height: 1.42857143;\n color: #337ab7;\n text-decoration: none;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-top-left-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n cursor: default;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n cursor: not-allowed;\n background-color: #fff;\n border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n text-align: center;\n list-style: none;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n cursor: not-allowed;\n background-color: #fff;\n}\n.label {\n display: inline;\n padding: 0.2em 0.6em 0.3em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n padding-right: 15px;\n padding-left: 15px;\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-right: 60px;\n padding-left: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-right: auto;\n margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n height: 20px;\n margin-bottom: 20px;\n overflow: hidden;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n padding-left: 0;\n margin-bottom: 20px;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n color: #777777;\n cursor: not-allowed;\n background-color: #eeeeee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n color: #555;\n text-decoration: none;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-right: 15px;\n padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n margin-bottom: 0;\n border: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n filter: alpha(opacity=20);\n opacity: 0.2;\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.modal-backdrop.in {\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: 400;\n line-height: 1.42857143;\n line-break: auto;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n font-size: 12px;\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.tooltip.in {\n filter: alpha(opacity=90);\n opacity: 0.9;\n}\n.tooltip.top {\n padding: 5px 0;\n margin-top: -3px;\n}\n.tooltip.right {\n padding: 0 5px;\n margin-left: 3px;\n}\n.tooltip.bottom {\n padding: 5px 0;\n margin-top: 3px;\n}\n.tooltip.left {\n padding: 0 5px;\n margin-left: -3px;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n right: 5px;\n bottom: 0;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: 400;\n line-height: 1.42857143;\n line-break: auto;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow:after {\n content: \"\";\n border-width: 10px;\n}\n.popover.top > .arrow {\n bottom: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n bottom: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-color: #fff;\n border-bottom-width: 0;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n border-left-width: 0;\n}\n.popover.right > .arrow:after {\n bottom: -10px;\n left: 1px;\n content: \" \";\n border-right-color: #fff;\n border-left-width: 0;\n}\n.popover.bottom > .arrow {\n top: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n.popover.bottom > .arrow:after {\n top: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n right: 1px;\n bottom: -10px;\n content: \" \";\n border-right-width: 0;\n border-left-color: #fff;\n}\n.popover-title {\n padding: 8px 14px;\n margin: 0;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n.carousel-inner > .item {\n position: relative;\n display: none;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 15%;\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control.right {\n right: 0;\n left: auto;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n filter: alpha(opacity=90);\n opacity: 0.9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n font-family: serif;\n line-height: 1;\n}\n.carousel-control .icon-prev:before {\n content: \"\\2039\";\n}\n.carousel-control .icon-next:before {\n content: \"\\203a\";\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n padding-left: 0;\n margin-left: -30%;\n text-align: center;\n list-style: none;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n border: 1px solid #fff;\n border-radius: 10px;\n}\n.carousel-indicators .active {\n width: 12px;\n height: 12px;\n margin: 0;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n right: 20%;\n left: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n display: table;\n content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-right: auto;\n margin-left: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */", "// stylelint-disable\n\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// 1. Remove the bottom border in Chrome 57- and Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n//\n\nabbr[title] {\n border-bottom: none; // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n", "// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important; // Black prints faster: h5bp.com/s\n text-shadow: none !important;\n background: transparent !important;\n box-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n}\n", "// stylelint-disable value-list-comma-newline-after, value-list-comma-space-after, indentation, declaration-colon-newline-after, font-family-no-missing-generic-family-keyword\n\n//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: \"Glyphicons Halflings\";\n src: url(\"@{icon-font-path}@{icon-font-name}.eot\");\n src: url(\"@{icon-font-path}@{icon-font-name}.eot?#iefix\") format(\"embedded-opentype\"),\n url(\"@{icon-font-path}@{icon-font-name}.woff2\") format(\"woff2\"),\n url(\"@{icon-font-path}@{icon-font-name}.woff\") format(\"woff\"),\n url(\"@{icon-font-path}@{icon-font-name}.ttf\") format(\"truetype\"),\n url(\"@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}\") format(\"svg\");\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: \"Glyphicons Halflings\";\n font-style: normal;\n font-weight: 400;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n", "//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// https://getbootstrap.com/docs/3.4/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: https://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n", "// stylelint-disable indentation, property-no-vendor-prefix, selector-no-vendor-prefix\n\n// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n word-wrap: break-word;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n", "// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n", "// stylelint-disable media-feature-name-no-vendor-prefix, media-feature-parentheses-space-inside, media-feature-name-no-unknown, indentation, at-rule-name-space-after\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n", "// stylelint-disable selector-list-comma-newline-after, selector-no-qualifying-type\n\n//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: 400;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n padding: .2em;\n background-color: @state-warning-bg;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: 700;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n}\n\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: \"\\2014 \\00A0\"; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: \"\"; }\n &:after {\n content: \"\\00A0 \\2014\"; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n", "// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n", "// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n", "// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n", "//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n color: @pre-color;\n word-break: break-all;\n word-wrap: break-word;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n", "//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n.row-no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n", "// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n padding-right: ceil((@gutter / 2));\n padding-left: floor((@gutter / 2));\n margin-right: auto;\n margin-left: auto;\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-right: floor((@gutter / -2));\n margin-left: ceil((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n", "// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-right: floor((@grid-gutter-width / 2));\n padding-left: ceil((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n", "// stylelint-disable selector-max-type, selector-max-compound-selectors, selector-no-qualifying-type\n\n//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n\n // Table cell sizing\n //\n // Reset default table behavior\n\n col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n display: table-column;\n float: none;\n }\n\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n display: table-cell;\n float: none;\n }\n }\n}\n\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\n\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n min-height: .01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n overflow-x: auto;\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * .75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n", "// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n", "// stylelint-disable selector-no-qualifying-type, property-no-vendor-prefix, media-feature-name-no-vendor-prefix\n\n//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: 700;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\ninput[type=\"search\"] {\n // Override content-box in Normalize (* isn't specific enough)\n .box-sizing(border-box);\n\n // Search inputs in iOS\n //\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n -webkit-appearance: none;\n appearance: none;\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n\n // Apply same disabled cursor tweak as for inputs\n // Some special care is needed because
                                          diff --git a/docs/manifest.json b/docs/manifest.json index 2a4a8307..a0c5141c 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,6 +1,6 @@ { "homepages": [], - "source_base_path": "E:/Projects/LiteNetLib/docfx_project", + "source_base_path": "e:/Projects/LiteNetLib/docfx_project", "xrefmap": "xrefmap.yml", "files": [ { @@ -463,6 +463,16 @@ }, "version": "" }, + { + "type": "ManagedReference", + "source_relative_path": "api/LiteNetLib.Utils.PreserveAttribute.yml", + "output": { + ".html": { + "relative_path": "api/LiteNetLib.Utils.PreserveAttribute.html" + } + }, + "version": "" + }, { "type": "ManagedReference", "source_relative_path": "api/LiteNetLib.Utils.yml", diff --git a/docs/xrefmap.yml b/docs/xrefmap.yml index 0212753f..c44a2db1 100644 --- a/docs/xrefmap.yml +++ b/docs/xrefmap.yml @@ -841,15 +841,15 @@ references: fullName.vb: LiteNetLib.Layers.Crc32cLayer.New nameWithType: Crc32cLayer.Crc32cLayer nameWithType.vb: Crc32cLayer.New -- uid: LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@,System.Int32@) - name: ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int, ref int) - href: api/LiteNetLib.Layers.Crc32cLayer.html#LiteNetLib_Layers_Crc32cLayer_ProcessInboundPacket_System_Net_IPEndPoint__System_Byte____System_Int32__System_Int32__ - commentId: M:LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@,System.Int32@) - name.vb: ProcessInboundPacket(IPEndPoint, Byte(), Integer, Integer) - fullName: LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket(ref System.Net.IPEndPoint, ref byte[], ref int, ref int) - fullName.vb: LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket(System.Net.IPEndPoint, Byte(), Integer, Integer) - nameWithType: Crc32cLayer.ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int, ref int) - nameWithType.vb: Crc32cLayer.ProcessInboundPacket(IPEndPoint, Byte(), Integer, Integer) +- uid: LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@) + name: ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int) + href: api/LiteNetLib.Layers.Crc32cLayer.html#LiteNetLib_Layers_Crc32cLayer_ProcessInboundPacket_System_Net_IPEndPoint__System_Byte____System_Int32__ + commentId: M:LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@) + name.vb: ProcessInboundPacket(IPEndPoint, Byte(), Integer) + fullName: LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket(ref System.Net.IPEndPoint, ref byte[], ref int) + fullName.vb: LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket(System.Net.IPEndPoint, Byte(), Integer) + nameWithType: Crc32cLayer.ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int) + nameWithType.vb: Crc32cLayer.ProcessInboundPacket(IPEndPoint, Byte(), Integer) - uid: LiteNetLib.Layers.Crc32cLayer.ProcessInboundPacket* name: ProcessInboundPacket href: api/LiteNetLib.Layers.Crc32cLayer.html#LiteNetLib_Layers_Crc32cLayer_ProcessInboundPacket_ @@ -904,15 +904,15 @@ references: commentId: F:LiteNetLib.Layers.PacketLayerBase.ExtraPacketSizeForLayer fullName: LiteNetLib.Layers.PacketLayerBase.ExtraPacketSizeForLayer nameWithType: PacketLayerBase.ExtraPacketSizeForLayer -- uid: LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@,System.Int32@) - name: ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int, ref int) - href: api/LiteNetLib.Layers.PacketLayerBase.html#LiteNetLib_Layers_PacketLayerBase_ProcessInboundPacket_System_Net_IPEndPoint__System_Byte____System_Int32__System_Int32__ - commentId: M:LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@,System.Int32@) - name.vb: ProcessInboundPacket(IPEndPoint, Byte(), Integer, Integer) - fullName: LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket(ref System.Net.IPEndPoint, ref byte[], ref int, ref int) - fullName.vb: LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket(System.Net.IPEndPoint, Byte(), Integer, Integer) - nameWithType: PacketLayerBase.ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int, ref int) - nameWithType.vb: PacketLayerBase.ProcessInboundPacket(IPEndPoint, Byte(), Integer, Integer) +- uid: LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@) + name: ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int) + href: api/LiteNetLib.Layers.PacketLayerBase.html#LiteNetLib_Layers_PacketLayerBase_ProcessInboundPacket_System_Net_IPEndPoint__System_Byte____System_Int32__ + commentId: M:LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@) + name.vb: ProcessInboundPacket(IPEndPoint, Byte(), Integer) + fullName: LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket(ref System.Net.IPEndPoint, ref byte[], ref int) + fullName.vb: LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket(System.Net.IPEndPoint, Byte(), Integer) + nameWithType: PacketLayerBase.ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int) + nameWithType.vb: PacketLayerBase.ProcessInboundPacket(IPEndPoint, Byte(), Integer) - uid: LiteNetLib.Layers.PacketLayerBase.ProcessInboundPacket* name: ProcessInboundPacket href: api/LiteNetLib.Layers.PacketLayerBase.html#LiteNetLib_Layers_PacketLayerBase_ProcessInboundPacket_ @@ -979,15 +979,15 @@ references: fullName.vb: LiteNetLib.Layers.XorEncryptLayer.New nameWithType: XorEncryptLayer.XorEncryptLayer nameWithType.vb: XorEncryptLayer.New -- uid: LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@,System.Int32@) - name: ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int, ref int) - href: api/LiteNetLib.Layers.XorEncryptLayer.html#LiteNetLib_Layers_XorEncryptLayer_ProcessInboundPacket_System_Net_IPEndPoint__System_Byte____System_Int32__System_Int32__ - commentId: M:LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@,System.Int32@) - name.vb: ProcessInboundPacket(IPEndPoint, Byte(), Integer, Integer) - fullName: LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket(ref System.Net.IPEndPoint, ref byte[], ref int, ref int) - fullName.vb: LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket(System.Net.IPEndPoint, Byte(), Integer, Integer) - nameWithType: XorEncryptLayer.ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int, ref int) - nameWithType.vb: XorEncryptLayer.ProcessInboundPacket(IPEndPoint, Byte(), Integer, Integer) +- uid: LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@) + name: ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int) + href: api/LiteNetLib.Layers.XorEncryptLayer.html#LiteNetLib_Layers_XorEncryptLayer_ProcessInboundPacket_System_Net_IPEndPoint__System_Byte____System_Int32__ + commentId: M:LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket(System.Net.IPEndPoint@,System.Byte[]@,System.Int32@) + name.vb: ProcessInboundPacket(IPEndPoint, Byte(), Integer) + fullName: LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket(ref System.Net.IPEndPoint, ref byte[], ref int) + fullName.vb: LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket(System.Net.IPEndPoint, Byte(), Integer) + nameWithType: XorEncryptLayer.ProcessInboundPacket(ref IPEndPoint, ref byte[], ref int) + nameWithType.vb: XorEncryptLayer.ProcessInboundPacket(IPEndPoint, Byte(), Integer) - uid: LiteNetLib.Layers.XorEncryptLayer.ProcessInboundPacket* name: ProcessInboundPacket href: api/LiteNetLib.Layers.XorEncryptLayer.html#LiteNetLib_Layers_XorEncryptLayer_ProcessInboundPacket_ @@ -1520,6 +1520,12 @@ references: commentId: F:LiteNetLib.NetManager.DisconnectTimeout fullName: LiteNetLib.NetManager.DisconnectTimeout nameWithType: NetManager.DisconnectTimeout +- uid: LiteNetLib.NetManager.DontRoute + name: DontRoute + href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_DontRoute + commentId: F:LiteNetLib.NetManager.DontRoute + fullName: LiteNetLib.NetManager.DontRoute + nameWithType: NetManager.DontRoute - uid: LiteNetLib.NetManager.EnableStatistics name: EnableStatistics href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_EnableStatistics @@ -1957,6 +1963,33 @@ references: fullName.vb: LiteNetLib.NetManager.SendToAll(Byte(), Integer, Integer, Byte, LiteNetLib.DeliveryMethod) nameWithType: NetManager.SendToAll(byte[], int, int, byte, DeliveryMethod) nameWithType.vb: NetManager.SendToAll(Byte(), Integer, Integer, Byte, DeliveryMethod) +- uid: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan{System.Byte},LiteNetLib.DeliveryMethod,LiteNetLib.NetPeer) + name: SendToAll(ReadOnlySpan, DeliveryMethod, NetPeer) + href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_SendToAll_System_ReadOnlySpan_System_Byte__LiteNetLib_DeliveryMethod_LiteNetLib_NetPeer_ + commentId: M:LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan{System.Byte},LiteNetLib.DeliveryMethod,LiteNetLib.NetPeer) + name.vb: SendToAll(ReadOnlySpan(Of Byte), DeliveryMethod, NetPeer) + fullName: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan, LiteNetLib.DeliveryMethod, LiteNetLib.NetPeer) + fullName.vb: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan(Of Byte), LiteNetLib.DeliveryMethod, LiteNetLib.NetPeer) + nameWithType: NetManager.SendToAll(ReadOnlySpan, DeliveryMethod, NetPeer) + nameWithType.vb: NetManager.SendToAll(ReadOnlySpan(Of Byte), DeliveryMethod, NetPeer) +- uid: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan{System.Byte},LiteNetLib.DeliveryMethod) + name: SendToAll(ReadOnlySpan, DeliveryMethod) + href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_SendToAll_System_ReadOnlySpan_System_Byte__LiteNetLib_DeliveryMethod_ + commentId: M:LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan{System.Byte},LiteNetLib.DeliveryMethod) + name.vb: SendToAll(ReadOnlySpan(Of Byte), DeliveryMethod) + fullName: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan, LiteNetLib.DeliveryMethod) + fullName.vb: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan(Of Byte), LiteNetLib.DeliveryMethod) + nameWithType: NetManager.SendToAll(ReadOnlySpan, DeliveryMethod) + nameWithType.vb: NetManager.SendToAll(ReadOnlySpan(Of Byte), DeliveryMethod) +- uid: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan{System.Byte},System.Byte,LiteNetLib.DeliveryMethod,LiteNetLib.NetPeer) + name: SendToAll(ReadOnlySpan, byte, DeliveryMethod, NetPeer) + href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_SendToAll_System_ReadOnlySpan_System_Byte__System_Byte_LiteNetLib_DeliveryMethod_LiteNetLib_NetPeer_ + commentId: M:LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan{System.Byte},System.Byte,LiteNetLib.DeliveryMethod,LiteNetLib.NetPeer) + name.vb: SendToAll(ReadOnlySpan(Of Byte), Byte, DeliveryMethod, NetPeer) + fullName: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan, byte, LiteNetLib.DeliveryMethod, LiteNetLib.NetPeer) + fullName.vb: LiteNetLib.NetManager.SendToAll(System.ReadOnlySpan(Of Byte), Byte, LiteNetLib.DeliveryMethod, LiteNetLib.NetPeer) + nameWithType: NetManager.SendToAll(ReadOnlySpan, byte, DeliveryMethod, NetPeer) + nameWithType.vb: NetManager.SendToAll(ReadOnlySpan(Of Byte), Byte, DeliveryMethod, NetPeer) - uid: LiteNetLib.NetManager.SendToAll* name: SendToAll href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_SendToAll_ @@ -2034,22 +2067,6 @@ references: commentId: F:LiteNetLib.NetManager.SimulationPacketLossChance fullName: LiteNetLib.NetManager.SimulationPacketLossChance nameWithType: NetManager.SimulationPacketLossChance -- uid: LiteNetLib.NetManager.SocketActive(System.Boolean) - name: SocketActive(bool) - href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_SocketActive_System_Boolean_ - commentId: M:LiteNetLib.NetManager.SocketActive(System.Boolean) - name.vb: SocketActive(Boolean) - fullName: LiteNetLib.NetManager.SocketActive(bool) - fullName.vb: LiteNetLib.NetManager.SocketActive(Boolean) - nameWithType: NetManager.SocketActive(bool) - nameWithType.vb: NetManager.SocketActive(Boolean) -- uid: LiteNetLib.NetManager.SocketActive* - name: SocketActive - href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_SocketActive_ - commentId: Overload:LiteNetLib.NetManager.SocketActive - isSpec: "True" - fullName: LiteNetLib.NetManager.SocketActive - nameWithType: NetManager.SocketActive - uid: LiteNetLib.NetManager.Start name: Start() href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_Start @@ -2336,19 +2353,19 @@ references: isSpec: "True" fullName: LiteNetLib.NetPeer.Disconnect nameWithType: NetPeer.Disconnect -- uid: LiteNetLib.NetPeer.EndPoint - name: EndPoint - href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_EndPoint - commentId: P:LiteNetLib.NetPeer.EndPoint - fullName: LiteNetLib.NetPeer.EndPoint - nameWithType: NetPeer.EndPoint -- uid: LiteNetLib.NetPeer.EndPoint* - name: EndPoint - href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_EndPoint_ - commentId: Overload:LiteNetLib.NetPeer.EndPoint - isSpec: "True" - fullName: LiteNetLib.NetPeer.EndPoint - nameWithType: NetPeer.EndPoint +- uid: LiteNetLib.NetPeer.GetHashCode + name: GetHashCode() + href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_GetHashCode + commentId: M:LiteNetLib.NetPeer.GetHashCode + fullName: LiteNetLib.NetPeer.GetHashCode() + nameWithType: NetPeer.GetHashCode() +- uid: LiteNetLib.NetPeer.GetHashCode* + name: GetHashCode + href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_GetHashCode_ + commentId: Overload:LiteNetLib.NetPeer.GetHashCode + isSpec: "True" + fullName: LiteNetLib.NetPeer.GetHashCode + nameWithType: NetPeer.GetHashCode - uid: LiteNetLib.NetPeer.GetMaxSinglePacketSize(LiteNetLib.DeliveryMethod) name: GetMaxSinglePacketSize(DeliveryMethod) href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_GetMaxSinglePacketSize_LiteNetLib_DeliveryMethod_ @@ -2603,6 +2620,19 @@ references: isSpec: "True" fullName: LiteNetLib.NetPeer.SendWithDeliveryEvent nameWithType: NetPeer.SendWithDeliveryEvent +- uid: LiteNetLib.NetPeer.Serialize + name: Serialize() + href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_Serialize + commentId: M:LiteNetLib.NetPeer.Serialize + fullName: LiteNetLib.NetPeer.Serialize() + nameWithType: NetPeer.Serialize() +- uid: LiteNetLib.NetPeer.Serialize* + name: Serialize + href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_Serialize_ + commentId: Overload:LiteNetLib.NetPeer.Serialize + isSpec: "True" + fullName: LiteNetLib.NetPeer.Serialize + nameWithType: NetPeer.Serialize - uid: LiteNetLib.NetPeer.Statistics name: Statistics href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_Statistics @@ -3203,6 +3233,141 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataReader.EndOfData nameWithType: NetDataReader.EndOfData +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Boolean@) + name: Get(out bool) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Boolean__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Boolean@) + name.vb: Get(Boolean) + fullName: LiteNetLib.Utils.NetDataReader.Get(out bool) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Boolean) + nameWithType: NetDataReader.Get(out bool) + nameWithType.vb: NetDataReader.Get(Boolean) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Byte@) + name: Get(out byte) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Byte__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Byte@) + name.vb: Get(Byte) + fullName: LiteNetLib.Utils.NetDataReader.Get(out byte) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Byte) + nameWithType: NetDataReader.Get(out byte) + nameWithType.vb: NetDataReader.Get(Byte) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Char@) + name: Get(out char) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Char__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Char@) + name.vb: Get(Char) + fullName: LiteNetLib.Utils.NetDataReader.Get(out char) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Char) + nameWithType: NetDataReader.Get(out char) + nameWithType.vb: NetDataReader.Get(Char) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Double@) + name: Get(out double) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Double__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Double@) + name.vb: Get(Double) + fullName: LiteNetLib.Utils.NetDataReader.Get(out double) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Double) + nameWithType: NetDataReader.Get(out double) + nameWithType.vb: NetDataReader.Get(Double) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Int16@) + name: Get(out short) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Int16__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Int16@) + name.vb: Get(Short) + fullName: LiteNetLib.Utils.NetDataReader.Get(out short) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Short) + nameWithType: NetDataReader.Get(out short) + nameWithType.vb: NetDataReader.Get(Short) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Int32@) + name: Get(out int) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Int32__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Int32@) + name.vb: Get(Integer) + fullName: LiteNetLib.Utils.NetDataReader.Get(out int) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Integer) + nameWithType: NetDataReader.Get(out int) + nameWithType.vb: NetDataReader.Get(Integer) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Int64@) + name: Get(out long) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Int64__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Int64@) + name.vb: Get(Long) + fullName: LiteNetLib.Utils.NetDataReader.Get(out long) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Long) + nameWithType: NetDataReader.Get(out long) + nameWithType.vb: NetDataReader.Get(Long) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Net.IPEndPoint@) + name: Get(out IPEndPoint) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Net_IPEndPoint__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Net.IPEndPoint@) + name.vb: Get(IPEndPoint) + fullName: LiteNetLib.Utils.NetDataReader.Get(out System.Net.IPEndPoint) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(System.Net.IPEndPoint) + nameWithType: NetDataReader.Get(out IPEndPoint) + nameWithType.vb: NetDataReader.Get(IPEndPoint) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.SByte@) + name: Get(out sbyte) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_SByte__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.SByte@) + name.vb: Get(SByte) + fullName: LiteNetLib.Utils.NetDataReader.Get(out sbyte) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(SByte) + nameWithType: NetDataReader.Get(out sbyte) + nameWithType.vb: NetDataReader.Get(SByte) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.Single@) + name: Get(out float) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_Single__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.Single@) + name.vb: Get(Single) + fullName: LiteNetLib.Utils.NetDataReader.Get(out float) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Single) + nameWithType: NetDataReader.Get(out float) + nameWithType.vb: NetDataReader.Get(Single) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.String@,System.Int32) + name: Get(out string, int) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_String__System_Int32_ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.String@,System.Int32) + name.vb: Get(String, Integer) + fullName: LiteNetLib.Utils.NetDataReader.Get(out string, int) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(String, Integer) + nameWithType: NetDataReader.Get(out string, int) + nameWithType.vb: NetDataReader.Get(String, Integer) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.String@) + name: Get(out string) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_String__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.String@) + name.vb: Get(String) + fullName: LiteNetLib.Utils.NetDataReader.Get(out string) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(String) + nameWithType: NetDataReader.Get(out string) + nameWithType.vb: NetDataReader.Get(String) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.UInt16@) + name: Get(out ushort) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_UInt16__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.UInt16@) + name.vb: Get(UShort) + fullName: LiteNetLib.Utils.NetDataReader.Get(out ushort) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(UShort) + nameWithType: NetDataReader.Get(out ushort) + nameWithType.vb: NetDataReader.Get(UShort) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.UInt32@) + name: Get(out uint) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_UInt32__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.UInt32@) + name.vb: Get(UInteger) + fullName: LiteNetLib.Utils.NetDataReader.Get(out uint) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(UInteger) + nameWithType: NetDataReader.Get(out uint) + nameWithType.vb: NetDataReader.Get(UInteger) +- uid: LiteNetLib.Utils.NetDataReader.Get(System.UInt64@) + name: Get(out ulong) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_System_UInt64__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get(System.UInt64@) + name.vb: Get(ULong) + fullName: LiteNetLib.Utils.NetDataReader.Get(out ulong) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(ULong) + nameWithType: NetDataReader.Get(out ulong) + nameWithType.vb: NetDataReader.Get(ULong) - uid: LiteNetLib.Utils.NetDataReader.Get* name: Get href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get_ @@ -3219,6 +3384,24 @@ references: fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Of T)() nameWithType: NetDataReader.Get() nameWithType.vb: NetDataReader.Get(Of T)() +- uid: LiteNetLib.Utils.NetDataReader.Get``1(``0@,System.Func{``0}) + name: Get(out T, Func) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get__1___0__System_Func___0__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get``1(``0@,System.Func{``0}) + name.vb: Get(Of T)(T, Func(Of T)) + fullName: LiteNetLib.Utils.NetDataReader.Get(out T, System.Func) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Of T)(T, System.Func(Of T)) + nameWithType: NetDataReader.Get(out T, Func) + nameWithType.vb: NetDataReader.Get(Of T)(T, Func(Of T)) +- uid: LiteNetLib.Utils.NetDataReader.Get``1(``0@) + name: Get(out T) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get__1___0__ + commentId: M:LiteNetLib.Utils.NetDataReader.Get``1(``0@) + name.vb: Get(Of T)(T) + fullName: LiteNetLib.Utils.NetDataReader.Get(out T) + fullName.vb: LiteNetLib.Utils.NetDataReader.Get(Of T)(T) + nameWithType: NetDataReader.Get(out T) + nameWithType.vb: NetDataReader.Get(Of T)(T) - uid: LiteNetLib.Utils.NetDataReader.Get``1(System.Func{``0}) name: Get(Func) href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get__1_System_Func___0__ @@ -3493,6 +3676,19 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataReader.GetRemainingBytesSegment nameWithType: NetDataReader.GetRemainingBytesSegment +- uid: LiteNetLib.Utils.NetDataReader.GetRemainingBytesSpan + name: GetRemainingBytesSpan() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetRemainingBytesSpan + commentId: M:LiteNetLib.Utils.NetDataReader.GetRemainingBytesSpan + fullName: LiteNetLib.Utils.NetDataReader.GetRemainingBytesSpan() + nameWithType: NetDataReader.GetRemainingBytesSpan() +- uid: LiteNetLib.Utils.NetDataReader.GetRemainingBytesSpan* + name: GetRemainingBytesSpan + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetRemainingBytesSpan_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.GetRemainingBytesSpan + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.GetRemainingBytesSpan + nameWithType: NetDataReader.GetRemainingBytesSpan - uid: LiteNetLib.Utils.NetDataReader.GetSByte name: GetSByte() href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetSByte @@ -5554,3 +5750,9 @@ references: fullName.vb: LiteNetLib.Utils.ParseException.New nameWithType: ParseException.ParseException nameWithType.vb: ParseException.New +- uid: LiteNetLib.Utils.PreserveAttribute + name: PreserveAttribute + href: api/LiteNetLib.Utils.PreserveAttribute.html + commentId: T:LiteNetLib.Utils.PreserveAttribute + fullName: LiteNetLib.Utils.PreserveAttribute + nameWithType: PreserveAttribute From 3fee090c4681b7674fc760e45f30b75dfc51e62d Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 20 Dec 2023 11:07:55 +0200 Subject: [PATCH 064/261] update unity example --- LiteNetLib/NetPeer.cs | 2 +- LiteNetLibSampleUnity/Assets/GameClient.cs | 22 +- LiteNetLibSampleUnity/Assets/GameServer.cs | 28 +- LiteNetLibSampleUnity/Assets/Resources.meta | 8 + .../Assets/Resources/BillingMode.json | 1 + .../Assets/Resources/BillingMode.json.meta | 7 + .../ProjectSettings/MemorySettings.asset | 35 + .../PackageManagerSettings.asset | 36 + .../ProjectSettings/PresetManager.asset | Bin 4104 -> 146 bytes .../ProjectSettings/ProjectSettings.asset | 606 +++-- .../ProjectSettings/ProjectVersion.txt | 3 +- .../ProjectSettings/VFXManager.asset | Bin 4148 -> 465 bytes .../VersionControlSettings.asset | 8 + .../UserSettings/EditorUserSettings.asset | 28 + .../Layouts/CurrentMaximizeLayout.dwlt | 1680 +++++++++++++ .../UserSettings/Layouts/default-2022.dwlt | 2095 +++++++++++++++++ .../UserSettings/Search.settings | 1 + 17 files changed, 4355 insertions(+), 205 deletions(-) create mode 100644 LiteNetLibSampleUnity/Assets/Resources.meta create mode 100644 LiteNetLibSampleUnity/Assets/Resources/BillingMode.json create mode 100644 LiteNetLibSampleUnity/Assets/Resources/BillingMode.json.meta create mode 100644 LiteNetLibSampleUnity/ProjectSettings/MemorySettings.asset create mode 100644 LiteNetLibSampleUnity/ProjectSettings/PackageManagerSettings.asset create mode 100644 LiteNetLibSampleUnity/ProjectSettings/VersionControlSettings.asset create mode 100644 LiteNetLibSampleUnity/UserSettings/EditorUserSettings.asset create mode 100644 LiteNetLibSampleUnity/UserSettings/Layouts/CurrentMaximizeLayout.dwlt create mode 100644 LiteNetLibSampleUnity/UserSettings/Layouts/default-2022.dwlt create mode 100644 LiteNetLibSampleUnity/UserSettings/Search.settings diff --git a/LiteNetLib/NetPeer.cs b/LiteNetLib/NetPeer.cs index 4d7a2b56..38c10999 100644 --- a/LiteNetLib/NetPeer.cs +++ b/LiteNetLib/NetPeer.cs @@ -257,7 +257,7 @@ internal void FinishEndPointChange(IPEndPoint newEndPoint) if (_connectionState != ConnectionState.EndPointChange) return; _connectionState = ConnectionState.Connected; - + Address = newEndPoint.Address; Port = newEndPoint.Port; diff --git a/LiteNetLibSampleUnity/Assets/GameClient.cs b/LiteNetLibSampleUnity/Assets/GameClient.cs index 18fff780..f6a120e9 100644 --- a/LiteNetLibSampleUnity/Assets/GameClient.cs +++ b/LiteNetLibSampleUnity/Assets/GameClient.cs @@ -14,7 +14,7 @@ public class GameClient : MonoBehaviour, INetEventListener private float _oldBallPosX; private float _lerpTime; - void Start() + private void Start() { _netClient = new NetManager(this); _netClient.UnconnectedMessagesEnabled = true; @@ -22,7 +22,7 @@ void Start() _netClient.Start(); } - void Update() + private void Update() { _netClient.PollEvents(); @@ -43,23 +43,23 @@ void Update() } } - void OnDestroy() + private void OnDestroy() { if (_netClient != null) _netClient.Stop(); } - public void OnPeerConnected(NetPeer peer) + void INetEventListener.OnPeerConnected(NetPeer peer) { - Debug.Log("[CLIENT] We connected to " + peer.EndPoint); + Debug.Log("[CLIENT] We connected to " + peer); } - public void OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode) + void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode) { Debug.Log("[CLIENT] We received error " + socketErrorCode); } - public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod) + void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) { _newBallPosX = reader.GetFloat(); @@ -73,7 +73,7 @@ public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMetho _lerpTime = 0f; } - public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) + void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) { if (messageType == UnconnectedMessageType.BasicMessage && _netClient.ConnectedPeersCount == 0 && reader.GetInt() == 1) { @@ -82,17 +82,17 @@ public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketRead } } - public void OnNetworkLatencyUpdate(NetPeer peer, int latency) + void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency) { } - public void OnConnectionRequest(ConnectionRequest request) + void INetEventListener.OnConnectionRequest(ConnectionRequest request) { } - public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) + void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) { Debug.Log("[CLIENT] We disconnected because " + disconnectInfo.Reason); } diff --git a/LiteNetLibSampleUnity/Assets/GameServer.cs b/LiteNetLibSampleUnity/Assets/GameServer.cs index 3e06ee57..0f5641ee 100644 --- a/LiteNetLibSampleUnity/Assets/GameServer.cs +++ b/LiteNetLibSampleUnity/Assets/GameServer.cs @@ -13,7 +13,7 @@ public class GameServer : MonoBehaviour, INetEventListener, INetLogger [SerializeField] private GameObject _serverBall; - void Start() + private void Start() { NetDebug.Logger = this; _dataWriter = new NetDataWriter(); @@ -23,12 +23,12 @@ void Start() _netServer.UpdateTime = 15; } - void Update() + private void Update() { _netServer.PollEvents(); } - void FixedUpdate() + private void FixedUpdate() { if (_ourPeer != null) { @@ -39,25 +39,25 @@ void FixedUpdate() } } - void OnDestroy() + private void OnDestroy() { NetDebug.Logger = null; if (_netServer != null) _netServer.Stop(); } - public void OnPeerConnected(NetPeer peer) + void INetEventListener.OnPeerConnected(NetPeer peer) { - Debug.Log("[SERVER] We have new peer " + peer.EndPoint); + Debug.Log("[SERVER] We have new peer " + peer); _ourPeer = peer; } - public void OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode) + void INetEventListener.OnNetworkError(IPEndPoint endPoint, SocketError socketErrorCode) { Debug.Log("[SERVER] error " + socketErrorCode); } - public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, + void INetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType) { if (messageType == UnconnectedMessageType.Broadcast) @@ -69,27 +69,27 @@ public void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketRead } } - public void OnNetworkLatencyUpdate(NetPeer peer, int latency) + void INetEventListener.OnNetworkLatencyUpdate(NetPeer peer, int latency) { } - public void OnConnectionRequest(ConnectionRequest request) + void INetEventListener.OnConnectionRequest(ConnectionRequest request) { request.AcceptIfKey("sample_app"); } - public void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) + void INetEventListener.OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo) { - Debug.Log("[SERVER] peer disconnected " + peer.EndPoint + ", info: " + disconnectInfo.Reason); + Debug.Log("[SERVER] peer disconnected " + peer + ", info: " + disconnectInfo.Reason); if (peer == _ourPeer) _ourPeer = null; } - public void OnNetworkReceive(NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod) + void INetEventListener.OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channelNumber, DeliveryMethod deliveryMethod) { } - public void WriteNet(NetLogLevel level, string str, params object[] args) + void INetLogger.WriteNet(NetLogLevel level, string str, params object[] args) { Debug.LogFormat(str, args); } diff --git a/LiteNetLibSampleUnity/Assets/Resources.meta b/LiteNetLibSampleUnity/Assets/Resources.meta new file mode 100644 index 00000000..0ec2b74a --- /dev/null +++ b/LiteNetLibSampleUnity/Assets/Resources.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0680635b8862cad41957568e3143c8c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/LiteNetLibSampleUnity/Assets/Resources/BillingMode.json b/LiteNetLibSampleUnity/Assets/Resources/BillingMode.json new file mode 100644 index 00000000..6f4bfb71 --- /dev/null +++ b/LiteNetLibSampleUnity/Assets/Resources/BillingMode.json @@ -0,0 +1 @@ +{"androidStore":"GooglePlay"} \ No newline at end of file diff --git a/LiteNetLibSampleUnity/Assets/Resources/BillingMode.json.meta b/LiteNetLibSampleUnity/Assets/Resources/BillingMode.json.meta new file mode 100644 index 00000000..19a785dd --- /dev/null +++ b/LiteNetLibSampleUnity/Assets/Resources/BillingMode.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 935f8151a9a85ee40bfcd6cbe0333137 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/LiteNetLibSampleUnity/ProjectSettings/MemorySettings.asset b/LiteNetLibSampleUnity/ProjectSettings/MemorySettings.asset new file mode 100644 index 00000000..5b5facec --- /dev/null +++ b/LiteNetLibSampleUnity/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: {} diff --git a/LiteNetLibSampleUnity/ProjectSettings/PackageManagerSettings.asset b/LiteNetLibSampleUnity/ProjectSettings/PackageManagerSettings.asset new file mode 100644 index 00000000..89ffc0e9 --- /dev/null +++ b/LiteNetLibSampleUnity/ProjectSettings/PackageManagerSettings.asset @@ -0,0 +1,36 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 53 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_EnablePreReleasePackages: 0 + m_AdvancedSettingsExpanded: 1 + m_ScopedRegistriesSettingsExpanded: 1 + m_SeeAllPackageVersions: 0 + m_DismissPreviewPackagesInUse: 0 + oneTimeWarningShown: 0 + m_Registries: + - m_Id: main + m_Name: + m_Url: https://packages.unity.com + m_Scopes: [] + m_IsDefault: 1 + m_Capabilities: 7 + m_ConfigSource: 0 + m_UserSelectedRegistryName: + m_UserAddingNewScopedRegistry: 0 + m_RegistryInfoDraft: + m_Modified: 0 + m_ErrorMessage: + m_UserModificationsInstanceId: -864 + m_OriginalInstanceId: -866 + m_LoadAssets: 0 diff --git a/LiteNetLibSampleUnity/ProjectSettings/PresetManager.asset b/LiteNetLibSampleUnity/ProjectSettings/PresetManager.asset index 3f07844c98aef18697edd42325705d4236b5c069..67a94daefe2e6bce3ec73546ad7cda94f702ad22 100644 GIT binary patch literal 146 zcmY$5boBL6Fw`^TQVnr*S5PcfR47SIw<^ucEU7e3(M!(H)iE+KG_>N<)zt;b8X8-e znOGW{nOiET8FB>_r52}__$KBhrl%HJaVaR|#``B_r6!knWTvFL* mG81z$t5Q?KQj3Z+^Yg3}jKHd0QqvMkb4noQ02No)asdFNTr08w literal 4104 zcmeH_yGlbr5Qb-S^?uhzL41K|EWCgOix3nqM6nM?J(_4DYL0@1u$@n!txZT}qgYwl zSzFlpC?5ZR_e6|uAnd@LnfZ2hcK1(2;!`369U?M_h#)dMlU>NnX66pE@)d@mQeczQ zjcp0TZ_~HjX`GHUjA{qUr$fS;k}x!s8N+*I4Uc!pZ${B+y9 zddZEaWeYp`F4ok^@`Tat1~upRBS!CPn{R%|W$v-}Z|OG3ei->3BIoliLxeEir-Aqg zCm)8>6kbXFTRMywrVanC!)U~d=YHJ}HoOz>&_9=2DeoV67u8_BQV%4`ZHpl`-MKpT zCE%x4+Vq0TrBAY&M`;J`vo00`4lGovcB$wE<-a`zuUg&p_Ks!W9&6{<+fNowTCz(y qOtcwZWGo6MZ~YnUiu*bRoB~b(r+`zyDc}@v3OEIv0#1Sdt-v=11*1d& diff --git a/LiteNetLibSampleUnity/ProjectSettings/ProjectSettings.asset b/LiteNetLibSampleUnity/ProjectSettings/ProjectSettings.asset index 85038959..29e4475c 100644 --- a/LiteNetLibSampleUnity/ProjectSettings/ProjectSettings.asset +++ b/LiteNetLibSampleUnity/ProjectSettings/ProjectSettings.asset @@ -3,9 +3,11 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 11 + serializedVersion: 26 productGUID: cf592f4b245d2b540a06dd6461f51365 AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 defaultScreenOrientation: 4 targetDevice: 2 useOnDemandResources: 0 @@ -14,7 +16,7 @@ PlayerSettings: productName: LiteNetLibSampleUnity defaultCursor: {fileID: 0} cursorHotspot: {x: 0, y: 0} - m_SplashScreenBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21176471, a: 1} + m_SplashScreenBackgroundColor: {r: 0.12156863, g: 0.12156863, b: 0.1254902, a: 1} m_ShowUnitySplashScreen: 1 m_ShowUnitySplashLogo: 1 m_SplashScreenOverlayOpacity: 1 @@ -38,8 +40,6 @@ PlayerSettings: width: 1 height: 1 m_SplashScreenLogos: [] - m_SplashScreenBackgroundLandscape: {fileID: 0} - m_SplashScreenBackgroundPortrait: {fileID: 0} m_VirtualRealitySplashScreen: {fileID: 0} m_HolographicTrackingLossScreen: {fileID: 0} defaultScreenWidth: 1024 @@ -48,37 +48,53 @@ PlayerSettings: defaultScreenHeightWeb: 600 m_StereoRenderingPath: 0 m_ActiveColorSpace: 0 + unsupportedMSAAFallback: 0 + m_SpriteBatchVertexThreshold: 300 m_MTRendering: 1 - m_MobileMTRendering: 0 + mipStripping: 0 + numberOfMipsStripped: 0 + numberOfMipsStrippedPerMipmapLimitGroup: {} m_StackTraceTypes: 010000000100000001000000010000000100000001000000 iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 - tizenShowActivityIndicatorOnLoading: -1 - iosAppInBackgroundBehavior: 0 - displayResolutionDialog: 1 - iosAllowHTTPDownload: 1 + iosUseCustomAppBackgroundBehavior: 0 allowedAutorotateToPortrait: 1 allowedAutorotateToPortraitUpsideDown: 1 allowedAutorotateToLandscapeRight: 1 allowedAutorotateToLandscapeLeft: 1 useOSAutorotation: 1 use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 disableDepthAndStencilBuffers: 0 - defaultIsFullScreen: 1 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidUseSwappy: 0 + androidBlitType: 0 + androidResizableWindow: 0 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 defaultIsNativeResolution: 1 + macRetinaSupport: 1 runInBackground: 0 captureSingleScreen: 0 muteOtherAudioSources: 0 Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 submitAnalytics: 1 usePlayerLog: 1 + dedicatedServerOptimizations: 0 bakeCollisionMeshes: 0 forceSingleInstance: 0 + useFlipModelSwapchain: 1 resizableWindow: 0 useMacAppStoreValidation: 0 macAppStoreCategory: public.app-category.games gpuSkinning: 0 - graphicsJobs: 0 xboxPIXTextureCapture: 0 xboxEnableAvatar: 0 xboxEnableKinect: 0 @@ -86,66 +102,75 @@ PlayerSettings: xboxEnableFitness: 0 visibleInBackground: 0 allowFullscreenSwitch: 1 - graphicsJobMode: 0 - macFullscreenMode: 2 - d3d9FullscreenMode: 1 - d3d11FullscreenMode: 1 + fullscreenMode: 1 xboxSpeechDB: 0 xboxEnableHeadOrientation: 0 xboxEnableGuest: 0 xboxEnablePIXSampling: 0 - n3dsDisableStereoscopicView: 0 - n3dsEnableSharedListOpt: 1 - n3dsEnableVSync: 0 - ignoreAlphaClear: 0 + metalFramebufferOnly: 0 xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 xboxOneMonoLoggingLevel: 0 xboxOneLoggingLevel: 1 - videoMemoryForVertexBuffers: 0 - psp2PowerMode: 0 - psp2AcquireBGM: 1 - wiiUTVResolution: 0 - wiiUGamePadMSAA: 1 - wiiUSupportsNunchuk: 0 - wiiUSupportsClassicController: 0 - wiiUSupportsBalanceBoard: 0 - wiiUSupportsMotionPlus: 0 - wiiUSupportsProController: 0 - wiiUAllowScreenCapture: 1 - wiiUControllerCount: 0 - m_SupportedAspectRatios: - 4:3: 1 - 5:4: 1 - 16:10: 1 - 16:9: 1 - Others: 1 + xboxOneDisableEsram: 0 + xboxOneEnableTypeOptimization: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 1048576 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + switchGpuScratchPoolGranularity: 2097152 + switchAllowGpuScratchShrinking: 0 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + switchNVNGraphicsFirmwareMemory: 32 + switchMaxWorkerMultiple: 8 + stadiaPresentMode: 0 + stadiaTargetFramerate: 0 + vulkanNumSwapchainBuffers: 3 + vulkanEnableSetSRGBWrite: 0 + vulkanEnablePreTransform: 0 + vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 + loadStoreDebugModeEnabled: 0 bundleVersion: 1.0 preloadedAssets: [] metroInputSource: 0 + wsaTransparentSwapchain: 0 m_HolographicPauseOnTrackingLoss: 1 xboxOneDisableKinectGpuReservation: 0 xboxOneEnable7thCore: 0 vrSettings: - cardboard: - depthFormat: 0 - enableTransitionView: 0 - daydream: - depthFormat: 0 - useSustainedPerformanceMode: 0 - hololens: - depthFormat: 1 - protectGraphicsMemory: 0 + enable360StereoCapture: 0 + isWsaHolographicRemotingEnabled: 0 + enableFrameTimingStats: 0 + enableOpenGLProfilerGPURecorders: 1 + allowHDRDisplaySupport: 0 useHDRDisplay: 0 + hdrBitDepth: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + resetResolutionOnWindowResize: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 applicationIdentifier: Android: com.RevenantX.LiteNetLibTest Standalone: unity.RevenantX.LiteNetLibSampleUnity Tizen: com.RevenantX.LiteNetLibTest - iOS: com.RevenantX.LiteNetLibTest + iPhone: com.RevenantX.LiteNetLibTest tvOS: com.RevenantX.LiteNetLibTest buildNumber: - iOS: 0 + Standalone: 0 + VisionOS: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 1 AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 16 + AndroidMinSdkVersion: 22 AndroidTargetSdkVersion: 0 AndroidPreferredInstallLocation: 1 aotOptions: @@ -158,35 +183,31 @@ PlayerSettings: APKExpansionFiles: 0 keepLoadedShadersAlive: 0 StripUnusedMeshComponents: 0 - VertexChannelCompressionMask: - serializedVersion: 2 - m_Bits: 238 + strictShaderVariantMatching: 0 + VertexChannelCompressionMask: 214 iPhoneSdkVersion: 988 - iOSTargetOSVersionString: 6.0 + iOSTargetOSVersionString: 12.0 tvOSSdkVersion: 0 tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 9.0 + tvOSTargetOSVersionString: 12.0 + VisionOSSdkVersion: 0 + VisionOSTargetOSVersionString: 1.0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 0 uIRequiresFullScreen: 1 uIStatusBarHidden: 1 uIExitOnSuspend: 0 uIStatusBarStyle: 0 - iPhoneSplashScreen: {fileID: 0} - iPhoneHighResSplashScreen: {fileID: 0} - iPhoneTallHighResSplashScreen: {fileID: 0} - iPhone47inSplashScreen: {fileID: 0} - iPhone55inPortraitSplashScreen: {fileID: 0} - iPhone55inLandscapeSplashScreen: {fileID: 0} - iPadPortraitSplashScreen: {fileID: 0} - iPadHighResPortraitSplashScreen: {fileID: 0} - iPadLandscapeSplashScreen: {fileID: 0} - iPadHighResLandscapeSplashScreen: {fileID: 0} appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] iOSLaunchScreenType: 0 iOSLaunchScreenPortrait: {fileID: 0} iOSLaunchScreenLandscape: {fileID: 0} @@ -204,31 +225,64 @@ PlayerSettings: iOSLaunchScreeniPadFillPct: 100 iOSLaunchScreeniPadSize: 100 iOSLaunchScreeniPadCustomXibPath: + iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: iOSDeviceRequirements: [] iOSURLSchemes: [] + macOSURLSchemes: [] iOSBackgroundModes: 0 iOSMetalForceHardShadows: 0 metalEditorSupport: 1 metalAPIValidation: 1 iOSRenderExtraFrameOnPause: 1 + iosCopyPluginsCodeInsteadOfSymlink: 0 appleDeveloperTeamID: iOSManualSigningProvisioningProfileID: tvOSManualSigningProvisioningProfileID: + VisionOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + VisionOSManualSigningProvisioningProfileType: 0 appleEnableAutomaticSigning: 0 - AndroidTargetDevice: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + shaderPrecisionModel: 0 + clonedFromGUID: 00000000000000000000000000000000 + templatePackageId: + templateDefaultScene: + useCustomMainManifest: 0 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 0 + useCustomLauncherGradleManifest: 0 + useCustomBaseGradleTemplate: 0 + useCustomGradlePropertiesTemplate: 0 + useCustomGradleSettingsTemplate: 0 + useCustomProguardFile: 0 + AndroidTargetArchitectures: 1 + AndroidTargetDevices: 0 AndroidSplashScreenScale: 0 androidSplashScreen: {fileID: 0} - AndroidKeystoreName: + AndroidKeystoreName: '{inproject}: ' AndroidKeyaliasName: + AndroidEnableArmv9SecurityFeatures: 0 + AndroidBuildApkPerCpuArchitecture: 0 AndroidTVCompatibility: 1 AndroidIsGame: 1 + AndroidEnableTango: 0 androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 m_AndroidBanners: - width: 320 height: 180 banner: {fileID: 0} androidGamepadSupportLevel: 0 - resolutionDialogBanner: {fileID: 0} + chromeosInputEmulation: 1 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 150 m_BuildTargetIcons: - m_BuildTarget: m_Icons: @@ -236,14 +290,159 @@ PlayerSettings: m_Icon: {fileID: 0} m_Width: 128 m_Height: 128 + m_Kind: 0 + m_BuildTargetPlatformIcons: + - m_BuildTarget: Android + m_Icons: + - m_Textures: [] + m_Width: 432 + m_Height: 432 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 324 + m_Height: 324 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 216 + m_Height: 216 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 162 + m_Height: 162 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 108 + m_Height: 108 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 81 + m_Height: 81 + m_Kind: 2 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 1 + m_SubKind: + - m_Textures: [] + m_Width: 192 + m_Height: 192 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 144 + m_Height: 144 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 96 + m_Height: 96 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 72 + m_Height: 72 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 48 + m_Height: 48 + m_Kind: 0 + m_SubKind: + - m_Textures: [] + m_Width: 36 + m_Height: 36 + m_Kind: 0 + m_SubKind: m_BuildTargetBatching: [] - m_BuildTargetGraphicsAPIs: [] + m_BuildTargetShaderSettings: [] + m_BuildTargetGraphicsJobs: + - m_BuildTarget: WindowsStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: MacStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: LinuxStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AndroidPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: iOSSupport + m_GraphicsJobs: 0 + - m_BuildTarget: PS4Player + m_GraphicsJobs: 0 + - m_BuildTarget: PS5Player + m_GraphicsJobs: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobs: 0 + - m_BuildTarget: GameCoreXboxOneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: GameCoreScarlettSupport + m_GraphicsJobs: 0 + - m_BuildTarget: Switch + m_GraphicsJobs: 0 + - m_BuildTarget: WebGLSupport + m_GraphicsJobs: 0 + - m_BuildTarget: MetroSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AppleTVSupport + m_GraphicsJobs: 0 + - m_BuildTarget: VisionOSPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: BJMSupport + m_GraphicsJobs: 0 + - m_BuildTarget: CloudRendering + m_GraphicsJobs: 0 + - m_BuildTarget: EmbeddedLinux + m_GraphicsJobs: 0 + - m_BuildTarget: QNX + m_GraphicsJobs: 0 + m_BuildTargetGraphicsJobMode: + - m_BuildTarget: PS4Player + m_GraphicsJobMode: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobMode: 0 + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: AndroidPlayer + m_APIs: 0b00000008000000 + m_Automatic: 0 m_BuildTargetVRSettings: - m_BuildTarget: Android m_Enabled: 0 m_Devices: - Oculus - - m_BuildTarget: Metro + - m_BuildTarget: Windows Store Apps m_Enabled: 0 m_Devices: [] - m_BuildTarget: N3DS @@ -287,35 +486,50 @@ PlayerSettings: - m_BuildTarget: XboxOne m_Enabled: 0 m_Devices: [] - - m_BuildTarget: iOS + - m_BuildTarget: iPhone m_Enabled: 0 m_Devices: [] - m_BuildTarget: tvOS m_Enabled: 0 m_Devices: [] + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 openGLRequireES31: 0 openGLRequireES31AEP: 0 - webPlayerTemplate: APPLICATION:Default + openGLRequireES32: 0 m_TemplateCustomTags: {} - wiiUTitleID: 0005000011000000 - wiiUGroupID: 00010000 - wiiUCommonSaveSize: 4096 - wiiUAccountSaveSize: 2048 - wiiUOlvAccessKey: 0 - wiiUTinCode: 0 - wiiUJoinGameId: 0 - wiiUJoinGameModeMask: 0000000000000000 - wiiUCommonBossSize: 0 - wiiUAccountBossSize: 0 - wiiUAddOnUniqueIDs: [] - wiiUMainThreadStackSize: 3072 - wiiULoaderThreadStackSize: 1024 - wiiUSystemHeapSize: 128 - wiiUTVStartupScreen: {fileID: 0} - wiiUGamePadStartupScreen: {fileID: 0} - wiiUDrcBufferDisabled: 0 - wiiUProfilerLibPath: + mobileMTRendering: + VisionOS: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: + - m_BuildTarget: Standalone + m_EncodingQuality: 1 + - m_BuildTarget: XboxOne + m_EncodingQuality: 1 + - m_BuildTarget: PS4 + m_EncodingQuality: 1 + - m_BuildTarget: GameCoreScarlett + m_EncodingQuality: 1 + - m_BuildTarget: GameCoreXboxOne + m_EncodingQuality: 1 + m_BuildTargetGroupHDRCubemapEncodingQuality: + - m_BuildTarget: Standalone + m_EncodingQuality: 2 + - m_BuildTarget: XboxOne + m_EncodingQuality: 2 + - m_BuildTarget: PS4 + m_EncodingQuality: 2 + - m_BuildTarget: GameCoreScarlett + m_EncodingQuality: 2 + - m_BuildTarget: GameCoreXboxOne + m_EncodingQuality: 2 + m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetGroupLoadStoreDebugModeSettings: [] + m_BuildTargetNormalMapEncoding: [] + m_BuildTargetDefaultTextureCompressionFormat: [] playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 actionOnDotNetUnhandledException: 1 enableInternalProfiler: 0 logObjCUncaughtExceptions: 1 @@ -323,13 +537,21 @@ PlayerSettings: cameraUsageDescription: locationUsageDescription: microphoneUsageDescription: + bluetoothUsageDescription: + macOSTargetOSVersion: 10.13.0 + switchNMETAOverride: switchNetLibKey: switchSocketMemoryPoolSize: 6144 switchSocketAllocatorPoolSize: 128 switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 switchUseCPUProfiler: 0 + switchEnableFileSystemTrace: 0 + switchUseGOLDLinker: 0 + switchLTOSetting: 0 switchApplicationID: 0x0005000C10000001 switchNSODependencies: + switchCompilerFlags: switchTitleNames_0: switchTitleNames_1: switchTitleNames_2: @@ -345,6 +567,7 @@ PlayerSettings: switchTitleNames_12: switchTitleNames_13: switchTitleNames_14: + switchTitleNames_15: switchPublisherNames_0: switchPublisherNames_1: switchPublisherNames_2: @@ -360,6 +583,7 @@ PlayerSettings: switchPublisherNames_12: switchPublisherNames_13: switchPublisherNames_14: + switchPublisherNames_15: switchIcons_0: {fileID: 0} switchIcons_1: {fileID: 0} switchIcons_2: {fileID: 0} @@ -375,6 +599,7 @@ PlayerSettings: switchIcons_12: {fileID: 0} switchIcons_13: {fileID: 0} switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} switchSmallIcons_0: {fileID: 0} switchSmallIcons_1: {fileID: 0} switchSmallIcons_2: {fileID: 0} @@ -390,6 +615,7 @@ PlayerSettings: switchSmallIcons_12: {fileID: 0} switchSmallIcons_13: {fileID: 0} switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} switchManualHTML: switchAccessibleURLs: switchLegalInformation: @@ -399,13 +625,12 @@ PlayerSettings: switchReleaseVersion: 0 switchDisplayVersion: 1.0.0 switchStartupUserAccount: 0 - switchTouchScreenUsage: 0 switchSupportedLanguagesMask: 0 switchLogoType: 0 switchApplicationErrorCodeCategory: switchUserAccountSaveDataSize: 0 switchUserAccountSaveDataJournalSize: 0 - switchAttribute: 0 + switchApplicationAttribute: 0 switchCardSpecSize: 4 switchCardSpecClock: 25 switchRatingsMask: 0 @@ -421,6 +646,7 @@ PlayerSettings: switchRatingsInt_9: 0 switchRatingsInt_10: 0 switchRatingsInt_11: 0 + switchRatingsInt_12: 0 switchLocalCommunicationIds_0: 0x0005000C10000001 switchLocalCommunicationIds_1: switchLocalCommunicationIds_2: @@ -431,7 +657,32 @@ PlayerSettings: switchLocalCommunicationIds_7: switchParentalControl: 0 switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 22 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 1 + switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchUseNewStyleFilepaths: 1 + switchUseLegacyFmodPriorities: 0 + switchUseMicroSleepForYield: 1 + switchEnableRamDiskSupport: 0 + switchMicroSleepForYieldTime: 25 + switchRamDiskSpaceSize: 12 ps4NPAgeRating: 12 ps4NPTitleSecret: ps4NPTrophyPackPath: @@ -450,12 +701,15 @@ PlayerSettings: ps4PronunciationSIGPath: ps4BackgroundImagePath: ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: ps4SaveDataImagePath: ps4SdkOverride: ps4BGMPath: ps4ShareFilePath: ps4ShareOverlayImagePath: ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: ps4NPtitleDatPath: ps4RemotePlayKeyAssignment: -1 ps4RemotePlayKeyMappingDir: @@ -468,17 +722,20 @@ PlayerSettings: ps4DownloadDataSize: 0 ps4GarlicHeapSize: 2048 ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ - ps4UseDebugIl2cppLibs: 0 ps4pnSessions: 1 ps4pnPresence: 1 ps4pnFriends: 1 ps4pnGameCustomData: 1 playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 restrictedAudioUsageRights: 0 ps4UseResolutionFallback: 0 ps4ReprojectionSupport: 0 ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 ps4SocialScreenEnabled: 0 ps4ScriptOptimizationLevel: 3 ps4Audio3dVirtualSpeakerCount: 14 @@ -495,63 +752,21 @@ PlayerSettings: ps4disableAutoHideSplash: 0 ps4videoRecordingFeaturesUsed: 0 ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4AllowPS5Detection: 0 + ps4GPU800MHz: 1 ps4attribEyeToEyeDistanceSettingVR: 0 ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 monoEnv: - psp2Splashimage: {fileID: 0} - psp2NPTrophyPackPath: - psp2NPSupportGBMorGJP: 0 - psp2NPAgeRating: 12 - psp2NPTitleDatPath: - psp2NPCommsID: - psp2NPCommunicationsID: - psp2NPCommsPassphrase: - psp2NPCommsSig: - psp2ParamSfxPath: - psp2ManualPath: - psp2LiveAreaGatePath: - psp2LiveAreaBackroundPath: - psp2LiveAreaPath: - psp2LiveAreaTrialPath: - psp2PatchChangeInfoPath: - psp2PatchOriginalPackage: - psp2PackagePassword: F69AzBlax3CF3EDNhm3soLBPh71Yexui - psp2KeystoneFile: - psp2MemoryExpansionMode: 0 - psp2DRMType: 0 - psp2StorageType: 0 - psp2MediaCapacity: 0 - psp2DLCConfigPath: - psp2ThumbnailPath: - psp2BackgroundPath: - psp2SoundPath: - psp2TrophyCommId: - psp2TrophyPackagePath: - psp2PackagedResourcesPath: - psp2SaveDataQuota: 10240 - psp2ParentalLevel: 1 - psp2ShortTitle: Not Set - psp2ContentID: IV0000-ABCD12345_00-0123456789ABCDEF - psp2Category: 0 - psp2MasterVersion: 01.00 - psp2AppVersion: 01.00 - psp2TVBootMode: 0 - psp2EnterButtonAssignment: 2 - psp2TVDisableEmu: 0 - psp2AllowTwitterDialog: 1 - psp2Upgradable: 0 - psp2HealthWarning: 0 - psp2UseLibLocation: 0 - psp2InfoBarOnStartup: 0 - psp2InfoBarColor: 0 - psp2UseDebugIl2cppLibs: 0 - psmSplashimage: {fileID: 0} splashScreenBackgroundSourceLandscape: {fileID: 0} splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 spritePackerPolicy: webGLMemorySize: 256 webGLExceptionSupport: 1 webGLNameFilesAsHashes: 0 + webGLShowDiagnostics: 0 webGLDataCaching: 0 webGLDebugSymbols: 0 webGLEmscriptenArgs: @@ -559,19 +774,53 @@ PlayerSettings: webGLTemplate: APPLICATION:Default webGLAnalyzeBuildSize: 0 webGLUseEmbeddedResources: 0 - webGLUseWasm: 0 webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLDecompressionFallback: 0 + webGLInitialMemorySize: 32 + webGLMaximumMemorySize: 2048 + webGLMemoryGrowthMode: 2 + webGLMemoryLinearGrowthStep: 16 + webGLMemoryGeometricGrowthStep: 0.2 + webGLMemoryGeometricGrowthCap: 96 + webGLPowerPreference: 2 scriptingDefineSymbols: - 7: UNITY + Android: UNITY + additionalCompilerArguments: {} platformArchitecture: {} scriptingBackend: Android: 0 - Metro: 2 Standalone: 0 WebGL: 1 WebPlayer: 0 + Windows Store Apps: 2 + il2cppCompilerConfiguration: {} + il2cppCodeGeneration: {} + managedStrippingLevel: + EmbeddedLinux: 1 + GameCoreScarlett: 1 + GameCoreXboxOne: 1 + Nintendo Switch: 1 + PS4: 1 + PS5: 1 + QNX: 1 + Stadia: 1 + VisionOS: 1 + WebGL: 1 + Windows Store Apps: 1 + XboxOne: 1 + iPhone: 1 + tvOS: 1 incrementalIl2cppBuild: {} + suppressCommonWarnings: 1 + allowUnsafeCode: 0 + useDeterministicCompilation: 1 additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 1 + gcWBarrierValidation: 0 apiCompatibilityLevelPerPlatform: {} m_RenderingPath: 1 m_MobileRenderingPath: 1 @@ -585,11 +834,12 @@ PlayerSettings: metroApplicationDescription: LiteNetLibSampleUnity wsaImages: {} metroTileShortName: - metroCommandLineArgsFile: metroTileShowName: 0 metroMediumTileShowName: 0 metroLargeTileShowName: 0 metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 metroDefaultTileSize: 1 metroTileForegroundText: 1 metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} @@ -597,35 +847,11 @@ PlayerSettings: a: 1} metroSplashScreenUseBackgroundColor: 1 platformCapabilities: {} + metroTargetDeviceFamilies: {} metroFTAName: metroFTAFileTypes: [] metroProtocolName: - metroCompilationOverrides: 1 - tizenProductDescription: - tizenProductURL: - tizenSigningProfileName: - tizenGPSPermissions: 0 - tizenMicrophonePermissions: 0 - tizenDeploymentTarget: - tizenDeploymentTargetType: -1 - tizenMinOSVersion: 1 - n3dsUseExtSaveData: 0 - n3dsCompressStaticMem: 1 - n3dsExtSaveDataNumber: 0x12345 - n3dsStackSize: 131072 - n3dsTargetPlatform: 2 - n3dsRegion: 7 - n3dsMediaSize: 0 - n3dsLogoStyle: 3 - n3dsTitle: GameName - n3dsProductCode: - n3dsApplicationId: 0xFF3FF - stvDeviceAddress: - stvProductDescription: - stvProductAuthor: - stvProductAuthorEmail: - stvProductLink: - stvProductCategory: 0 + vcxProjDefaultLanguage: XboxOneProductId: XboxOneUpdateKey: XboxOneSandboxId: @@ -635,6 +861,7 @@ PlayerSettings: XboxOneGameOsOverridePath: XboxOnePackagingOverridePath: XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 XboxOnePackageEncryption: 0 XboxOnePackageUpdateGranularity: 2 XboxOneDescription: @@ -643,16 +870,16 @@ PlayerSettings: XboxOneCapability: [] XboxOneGameRating: {} XboxOneIsContentPackage: 0 + XboxOneEnhancedXboxCompatibilityMode: 0 XboxOneEnableGPUVariability: 0 XboxOneSockets: {} XboxOneSplashScreen: {fileID: 0} XboxOneAllowedProductIds: [] XboxOnePersistentLocalStorageSize: 0 - xboxOneScriptCompiler: 0 - vrEditorSettings: - daydream: - daydreamIconForeground: {fileID: 0} - daydreamIconBackground: {fileID: 0} + XboxOneXTitleMemory: 8 + XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: + vrEditorSettings: {} cloudServicesEnabled: Analytics: 0 Build: 0 @@ -663,10 +890,33 @@ PlayerSettings: Purchasing: 0 UNet: 0 Unity_Ads: 0 - facebookSdkVersion: 7.9.1 - apiCompatibilityLevel: 2 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + hmiPlayerDataPath: + hmiForceSRGBBlit: 1 + embeddedLinuxEnableGamepadInput: 1 + hmiLogStartupTiming: 0 + hmiCpuConfiguration: + apiCompatibilityLevel: 6 + activeInputHandler: 0 + windowsGamepadBackendHint: 0 cloudProjectId: + framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] projectName: organizationId: cloudEnabled: 0 - enableNewInputSystem: 0 + legacyClampBlendShapeWeights: 1 + hmiLoadingImage: {fileID: 0} + platformRequiresReadableAssets: 0 + virtualTexturingSupportEnabled: 0 + insecureHttpOption: 0 diff --git a/LiteNetLibSampleUnity/ProjectSettings/ProjectVersion.txt b/LiteNetLibSampleUnity/ProjectSettings/ProjectVersion.txt index d848e35e..e4eac159 100644 --- a/LiteNetLibSampleUnity/ProjectSettings/ProjectVersion.txt +++ b/LiteNetLibSampleUnity/ProjectSettings/ProjectVersion.txt @@ -1 +1,2 @@ -m_EditorVersion: 2018.3.8f1 +m_EditorVersion: 2022.3.12f1 +m_EditorVersionWithRevision: 2022.3.12f1 (4fe6e059c7ef) diff --git a/LiteNetLibSampleUnity/ProjectSettings/VFXManager.asset b/LiteNetLibSampleUnity/ProjectSettings/VFXManager.asset index 85b0821bd6112e21b75662df3a1fbc9df5dcbce7..852348bcbdefc6ca66eed4c68cf7c2a6d22a0f22 100644 GIT binary patch literal 465 zcmZ{g&2ED*5QOhMg>y(xC4!*Rgj;?}8!4y}PNVizId}nAU@WspK~>+q#!)U+@o~Nx zYj&m|t7K37neR-Gt7kIlCInd#by8p-@LAT>_jAwpBgb{!fi8o`Ae@KG1-bK`Q~aJV z$qLYsLrDGkdj5h8Uj&D^VnrJf&&oT=g*Jeej2kQY&P4^gt-(K*ZyMFFyF3Ry=Aexp zO;glDy(!KR#^O)4!hQ^8U zJ2(b)#x)z(ndoytdpPGgdiH_uh-0#jNTT9o&hHT0%%l3gOW5K2PBYgTr6bHk__BackingField: 0 + k__BackingField: -1 + m_GroupName: + - rid: 7267259948770525185 + type: {class: GPUProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.GPUProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_ViewType: 0 + updateViewLive: 0 + m_CurrentFrameIndex: -1 + m_HierarchyOverruledThreadFromSelection: 0 + m_ProfilerViewFilteringOptions: 1 + m_FrameDataHierarchyView: + m_Serialized: 0 + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_MultiColumnHeaderState: + m_Columns: [] + m_VisibleColumns: + m_SortedColumns: + m_ThreadIndexInThreadNames: 0 + m_DetailedViewType: 0 + m_DetailedViewSpliterState: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: 0 + realSizes: [] + relativeSizes: [] + minSizes: [] + maxSizes: [] + lastTotalSize: 0 + splitSize: 0 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_DetailedObjectsView: + m_SelectedID: 0 + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_MultiColumnHeaderState: + m_Columns: [] + m_VisibleColumns: + m_SortedColumns: + m_VertSplit: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: 0 + realSizes: [] + relativeSizes: [] + minSizes: [] + maxSizes: [] + lastTotalSize: 0 + splitSize: 0 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_DetailedCallsView: + m_SelectedID: 0 + m_VertSplit: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: 0 + realSizes: [] + relativeSizes: [] + minSizes: [] + maxSizes: [] + lastTotalSize: 0 + splitSize: 0 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_CalleesTreeView: + m_ViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_ViewHeaderState: + m_Columns: [] + m_VisibleColumns: + m_SortedColumns: + m_CallersTreeView: + m_ViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_ViewHeaderState: + m_Columns: [] + m_VisibleColumns: + m_SortedColumns: + m_FullThreadName: Main Thread + m_ThreadName: Main Thread + k__BackingField: 0 + k__BackingField: -1 + m_GroupName: + - rid: 7267259948770525186 + type: {class: RenderingProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.RenderingProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525187 + type: {class: MemoryProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.MemoryProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_ViewSplit: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: -1 + realSizes: + - 0 + - 0 + relativeSizes: + - 0.7 + - 0.3 + minSizes: + - 450 + - 50 + maxSizes: + - 0 + - 0 + lastTotalSize: 0 + splitSize: 6 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + - rid: 7267259948770525188 + type: {class: AudioProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.AudioProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_ShowInactiveDSPChains: 0 + m_HighlightAudibleDSPChains: 1 + m_DSPGraphZoomFactor: 1 + m_DSPGraphHorizontalLayout: 0 + - rid: 7267259948770525189 + type: {class: VideoProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.VideoProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525190 + type: {class: PhysicsProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.PhysicsProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525191 + type: {class: Physics2DProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.Physics2DProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525192 + type: {class: UIProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.UIProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525193 + type: {class: UIDetailsProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.UIDetailsProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525194 + type: {class: GlobalIlluminationProfilerModule, ns: UnityEditorInternal.Profiling, + asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.GlobalIlluminationProfilerModule, + UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525195 + type: {class: VirtualTexturingProfilerModule, ns: UnityEditorInternal.Profiling, + asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.VirtualTexturingProfilerModule, + UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_VTProfilerView: + rid: 7267259948770525198 + - rid: 7267259948770525196 + type: {class: FileIOProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.FileIOProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525197 + type: {class: AssetLoadingProfilerModule, ns: UnityEditorInternal.Profiling, + asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.AssetLoadingProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525198 + type: {class: VirtualTexturingProfilerView, ns: UnityEditor, asm: UnityEditor.CoreModule} + data: + m_SortAscending: 0 + m_SortedColumn: -1 +--- !u!114 &8 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 9} + - {fileID: 11} + m_Position: + serializedVersion: 2 + x: 1493 + y: 0 + width: 376 + height: 1299 + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 8096, y: 16192} + vertical: 1 + controlID: 338 +--- !u!114 &9 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: SceneHierarchyWindow + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 376 + height: 624 + m_MinSize: {x: 202, y: 221} + m_MaxSize: {x: 4002, y: 4021} + m_ActualView: {fileID: 10} + m_Panes: + - {fileID: 10} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &10 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Hierarchy + m_Image: {fileID: 7966133145522015247, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1493 + y: 73 + width: 374 + height: 603 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_SceneHierarchy: + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: 1638ffff1a3cffff + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 9} + m_SearchString: + m_ExpandedScenes: [] + m_CurrenRootInstanceID: 0 + m_LockTracker: + m_IsLocked: 0 + m_CurrentSortingName: TransformSorting + m_WindowGUID: 5744dfe58afd7b349b2bf692722dc4ff +--- !u!114 &11 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: ProjectBrowser + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 624 + width: 376 + height: 675 + m_MinSize: {x: 232, y: 271} + m_MaxSize: {x: 10002, y: 10021} + m_ActualView: {fileID: 12} + m_Panes: + - {fileID: 12} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &12 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 230, y: 250} + m_MaxSize: {x: 10000, y: 10000} + m_TitleContent: + m_Text: Project + m_Image: {fileID: -5467254957812901981, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1493 + y: 697 + width: 374 + height: 654 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_SearchFilter: + m_NameFilter: + m_ClassNames: [] + m_AssetLabels: [] + m_AssetBundleNames: [] + m_ReferencingInstanceIDs: + m_SceneHandles: + m_ShowAllHits: 0 + m_SkipHidden: 0 + m_SearchArea: 1 + m_Folders: + - Assets + m_Globs: [] + m_OriginalText: + m_ImportLogFlags: 0 + m_FilterByTypeIntersection: 0 + m_ViewMode: 0 + m_StartGridSize: 16 + m_LastFolders: [] + m_LastFoldersGridSize: -1 + m_LastProjectPath: E:\Projects\LiteNetLib\LiteNetLibSampleUnity + m_LockTracker: + m_IsLocked: 0 + m_FolderTreeState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 0e800000 + m_LastClickedID: 32782 + m_ExpandedIDs: ffffffffd0400000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_AssetTreeState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 887a0000 + m_LastClickedID: 31368 + m_ExpandedIDs: ffffffffd0400000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 11} + m_SearchString: + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_ListAreaState: + m_SelectedInstanceIDs: 887a0000 + m_LastClickedInstanceID: 31368 + m_HadKeyboardFocusLastEvent: 0 + m_ExpandedInstanceIDs: c6230000d0640000967900008e6d00007674000022740000a66f000000000000687100009c230000f4b70000288000007a5f00008e7d0000ecbc0000346d0000f09c0000c297000026850000f06c0000de7d0000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 11} + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_NewAssetIndexInList: -1 + m_ScrollPosition: {x: 0, y: 0} + m_GridSize: 16 + m_SkipHiddenPackages: 0 + m_DirectoriesAreaWidth: 178 +--- !u!114 &13 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: InspectorWindow + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 1869 + y: 0 + width: 691 + height: 1299 + m_MinSize: {x: 275, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_ActualView: {fileID: 14} + m_Panes: + - {fileID: 14} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &14 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 275, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Inspector + m_Image: {fileID: -2667387946076563598, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1869 + y: 73 + width: 690 + height: 1278 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_ObjectsLockedBeforeSerialization: [] + m_InstanceIDsLockedBeforeSerialization: + m_PreviewResizer: + m_CachedPref: 526 + m_ControlHash: -371814159 + m_PrefName: Preview_InspectorPreview + m_LastInspectedObjectInstanceID: 31368 + m_LastVerticalScrollValue: 0 + m_GlobalObjectId: + m_InspectorMode: 0 + m_LockTracker: + m_IsLocked: 0 + m_PreviewWindow: {fileID: 0} diff --git a/LiteNetLibSampleUnity/UserSettings/Layouts/default-2022.dwlt b/LiteNetLibSampleUnity/UserSettings/Layouts/default-2022.dwlt new file mode 100644 index 00000000..bea9ed68 --- /dev/null +++ b/LiteNetLibSampleUnity/UserSettings/Layouts/default-2022.dwlt @@ -0,0 +1,2095 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12004, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_PixelRect: + serializedVersion: 2 + x: 0 + y: 43 + width: 2560 + height: 1349 + m_ShowMode: 4 + m_Title: Profiler + m_RootView: {fileID: 2} + m_MinSize: {x: 875, y: 421} + m_MaxSize: {x: 10000, y: 10000} + m_Maximized: 1 +--- !u!114 &2 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12008, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 3} + - {fileID: 5} + - {fileID: 4} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 2560 + height: 1349 + m_MinSize: {x: 875, y: 300} + m_MaxSize: {x: 10000, y: 10000} + m_UseTopView: 1 + m_TopViewHeight: 30 + m_UseBottomView: 1 + m_BottomViewHeight: 20 +--- !u!114 &3 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12011, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 2560 + height: 30 + m_MinSize: {x: 0, y: 0} + m_MaxSize: {x: 0, y: 0} + m_LastLoadedLayoutName: +--- !u!114 &4 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12042, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 1329 + width: 2560 + height: 20 + m_MinSize: {x: 0, y: 0} + m_MaxSize: {x: 0, y: 0} +--- !u!114 &5 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 6} + - {fileID: 9} + - {fileID: 12} + m_Position: + serializedVersion: 2 + x: 0 + y: 30 + width: 2560 + height: 1299 + m_MinSize: {x: 300, y: 100} + m_MaxSize: {x: 24288, y: 16192} + vertical: 0 + controlID: 684 +--- !u!114 &6 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 7} + - {fileID: 8} + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1493 + height: 1299 + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 8096, y: 16192} + vertical: 1 + controlID: 690 +--- !u!114 &7 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: GameView + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 1493 + height: 733 + m_MinSize: {x: 201, y: 221} + m_MaxSize: {x: 4001, y: 4021} + m_ActualView: {fileID: 13} + m_Panes: + - {fileID: 14} + - {fileID: 13} + m_Selected: 1 + m_LastSelected: 0 +--- !u!114 &8 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: ProfilerWindow + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 733 + width: 1493 + height: 566 + m_MinSize: {x: 901, y: 237} + m_MaxSize: {x: 4001, y: 4021} + m_ActualView: {fileID: 15} + m_Panes: + - {fileID: 15} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &9 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12010, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_Children: + - {fileID: 10} + - {fileID: 11} + m_Position: + serializedVersion: 2 + x: 1493 + y: 0 + width: 376 + height: 1299 + m_MinSize: {x: 100, y: 100} + m_MaxSize: {x: 8096, y: 16192} + vertical: 1 + controlID: 635 +--- !u!114 &10 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: SceneHierarchyWindow + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 0 + width: 376 + height: 624 + m_MinSize: {x: 202, y: 221} + m_MaxSize: {x: 4002, y: 4021} + m_ActualView: {fileID: 16} + m_Panes: + - {fileID: 16} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &11 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: ProjectBrowser + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 0 + y: 624 + width: 376 + height: 675 + m_MinSize: {x: 232, y: 271} + m_MaxSize: {x: 10002, y: 10021} + m_ActualView: {fileID: 17} + m_Panes: + - {fileID: 17} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &12 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12006, guid: 0000000000000000e000000000000000, type: 0} + m_Name: InspectorWindow + m_EditorClassIdentifier: + m_Children: [] + m_Position: + serializedVersion: 2 + x: 1869 + y: 0 + width: 691 + height: 1299 + m_MinSize: {x: 276, y: 71} + m_MaxSize: {x: 4001, y: 4021} + m_ActualView: {fileID: 18} + m_Panes: + - {fileID: 18} + m_Selected: 0 + m_LastSelected: 0 +--- !u!114 &13 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12015, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Game + m_Image: {fileID: -6423792434712278376, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 0 + y: 73 + width: 1492 + height: 712 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_SerializedViewNames: [] + m_SerializedViewValues: [] + m_PlayModeViewName: GameView + m_ShowGizmos: 0 + m_TargetDisplay: 0 + m_ClearColor: {r: 0, g: 0, b: 0, a: 0} + m_TargetSize: {x: 1228, y: 691} + m_TextureFilterMode: 0 + m_TextureHideFlags: 61 + m_RenderIMGUI: 1 + m_EnterPlayModeBehavior: 0 + m_UseMipMap: 0 + m_VSyncEnabled: 1 + m_Gizmos: 0 + m_Stats: 0 + m_SelectedSizes: 0100000000000000000000000e000000000000000000000000000000000000000000000000000000 + m_ZoomArea: + m_HRangeLocked: 0 + m_VRangeLocked: 0 + hZoomLockedByDefault: 0 + vZoomLockedByDefault: 0 + m_HBaseRangeMin: -614 + m_HBaseRangeMax: 614 + m_VBaseRangeMin: -345.5 + m_VBaseRangeMax: 345.5 + m_HAllowExceedBaseRangeMin: 1 + m_HAllowExceedBaseRangeMax: 1 + m_VAllowExceedBaseRangeMin: 1 + m_VAllowExceedBaseRangeMax: 1 + m_ScaleWithWindow: 0 + m_HSlider: 0 + m_VSlider: 0 + m_IgnoreScrollWheelUntilClicked: 0 + m_EnableMouseInput: 1 + m_EnableSliderZoomHorizontal: 0 + m_EnableSliderZoomVertical: 0 + m_UniformScale: 1 + m_UpDirection: 1 + m_DrawArea: + serializedVersion: 2 + x: 0 + y: 21 + width: 1492 + height: 691 + m_Scale: {x: 1, y: 1} + m_Translation: {x: 746, y: 345.5} + m_MarginLeft: 0 + m_MarginRight: 0 + m_MarginTop: 0 + m_MarginBottom: 0 + m_LastShownAreaInsideMargins: + serializedVersion: 2 + x: -746 + y: -345.5 + width: 1492 + height: 691 + m_MinimalGUI: 1 + m_defaultScale: 1 + m_LastWindowPixelSize: {x: 1492, y: 712} + m_ClearInEditMode: 1 + m_NoCameraWarning: 1 + m_LowResolutionForAspectRatios: 01000001000000000000 + m_XRRenderMode: 0 + m_RenderTexture: {fileID: 0} +--- !u!114 &14 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12013, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Scene + m_Image: {fileID: 2593428753322112591, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 0 + y: 73 + width: 1492 + height: 845 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: + - dockPosition: 0 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: -166, y: -26} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 3 + id: Tool Settings + index: 0 + layout: 1 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 0 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: -141, y: 149} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 1 + id: unity-grid-and-snap-toolbar + index: 1 + layout: 1 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 25} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: unity-scene-view-toolbar + index: 0 + layout: 1 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-toolbar__top + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 1 + id: unity-search-toolbar + index: 1 + layout: 1 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 0 + containerId: overlay-container--left + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 25} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: unity-transform-toolbar + index: 0 + layout: 2 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 0 + containerId: overlay-container--left + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 0, y: 197} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: unity-component-tools + index: 1 + layout: 2 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 0 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 67.5, y: -123} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 2 + id: Orientation + index: 0 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Light Settings + index: 2 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Camera + index: 1 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Cloth Constraints + index: 3 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Cloth Collisions + index: 4 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Navmesh Display + index: 4 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Agent Display + index: 5 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Obstacle Display + index: 6 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Occlusion Culling + index: 5 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Physics Debugger + index: 6 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Scene Visibility + index: 7 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 25} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Particles + index: 8 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Tilemap + index: 11 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 0, y: 0} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Tilemap Palette Helper + index: 12 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: -216, y: -156} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 3 + id: AINavigationOverlay + index: 9 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: APV Overlay + index: 8 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/TrailRenderer + index: 10 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 1 + snapOffset: {x: 48, y: 10} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: UnityEditor.SceneViewCameraOverlay + index: 10 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Open Tile Palette + index: 0 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + - dockPosition: 1 + containerId: overlay-container--right + floating: 0 + collapsed: 0 + displayed: 0 + snapOffset: {x: 48, y: 48} + snapOffsetDelta: {x: 0, y: 0} + snapCorner: 0 + id: Scene View/Tilemap Focus + index: 1 + layout: 4 + size: {x: 0, y: 0} + sizeOverriden: 0 + m_OverlaysVisible: 1 + m_WindowGUID: c9ee0d44a80756c48ba1fd3e952ef1b5 + m_Gizmos: 1 + m_OverrideSceneCullingMask: 6917529027641081856 + m_SceneIsLit: 1 + m_SceneLighting: 1 + m_2DMode: 0 + m_isRotationLocked: 0 + m_PlayAudio: 0 + m_AudioPlay: 0 + m_Position: + m_Target: {x: 0, y: 0, z: 0} + speed: 2 + m_Value: {x: 0, y: 0, z: 0} + m_RenderMode: 0 + m_CameraMode: + drawMode: 0 + name: Shaded + section: Shading Mode + m_ValidateTrueMetals: 0 + m_DoValidateTrueMetals: 0 + m_SceneViewState: + m_AlwaysRefresh: 0 + showFog: 1 + showSkybox: 1 + showFlares: 1 + showImageEffects: 1 + showParticleSystems: 1 + showVisualEffectGraphs: 1 + m_FxEnabled: 1 + m_Grid: + xGrid: + m_Fade: + m_Target: 0 + speed: 2 + m_Value: 0 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 0, y: 0} + yGrid: + m_Fade: + m_Target: 1 + speed: 2 + m_Value: 1 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 1, y: 1} + zGrid: + m_Fade: + m_Target: 0 + speed: 2 + m_Value: 0 + m_Color: {r: 0.5, g: 0.5, b: 0.5, a: 0.4} + m_Pivot: {x: 0, y: 0, z: 0} + m_Size: {x: 1, y: 1} + m_ShowGrid: 1 + m_GridAxis: 1 + m_gridOpacity: 0.5 + m_Rotation: + m_Target: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} + speed: 2 + m_Value: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} + m_Size: + m_Target: 10 + speed: 2 + m_Value: 10 + m_Ortho: + m_Target: 0 + speed: 2 + m_Value: 0 + m_CameraSettings: + m_Speed: 0.8856 + m_SpeedNormalized: 0.44 + m_SpeedMin: 0.01 + m_SpeedMax: 2 + m_EasingEnabled: 1 + m_EasingDuration: 0.4 + m_AccelerationEnabled: 1 + m_FieldOfViewHorizontalOrVertical: 60 + m_NearClip: 0.03 + m_FarClip: 10000 + m_DynamicClip: 1 + m_OcclusionCulling: 0 + m_LastSceneViewRotation: {x: -0.08717229, y: 0.89959055, z: -0.21045254, w: -0.3726226} + m_LastSceneViewOrtho: 0 + m_ReplacementShader: {fileID: 0} + m_ReplacementString: + m_SceneVisActive: 1 + m_LastLockedObject: {fileID: 0} + m_ViewIsLockedToObject: 0 +--- !u!114 &15 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 12070, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 900, y: 216} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Profiler + m_Image: {fileID: -1089619856830078684, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 0 + y: 806 + width: 1492 + height: 545 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_Recording: 1 + m_ActiveNativePlatformSupportModuleName: + m_AllModules: + - rid: 7267259948770525184 + - rid: 7267259948770525185 + - rid: 7267259948770525186 + - rid: 7267259948770525187 + - rid: 7267259948770525188 + - rid: 7267259948770525189 + - rid: 7267259948770525190 + - rid: 7267259948770525191 + - rid: 7267259948770525192 + - rid: 7267259948770525193 + - rid: 7267259948770525194 + - rid: 7267259948770525195 + - rid: 7267259948770525196 + - rid: 7267259948770525197 + m_CallstackRecordMode: 1 + m_ClearOnPlay: 0 + references: + version: 2 + RefIds: + - rid: 7267259948770525184 + type: {class: CPUProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.CPUProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_ViewType: 0 + updateViewLive: 0 + m_CurrentFrameIndex: 1103 + m_HierarchyOverruledThreadFromSelection: 0 + m_ProfilerViewFilteringOptions: 1 + m_FrameDataHierarchyView: + m_Serialized: 1 + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 8b000000 + m_LastClickedID: 139 + m_ExpandedIDs: 040000003a0000008b000000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_MultiColumnHeaderState: + m_Columns: + - width: 200 + sortedAscending: 1 + headerContent: + m_Text: Overview + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 200 + maxWidth: 1000000 + autoResize: 1 + allowToggleVisibility: 0 + canSort: 1 + userData: 0 + - width: 80 + sortedAscending: 0 + headerContent: + m_Text: Total + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 50 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 80 + sortedAscending: 0 + headerContent: + m_Text: Self + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 50 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 80 + sortedAscending: 0 + headerContent: + m_Text: Calls + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 50 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 80 + sortedAscending: 0 + headerContent: + m_Text: GC Alloc + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 50 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 80 + sortedAscending: 0 + headerContent: + m_Text: Time ms + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 50 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 80 + sortedAscending: 0 + headerContent: + m_Text: Self ms + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 50 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 25 + sortedAscending: 0 + headerContent: + m_Text: + m_Image: {fileID: -5161429177145976760, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: Warnings + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 25 + maxWidth: 25 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + m_VisibleColumns: 0000000001000000020000000300000004000000050000000600000007000000 + m_SortedColumns: 05000000 + m_ThreadIndexInThreadNames: 0 + m_DetailedViewType: 0 + m_DetailedViewSpliterState: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: -1 + realSizes: + - 0 + - 0 + relativeSizes: + - 0.7 + - 0.3 + minSizes: + - 450 + - 50 + maxSizes: + - 0 + - 0 + lastTotalSize: 0 + splitSize: 6 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_DetailedObjectsView: + m_SelectedID: -1 + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_MultiColumnHeaderState: + m_Columns: [] + m_VisibleColumns: + m_SortedColumns: + m_VertSplit: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: 0 + realSizes: [] + relativeSizes: [] + minSizes: [] + maxSizes: [] + lastTotalSize: 0 + splitSize: 0 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_DetailedCallsView: + m_SelectedID: -1 + m_VertSplit: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: 0 + realSizes: [] + relativeSizes: [] + minSizes: [] + maxSizes: [] + lastTotalSize: 0 + splitSize: 0 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_CalleesTreeView: + m_ViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_ViewHeaderState: + m_Columns: + - width: 150 + sortedAscending: 1 + headerContent: + m_Text: Called From + m_Image: {fileID: 0} + m_Tooltip: 'Parents the selected function is called from + + + (Press + ''F'' for frame selection)' + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 150 + maxWidth: 1000000 + autoResize: 1 + allowToggleVisibility: 0 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Calls + m_Image: {fileID: 0} + m_Tooltip: Total number of calls in a selected frame + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: GC Alloc + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Time ms + m_Image: {fileID: 0} + m_Tooltip: Total time the selected function spends within a parent + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Time % + m_Image: {fileID: 0} + m_Tooltip: Shows how often the selected function was called from + the parent call + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + m_VisibleColumns: 0000000001000000020000000300000004000000 + m_SortedColumns: 03000000 + m_CallersTreeView: + m_ViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_ViewHeaderState: + m_Columns: + - width: 150 + sortedAscending: 1 + headerContent: + m_Text: Called From + m_Image: {fileID: 0} + m_Tooltip: 'Parents the selected function is called from + + + (Press + ''F'' for frame selection)' + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 150 + maxWidth: 1000000 + autoResize: 1 + allowToggleVisibility: 0 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Calls + m_Image: {fileID: 0} + m_Tooltip: Total number of calls in a selected frame + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: GC Alloc + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Time ms + m_Image: {fileID: 0} + m_Tooltip: Total time the selected function spends within a parent + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Time % + m_Image: {fileID: 0} + m_Tooltip: Shows how often the selected function was called from + the parent call + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + m_VisibleColumns: 0000000001000000020000000300000004000000 + m_SortedColumns: 03000000 + m_FullThreadName: Main Thread + m_ThreadName: Main Thread + k__BackingField: 1059876 + k__BackingField: 0 + m_GroupName: + - rid: 7267259948770525185 + type: {class: GPUProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.GPUProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_ViewType: 0 + updateViewLive: 0 + m_CurrentFrameIndex: -1 + m_HierarchyOverruledThreadFromSelection: 0 + m_ProfilerViewFilteringOptions: 1 + m_FrameDataHierarchyView: + m_Serialized: 0 + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_MultiColumnHeaderState: + m_Columns: [] + m_VisibleColumns: + m_SortedColumns: + m_ThreadIndexInThreadNames: 0 + m_DetailedViewType: 0 + m_DetailedViewSpliterState: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: 0 + realSizes: [] + relativeSizes: [] + minSizes: [] + maxSizes: [] + lastTotalSize: 0 + splitSize: 0 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_DetailedObjectsView: + m_SelectedID: 0 + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_MultiColumnHeaderState: + m_Columns: [] + m_VisibleColumns: + m_SortedColumns: + m_VertSplit: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: 0 + realSizes: [] + relativeSizes: [] + minSizes: [] + maxSizes: [] + lastTotalSize: 0 + splitSize: 0 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_DetailedCallsView: + m_SelectedID: -1 + m_VertSplit: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: 0 + realSizes: [] + relativeSizes: [] + minSizes: [] + maxSizes: [] + lastTotalSize: 0 + splitSize: 0 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + m_CalleesTreeView: + m_ViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_ViewHeaderState: + m_Columns: + - width: 150 + sortedAscending: 1 + headerContent: + m_Text: Called From + m_Image: {fileID: 0} + m_Tooltip: 'Parents the selected function is called from + + + (Press + ''F'' for frame selection)' + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 150 + maxWidth: 1000000 + autoResize: 1 + allowToggleVisibility: 0 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Calls + m_Image: {fileID: 0} + m_Tooltip: Total number of calls in a selected frame + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: GC Alloc + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Time ms + m_Image: {fileID: 0} + m_Tooltip: Total time the selected function spends within a parent + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Time % + m_Image: {fileID: 0} + m_Tooltip: Shows how often the selected function was called from + the parent call + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + m_VisibleColumns: 0000000001000000020000000300000004000000 + m_SortedColumns: 03000000 + m_CallersTreeView: + m_ViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_ViewHeaderState: + m_Columns: + - width: 150 + sortedAscending: 1 + headerContent: + m_Text: Called From + m_Image: {fileID: 0} + m_Tooltip: 'Parents the selected function is called from + + + (Press + ''F'' for frame selection)' + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 150 + maxWidth: 1000000 + autoResize: 1 + allowToggleVisibility: 0 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Calls + m_Image: {fileID: 0} + m_Tooltip: Total number of calls in a selected frame + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: GC Alloc + m_Image: {fileID: 0} + m_Tooltip: + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Time ms + m_Image: {fileID: 0} + m_Tooltip: Total time the selected function spends within a parent + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + - width: 60 + sortedAscending: 0 + headerContent: + m_Text: Time % + m_Image: {fileID: 0} + m_Tooltip: Shows how often the selected function was called from + the parent call + contextMenuText: + headerTextAlignment: 0 + sortingArrowAlignment: 2 + minWidth: 60 + maxWidth: 1000000 + autoResize: 0 + allowToggleVisibility: 1 + canSort: 1 + userData: 0 + m_VisibleColumns: 0000000001000000020000000300000004000000 + m_SortedColumns: 03000000 + m_FullThreadName: Main Thread + m_ThreadName: Main Thread + k__BackingField: 0 + k__BackingField: -1 + m_GroupName: + - rid: 7267259948770525186 + type: {class: RenderingProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.RenderingProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525187 + type: {class: MemoryProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.MemoryProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_ViewSplit: + ID: 0 + splitterInitialOffset: 0 + currentActiveSplitter: -1 + realSizes: + - 0 + - 0 + relativeSizes: + - 0.7 + - 0.3 + minSizes: + - 450 + - 50 + maxSizes: + - 0 + - 0 + lastTotalSize: 0 + splitSize: 6 + xOffset: 0 + m_Version: 1 + oldRealSizes: + oldMinSizes: + oldMaxSizes: + oldSplitSize: 0 + - rid: 7267259948770525188 + type: {class: AudioProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.AudioProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_ShowInactiveDSPChains: 0 + m_HighlightAudibleDSPChains: 1 + m_DSPGraphZoomFactor: 1 + m_DSPGraphHorizontalLayout: 0 + - rid: 7267259948770525189 + type: {class: VideoProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.VideoProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525190 + type: {class: PhysicsProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.PhysicsProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525191 + type: {class: Physics2DProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.Physics2DProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525192 + type: {class: UIProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.UIProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525193 + type: {class: UIDetailsProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.UIDetailsProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525194 + type: {class: GlobalIlluminationProfilerModule, ns: UnityEditorInternal.Profiling, + asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.GlobalIlluminationProfilerModule, + UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525195 + type: {class: VirtualTexturingProfilerModule, ns: UnityEditorInternal.Profiling, + asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.VirtualTexturingProfilerModule, + UnityEditor.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + m_VTProfilerView: + rid: 7267259948770525198 + - rid: 7267259948770525196 + type: {class: FileIOProfilerModule, ns: UnityEditorInternal.Profiling, asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.FileIOProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525197 + type: {class: AssetLoadingProfilerModule, ns: UnityEditorInternal.Profiling, + asm: UnityEditor.CoreModule} + data: + m_Identifier: UnityEditorInternal.Profiling.AssetLoadingProfilerModule, UnityEditor.CoreModule, + Version=0.0.0.0, Culture=neutral, PublicKeyToken=null + m_PaneScroll: {x: 0, y: 0} + - rid: 7267259948770525198 + type: {class: VirtualTexturingProfilerView, ns: UnityEditor, asm: UnityEditor.CoreModule} + data: + m_SortAscending: 0 + m_SortedColumn: -1 +--- !u!114 &16 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12061, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 200, y: 200} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Hierarchy + m_Image: {fileID: 7966133145522015247, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1493 + y: 73 + width: 374 + height: 603 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_SceneHierarchy: + m_TreeViewState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 887a0000 + m_LastClickedID: 0 + m_ExpandedIDs: 1638ffff1a3cffff + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 0 + m_ClientGUIView: {fileID: 10} + m_SearchString: + m_ExpandedScenes: [] + m_CurrenRootInstanceID: 0 + m_LockTracker: + m_IsLocked: 0 + m_CurrentSortingName: TransformSorting + m_WindowGUID: 5744dfe58afd7b349b2bf692722dc4ff +--- !u!114 &17 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12014, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 230, y: 250} + m_MaxSize: {x: 10000, y: 10000} + m_TitleContent: + m_Text: Project + m_Image: {fileID: -5467254957812901981, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1493 + y: 697 + width: 374 + height: 654 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_SearchFilter: + m_NameFilter: + m_ClassNames: [] + m_AssetLabels: [] + m_AssetBundleNames: [] + m_ReferencingInstanceIDs: + m_SceneHandles: + m_ShowAllHits: 0 + m_SkipHidden: 0 + m_SearchArea: 1 + m_Folders: + - Assets + m_Globs: [] + m_OriginalText: + m_ImportLogFlags: 0 + m_FilterByTypeIntersection: 0 + m_ViewMode: 0 + m_StartGridSize: 16 + m_LastFolders: [] + m_LastFoldersGridSize: -1 + m_LastProjectPath: E:\Projects\LiteNetLib\LiteNetLibSampleUnity + m_LockTracker: + m_IsLocked: 0 + m_FolderTreeState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: 0e800000 + m_LastClickedID: 32782 + m_ExpandedIDs: ffffffffd0400000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 0} + m_SearchString: + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_AssetTreeState: + scrollPos: {x: 0, y: 0} + m_SelectedIDs: + m_LastClickedID: 0 + m_ExpandedIDs: ffffffffd0400000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 11} + m_SearchString: + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_ListAreaState: + m_SelectedInstanceIDs: + m_LastClickedInstanceID: 0 + m_HadKeyboardFocusLastEvent: 0 + m_ExpandedInstanceIDs: c6230000d0640000967900008e6d00007674000022740000a66f000000000000687100009c230000f4b70000288000007a5f00008e7d0000ecbc0000346d0000f09c0000c297000026850000f06c0000de7d0000 + m_RenameOverlay: + m_UserAcceptedRename: 0 + m_Name: + m_OriginalName: + m_EditFieldRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 0 + height: 0 + m_UserData: 0 + m_IsWaitingForDelay: 0 + m_IsRenaming: 0 + m_OriginalEventType: 11 + m_IsRenamingFilename: 1 + m_ClientGUIView: {fileID: 11} + m_CreateAssetUtility: + m_EndAction: {fileID: 0} + m_InstanceID: 0 + m_Path: + m_Icon: {fileID: 0} + m_ResourceFile: + m_NewAssetIndexInList: -1 + m_ScrollPosition: {x: 0, y: 0} + m_GridSize: 16 + m_SkipHiddenPackages: 0 + m_DirectoriesAreaWidth: 178 +--- !u!114 &18 +MonoBehaviour: + m_ObjectHideFlags: 52 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 1 + m_Script: {fileID: 12019, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_MinSize: {x: 275, y: 50} + m_MaxSize: {x: 4000, y: 4000} + m_TitleContent: + m_Text: Inspector + m_Image: {fileID: -2667387946076563598, guid: 0000000000000000d000000000000000, + type: 0} + m_Tooltip: + m_Pos: + serializedVersion: 2 + x: 1869 + y: 73 + width: 690 + height: 1278 + m_SerializedDataModeController: + m_DataMode: 0 + m_PreferredDataMode: 0 + m_SupportedDataModes: + isAutomatic: 1 + m_ViewDataDictionary: {fileID: 0} + m_OverlayCanvas: + m_LastAppliedPresetName: Default + m_SaveData: [] + m_OverlaysVisible: 1 + m_ObjectsLockedBeforeSerialization: [] + m_InstanceIDsLockedBeforeSerialization: + m_PreviewResizer: + m_CachedPref: 526 + m_ControlHash: -371814159 + m_PrefName: Preview_InspectorPreview + m_LastInspectedObjectInstanceID: -1 + m_LastVerticalScrollValue: 0 + m_GlobalObjectId: + m_InspectorMode: 0 + m_LockTracker: + m_IsLocked: 0 + m_PreviewWindow: {fileID: 0} diff --git a/LiteNetLibSampleUnity/UserSettings/Search.settings b/LiteNetLibSampleUnity/UserSettings/Search.settings new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/LiteNetLibSampleUnity/UserSettings/Search.settings @@ -0,0 +1 @@ +{} \ No newline at end of file From 2c2bd6805d0a563a622df68b79ec16b82122fcf5 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 20 Dec 2023 11:50:05 +0200 Subject: [PATCH 065/261] fix and optimize native sockets also --- LiteNetLib/NativeSocket.cs | 48 -------------------------------- LiteNetLib/NetManager.HashSet.cs | 2 +- LiteNetLib/NetManager.Socket.cs | 41 +++++++++++++++++++++------ LiteNetLib/NetPeer.cs | 16 ++++++++--- 4 files changed, 45 insertions(+), 62 deletions(-) diff --git a/LiteNetLib/NativeSocket.cs b/LiteNetLib/NativeSocket.cs index 171f48b6..f9d7b541 100644 --- a/LiteNetLib/NativeSocket.cs +++ b/LiteNetLib/NativeSocket.cs @@ -7,54 +7,6 @@ namespace LiteNetLib { - internal class NativeEndPoint : IPEndPoint - { - public byte[] NativeAddress; - - public void CopyNativeAddress() - { - var tempAddr = new byte[NativeAddress.Length]; - Buffer.BlockCopy(NativeAddress, 0, tempAddr, 0, NativeAddress.Length); - NativeAddress = tempAddr; - } - - public void SetNetAddress(byte[] address) - { - NativeAddress = address; - short family = (short)((address[1] << 8) | address[0]); - Port =(ushort)((address[2] << 8) | address[3]); - - if ((NativeSocket.UnixMode && family == NativeSocket.AF_INET6) || (!NativeSocket.UnixMode && (AddressFamily)family == AddressFamily.InterNetworkV6)) - { - uint scope = unchecked((uint)( - (address[27] << 24) + - (address[26] << 16) + - (address[25] << 8) + - (address[24]))); -#if NETCOREAPP || NETSTANDARD2_1 || NETSTANDARD2_1_OR_GREATER - Address = new IPAddress(new ReadOnlySpan(address, 8, 16), scope); -#else - byte[] addrBuffer = new byte[16]; - Buffer.BlockCopy(address, 8, addrBuffer, 0, 16); - Address = new IPAddress(addrBuffer, scope); -#endif - } - else //IPv4 - { - long ipv4Addr = unchecked((uint)((address[4] & 0x000000FF) | - (address[5] << 8 & 0x0000FF00) | - (address[6] << 16 & 0x00FF0000) | - (address[7] << 24))); - Address = new IPAddress(ipv4Addr); - } - } - - public NativeEndPoint() : base(IPAddress.Any, 0) - { - - } - } - internal static class NativeSocket { static diff --git a/LiteNetLib/NetManager.HashSet.cs b/LiteNetLib/NetManager.HashSet.cs index 944fb2be..72181aca 100644 --- a/LiteNetLib/NetManager.HashSet.cs +++ b/LiteNetLib/NetManager.HashSet.cs @@ -205,7 +205,7 @@ private bool TryGetPeer(IPEndPoint endPoint, out NetPeer actualValue) { #if NET8_0_OR_GREATER //can be NetPeer or IPEndPoint - int hashCode = endPoint.Serialize().GetHashCode() & Lower31BitMask; + int hashCode = (UseNativeSockets ? endPoint.GetHashCode() : endPoint.Serialize().GetHashCode()) & Lower31BitMask; #else int hashCode = endPoint.GetHashCode() & Lower31BitMask; #endif diff --git a/LiteNetLib/NetManager.Socket.cs b/LiteNetLib/NetManager.Socket.cs index b3a7b56c..66b7b21e 100644 --- a/LiteNetLib/NetManager.Socket.cs +++ b/LiteNetLib/NetManager.Socket.cs @@ -129,7 +129,7 @@ private void NativeReceiveLogic() IntPtr socketHandle6 = _udpSocketv6?.Handle ?? IntPtr.Zero; byte[] addrBuffer4 = new byte[NativeSocket.IPv4AddrSize]; byte[] addrBuffer6 = new byte[NativeSocket.IPv6AddrSize]; - var tempEndPoint = new NativeEndPoint(); + var tempEndPoint = new IPEndPoint(IPAddress.Any, 0); var selectReadList = new List(2); var socketv4 = _udpSocketv4; var socketV6 = _udpSocketv6; @@ -190,11 +190,10 @@ private void NativeReceiveLogic() } } - bool NativeReceiveFrom(IntPtr s, byte[] addrBuffer) + bool NativeReceiveFrom(IntPtr s, byte[] address) { - //Reading data - int addrSize = addrBuffer.Length; - packet.Size = NativeSocket.RecvFrom(s, packet.RawData, NetConstants.MaxPacketSize, addrBuffer, ref addrSize); + int addrSize = address.Length; + packet.Size = NativeSocket.RecvFrom(s, packet.RawData, NetConstants.MaxPacketSize, address, ref addrSize); if (packet.Size == 0) return true; //socket closed or empty packet @@ -204,9 +203,34 @@ bool NativeReceiveFrom(IntPtr s, byte[] addrBuffer) return ProcessError(new SocketException((int)NativeSocket.GetSocketError())) == false; } - //All ok! //NetDebug.WriteForce($"[R]Received data from {endPoint}, result: {packet.Size}"); - tempEndPoint.SetNetAddress(addrBuffer); + //refresh temp Addr/Port + short family = (short)((address[1] << 8) | address[0]); + tempEndPoint.Port =(ushort)((address[2] << 8) | address[3]); + if ((NativeSocket.UnixMode && family == NativeSocket.AF_INET6) || (!NativeSocket.UnixMode && (AddressFamily)family == AddressFamily.InterNetworkV6)) + { + uint scope = unchecked((uint)( + (address[27] << 24) + + (address[26] << 16) + + (address[25] << 8) + + (address[24]))); +#if NETCOREAPP || NETSTANDARD2_1 || NETSTANDARD2_1_OR_GREATER + tempEndPoint.Address = new IPAddress(new ReadOnlySpan(address, 8, 16), scope); +#else + byte[] addrBuffer = new byte[16]; + Buffer.BlockCopy(address, 8, addrBuffer, 0, 16); + tempEndPoint.Address = new IPAddress(addrBuffer, scope); +#endif + } + else //IPv4 + { + long ipv4Addr = unchecked((uint)((address[4] & 0x000000FF) | + (address[5] << 8 & 0x0000FF00) | + (address[6] << 16 & 0x00FF0000) | + (address[7] << 24))); + tempEndPoint.Address = new IPAddress(ipv4Addr); + } + if (TryGetPeer(tempEndPoint, out var peer)) { //use cached native ep @@ -214,9 +238,8 @@ bool NativeReceiveFrom(IntPtr s, byte[] addrBuffer) } else { - tempEndPoint.CopyNativeAddress(); OnMessageReceived(packet, tempEndPoint); - tempEndPoint = new NativeEndPoint(); + tempEndPoint = new IPEndPoint(IPAddress.Any, 0); } packet = PoolGetPacket(NetConstants.MaxPacketSize); return true; diff --git a/LiteNetLib/NetPeer.cs b/LiteNetLib/NetPeer.cs index 38c10999..1852e69c 100644 --- a/LiteNetLib/NetPeer.cs +++ b/LiteNetLib/NetPeer.cs @@ -222,9 +222,13 @@ internal NetPeer(NetManager netManager, IPEndPoint remoteEndPoint, int id) : bas Statistics = new NetStatistics(); NetManager = netManager; - if (NetManager.UseNativeSockets && remoteEndPoint is NativeEndPoint nep) - NativeAddress = nep.NativeAddress; _cachedSocketAddr = base.Serialize(); + if (NetManager.UseNativeSockets) + { + NativeAddress = new byte[_cachedSocketAddr.Size]; + for (int i = 0; i < _cachedSocketAddr.Size; i++) + NativeAddress[i] = _cachedSocketAddr[i]; + } #if NET8_0_OR_GREATER _cachedHashCode = NetManager.UseNativeSockets ? base.GetHashCode() : _cachedSocketAddr.GetHashCode(); #else @@ -261,8 +265,12 @@ internal void FinishEndPointChange(IPEndPoint newEndPoint) Address = newEndPoint.Address; Port = newEndPoint.Port; - if (NetManager.UseNativeSockets && newEndPoint is NativeEndPoint nep) - NativeAddress = nep.NativeAddress; + if (NetManager.UseNativeSockets) + { + NativeAddress = new byte[_cachedSocketAddr.Size]; + for (int i = 0; i < _cachedSocketAddr.Size; i++) + NativeAddress[i] = _cachedSocketAddr[i]; + } _cachedSocketAddr = base.Serialize(); #if NET8_0_OR_GREATER _cachedHashCode = NetManager.UseNativeSockets ? base.GetHashCode() : _cachedSocketAddr.GetHashCode(); From 38d962fcdaaf13964a2271d97815aa828764ab99 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 20 Dec 2023 12:13:12 +0200 Subject: [PATCH 066/261] upd --- LiteNetLibSampleUnity/Assets/LiteNetLib.dll | Bin 108544 -> 108032 bytes LiteNetLibSampleUnity/Assets/LiteNetLib.xml | 36 ++++++++++++-------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/LiteNetLibSampleUnity/Assets/LiteNetLib.dll b/LiteNetLibSampleUnity/Assets/LiteNetLib.dll index 7b7607d47ba80eaa40dc7e67cfa1ebabdad10a4a..039625da8c17b8fe832143e18f0ad9f9ead6b675 100644 GIT binary patch literal 108032 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 PomgOv@~hu39|isg{ZL-? literal 108544 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 - -

                                          - Gets peer by peer id - - id of peer - Peer if peer with id exist, otherwise null - - - - Gets peer by peer id - - id of peer - resulting peer - True if peer with id exist, otherwise false - Returns connected peers count @@ -716,6 +701,21 @@ NTP Server address. + + + Gets peer by peer id + + id of peer + Peer if peer with id exist, otherwise null + + + + Gets peer by peer id + + id of peer + resulting peer + True if peer with id exist, otherwise false + Maximum packet pool size (increase if you have tons of packets sending) @@ -811,6 +811,12 @@ Statistics of peer connection + + + IPEndPoint serialize + + SocketAddress + Returns packets count in queue for reliable channel From 786b1342414545796cc101dffa1b3f3eaee38707 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 20 Dec 2023 12:15:06 +0200 Subject: [PATCH 067/261] upd readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 48d2e622..fd26542d 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ Lite reliable UDP library for .NET Standard 2.0 (Mono, .NET Core, .NET Framework * Connection statisitcs * Multicasting (for discovering hosts in local network) * Unity support +* Support for .NET8 optimized socket calls (much less gc) * Supported platforms: * Windows/Mac/Linux (.NET Framework, Mono, .NET Core, .NET Standard) * Lumin OS (Magic Leap) From 8bbcedb1dbdc6f46131bccd4628c30445492090c Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 20 Dec 2023 12:21:12 +0200 Subject: [PATCH 068/261] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fd26542d..64a869bb 100644 --- a/README.md +++ b/README.md @@ -103,10 +103,10 @@ listener.ConnectionRequestEvent += request => listener.PeerConnectedEvent += peer => { - Console.WriteLine("We got connection: {0}", peer.EndPoint); // Show peer ip - NetDataWriter writer = new NetDataWriter(); // Create writer class - writer.Put("Hello client!"); // Put some string - peer.Send(writer, DeliveryMethod.ReliableOrdered); // Send with reliability + Console.WriteLine("We got connection: {0}", peer); // Show peer ip + NetDataWriter writer = new NetDataWriter(); // Create writer class + writer.Put("Hello client!"); // Put some string + peer.Send(writer, DeliveryMethod.ReliableOrdered); // Send with reliability }; while (!Console.KeyAvailable) From 8d9cb8386b1587d3780f2525aecde9ede9983dbf Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 20 Dec 2023 12:27:43 +0200 Subject: [PATCH 069/261] upd docs --- docs/api/LiteNetLib.ConnectionRequest.html | 68 +- docs/api/LiteNetLib.ConnectionState.html | 2 +- docs/api/LiteNetLib.DeliveryMethod.html | 2 +- docs/api/LiteNetLib.DisconnectInfo.html | 2 +- docs/api/LiteNetLib.DisconnectReason.html | 2 +- ...LiteNetLib.EventBasedNatPunchListener.html | 2 +- .../api/LiteNetLib.EventBasedNetListener.html | 2 +- .../LiteNetLib.IDeliveryEventListener.html | 2 +- docs/api/LiteNetLib.INatPunchListener.html | 2 +- docs/api/LiteNetLib.INetEventListener.html | 2 +- docs/api/LiteNetLib.INetLogger.html | 2 +- docs/api/LiteNetLib.INtpEventListener.html | 2 +- ...iteNetLib.IPeerAddressChangedListener.html | 2 +- docs/api/LiteNetLib.IPv6Mode.html | 2 +- .../LiteNetLib.InvalidPacketException.html | 2 +- docs/api/LiteNetLib.Layers.Crc32cLayer.html | 2 +- .../LiteNetLib.Layers.PacketLayerBase.html | 2 +- .../LiteNetLib.Layers.XorEncryptLayer.html | 2 +- docs/api/LiteNetLib.Layers.html | 5 +- docs/api/LiteNetLib.LocalAddrType.html | 2 +- docs/api/LiteNetLib.NatAddressType.html | 2 +- docs/api/LiteNetLib.NatPunchModule.html | 2 +- docs/api/LiteNetLib.NetConstants.html | 10 +- docs/api/LiteNetLib.NetDebug.html | 2 +- docs/api/LiteNetLib.NetLogLevel.html | 2 +- ...teNetLib.NetManager.NetPeerEnumerator.html | 49 +- docs/api/LiteNetLib.NetManager.html | 270 ++--- docs/api/LiteNetLib.NetPacketReader.html | 2 +- docs/api/LiteNetLib.NetPeer.html | 36 +- docs/api/LiteNetLib.NetStatistics.html | 8 +- docs/api/LiteNetLib.NetUtils.html | 20 +- docs/api/LiteNetLib.PooledPacket.html | 2 +- .../api/LiteNetLib.TooBigPacketException.html | 2 +- .../LiteNetLib.UnconnectedMessageType.html | 2 +- docs/api/LiteNetLib.Utils.CRC32C.html | 2 +- .../LiteNetLib.Utils.FastBitConverter.html | 2 +- .../LiteNetLib.Utils.INetSerializable.html | 2 +- ...LiteNetLib.Utils.InvalidTypeException.html | 2 +- docs/api/LiteNetLib.Utils.NetDataReader.html | 466 ++++----- docs/api/LiteNetLib.Utils.NetDataWriter.html | 208 ++-- .../LiteNetLib.Utils.NetPacketProcessor.html | 298 +++--- docs/api/LiteNetLib.Utils.NetSerializer.html | 172 ++-- .../LiteNetLib.Utils.NtpLeapIndicator.html | 2 +- docs/api/LiteNetLib.Utils.NtpMode.html | 2 +- docs/api/LiteNetLib.Utils.NtpPacket.html | 2 +- docs/api/LiteNetLib.Utils.ParseException.html | 2 +- .../LiteNetLib.Utils.PreserveAttribute.html | 2 +- docs/api/LiteNetLib.Utils.html | 11 +- docs/api/LiteNetLib.html | 14 +- docs/api/index.html | 3 +- docs/api/toc.html | 8 +- docs/api/toc.json | 2 + docs/articles/netserializerusage.html | 3 +- docs/articles/toc.html | 4 +- docs/articles/toc.json | 2 + docs/index.html | 3 +- docs/manifest.json | 13 +- docs/styles/docfx.css | 17 +- docs/styles/docfx.js | 70 +- docs/styles/docfx.vendor.min.css | 2 +- docs/styles/docfx.vendor.min.css.map | 2 +- docs/styles/docfx.vendor.min.js | 47 +- docs/styles/docfx.vendor.min.js.map | 8 +- docs/styles/main.js | 3 +- docs/styles/search-worker.min.js.map | 4 +- docs/toc.html | 4 +- docs/toc.json | 2 + docs/xrefmap.yml | 934 +++++++++--------- update_docs.bat | 2 +- 69 files changed, 1425 insertions(+), 1413 deletions(-) create mode 100644 docs/api/toc.json create mode 100644 docs/articles/toc.json create mode 100644 docs/toc.json diff --git a/docs/api/LiteNetLib.ConnectionRequest.html b/docs/api/LiteNetLib.ConnectionRequest.html index 2ac6eed4..d1a0a112 100644 --- a/docs/api/LiteNetLib.ConnectionRequest.html +++ b/docs/api/LiteNetLib.ConnectionRequest.html @@ -250,12 +250,12 @@
                                          Parameters
                                          -

                                          Reject(byte[], int, int, bool)

                                          +

                                          Reject(byte[])

                                          Declaration
                                          -
                                          public void Reject(byte[] rejectData, int start, int length, bool force)
                                          +
                                          public void Reject(byte[] rejectData)
                                          Parameters
                                          @@ -272,21 +272,6 @@
                                          Parameters
                                          - - - - - - - - - - - - - - -
                                          rejectData
                                          intstart
                                          intlength
                                          boolforce
                                          @@ -329,12 +314,12 @@
                                          Parameters
                                          -

                                          Reject(byte[])

                                          +

                                          Reject(byte[], int, int, bool)

                                          Declaration
                                          -
                                          public void Reject(byte[] rejectData)
                                          +
                                          public void Reject(byte[] rejectData, int start, int length, bool force)
                                          Parameters
                                          @@ -351,6 +336,21 @@
                                          Parameters
                                          + + + + + + + + + + + + + + +
                                          rejectData
                                          intstart
                                          intlength
                                          boolforce
                                          @@ -393,12 +393,12 @@
                                          Parameters
                                          -

                                          RejectForce(byte[], int, int)

                                          +

                                          RejectForce(byte[])

                                          Declaration
                                          -
                                          public void RejectForce(byte[] rejectData, int start, int length)
                                          +
                                          public void RejectForce(byte[] rejectData)
                                          Parameters
                                          @@ -415,27 +415,17 @@
                                          Parameters
                                          - - - - - - - - - -
                                          rejectData
                                          intstart
                                          intlength
                                          -

                                          RejectForce(byte[])

                                          +

                                          RejectForce(byte[], int, int)

                                          Declaration
                                          -
                                          public void RejectForce(byte[] rejectData)
                                          +
                                          public void RejectForce(byte[] rejectData, int start, int length)
                                          Parameters
                                          @@ -452,6 +442,16 @@
                                          Parameters
                                          + + + + + + + + + +
                                          rejectData
                                          intstart
                                          intlength
                                          @@ -465,7 +465,7 @@
                                          Parameters
                                        diff --git a/docs/api/LiteNetLib.ConnectionState.html b/docs/api/LiteNetLib.ConnectionState.html index 95321853..58cf8461 100644 --- a/docs/api/LiteNetLib.ConnectionState.html +++ b/docs/api/LiteNetLib.ConnectionState.html @@ -130,7 +130,7 @@

                                        Fields

                                      diff --git a/docs/api/LiteNetLib.DeliveryMethod.html b/docs/api/LiteNetLib.DeliveryMethod.html index 96b966e1..26e918ca 100644 --- a/docs/api/LiteNetLib.DeliveryMethod.html +++ b/docs/api/LiteNetLib.DeliveryMethod.html @@ -131,7 +131,7 @@

                                      Fields

                                    diff --git a/docs/api/LiteNetLib.DisconnectInfo.html b/docs/api/LiteNetLib.DisconnectInfo.html index 045f9553..ff816c09 100644 --- a/docs/api/LiteNetLib.DisconnectInfo.html +++ b/docs/api/LiteNetLib.DisconnectInfo.html @@ -170,7 +170,7 @@
                                    Field Value
                                  diff --git a/docs/api/LiteNetLib.DisconnectReason.html b/docs/api/LiteNetLib.DisconnectReason.html index 44cb6e20..cce66c85 100644 --- a/docs/api/LiteNetLib.DisconnectReason.html +++ b/docs/api/LiteNetLib.DisconnectReason.html @@ -153,7 +153,7 @@

                                  Fields

                                diff --git a/docs/api/LiteNetLib.EventBasedNatPunchListener.html b/docs/api/LiteNetLib.EventBasedNatPunchListener.html index bda25ccb..bb1556bb 100644 --- a/docs/api/LiteNetLib.EventBasedNatPunchListener.html +++ b/docs/api/LiteNetLib.EventBasedNatPunchListener.html @@ -155,7 +155,7 @@

                                Implements

                              diff --git a/docs/api/LiteNetLib.EventBasedNetListener.html b/docs/api/LiteNetLib.EventBasedNetListener.html index a9ce1833..52dd610f 100644 --- a/docs/api/LiteNetLib.EventBasedNetListener.html +++ b/docs/api/LiteNetLib.EventBasedNetListener.html @@ -461,7 +461,7 @@

                              Implements

                            diff --git a/docs/api/LiteNetLib.IDeliveryEventListener.html b/docs/api/LiteNetLib.IDeliveryEventListener.html index 5675990e..45281858 100644 --- a/docs/api/LiteNetLib.IDeliveryEventListener.html +++ b/docs/api/LiteNetLib.IDeliveryEventListener.html @@ -127,7 +127,7 @@
                            Parameters
                          diff --git a/docs/api/LiteNetLib.INatPunchListener.html b/docs/api/LiteNetLib.INatPunchListener.html index 01ce3662..dfc3138f 100644 --- a/docs/api/LiteNetLib.INatPunchListener.html +++ b/docs/api/LiteNetLib.INatPunchListener.html @@ -168,7 +168,7 @@
                          Parameters
                        diff --git a/docs/api/LiteNetLib.INetEventListener.html b/docs/api/LiteNetLib.INetEventListener.html index dd5989ec..3e363606 100644 --- a/docs/api/LiteNetLib.INetEventListener.html +++ b/docs/api/LiteNetLib.INetEventListener.html @@ -345,7 +345,7 @@
                        Parameters
                      diff --git a/docs/api/LiteNetLib.INetLogger.html b/docs/api/LiteNetLib.INetLogger.html index 725cc3d8..03b29630 100644 --- a/docs/api/LiteNetLib.INetLogger.html +++ b/docs/api/LiteNetLib.INetLogger.html @@ -132,7 +132,7 @@
                      Parameters
                    diff --git a/docs/api/LiteNetLib.INtpEventListener.html b/docs/api/LiteNetLib.INtpEventListener.html index 5df04d5d..78b5e65a 100644 --- a/docs/api/LiteNetLib.INtpEventListener.html +++ b/docs/api/LiteNetLib.INtpEventListener.html @@ -122,7 +122,7 @@
                    Parameters
                  diff --git a/docs/api/LiteNetLib.IPeerAddressChangedListener.html b/docs/api/LiteNetLib.IPeerAddressChangedListener.html index 44c8a52d..2b3967cb 100644 --- a/docs/api/LiteNetLib.IPeerAddressChangedListener.html +++ b/docs/api/LiteNetLib.IPeerAddressChangedListener.html @@ -129,7 +129,7 @@
                  Parameters
                diff --git a/docs/api/LiteNetLib.IPv6Mode.html b/docs/api/LiteNetLib.IPv6Mode.html index dd9ea3be..8489a7c7 100644 --- a/docs/api/LiteNetLib.IPv6Mode.html +++ b/docs/api/LiteNetLib.IPv6Mode.html @@ -116,7 +116,7 @@

                Fields

              diff --git a/docs/api/LiteNetLib.InvalidPacketException.html b/docs/api/LiteNetLib.InvalidPacketException.html index 998fe148..aada234f 100644 --- a/docs/api/LiteNetLib.InvalidPacketException.html +++ b/docs/api/LiteNetLib.InvalidPacketException.html @@ -183,7 +183,7 @@

              Implements

            diff --git a/docs/api/LiteNetLib.Layers.Crc32cLayer.html b/docs/api/LiteNetLib.Layers.Crc32cLayer.html index ce524723..7c455bfd 100644 --- a/docs/api/LiteNetLib.Layers.Crc32cLayer.html +++ b/docs/api/LiteNetLib.Layers.Crc32cLayer.html @@ -201,7 +201,7 @@
            Overrides
          diff --git a/docs/api/LiteNetLib.Layers.PacketLayerBase.html b/docs/api/LiteNetLib.Layers.PacketLayerBase.html index e9e061bb..b111bbce 100644 --- a/docs/api/LiteNetLib.Layers.PacketLayerBase.html +++ b/docs/api/LiteNetLib.Layers.PacketLayerBase.html @@ -235,7 +235,7 @@
          Parameters
        diff --git a/docs/api/LiteNetLib.Layers.XorEncryptLayer.html b/docs/api/LiteNetLib.Layers.XorEncryptLayer.html index 9918dfd5..5a87e07b 100644 --- a/docs/api/LiteNetLib.Layers.XorEncryptLayer.html +++ b/docs/api/LiteNetLib.Layers.XorEncryptLayer.html @@ -309,7 +309,7 @@
        Parameters
      diff --git a/docs/api/LiteNetLib.Layers.html b/docs/api/LiteNetLib.Layers.html index b9224a06..2ca81449 100644 --- a/docs/api/LiteNetLib.Layers.html +++ b/docs/api/LiteNetLib.Layers.html @@ -74,7 +74,8 @@

      Names
      -

      Classes +

      +Classes

      Crc32cLayer

      @@ -94,7 +95,7 @@

      XorEncryptLaye

    diff --git a/docs/api/LiteNetLib.LocalAddrType.html b/docs/api/LiteNetLib.LocalAddrType.html index 7f4ccb85..78f95986 100644 --- a/docs/api/LiteNetLib.LocalAddrType.html +++ b/docs/api/LiteNetLib.LocalAddrType.html @@ -118,7 +118,7 @@

    Fields

diff --git a/docs/api/LiteNetLib.NatAddressType.html b/docs/api/LiteNetLib.NatAddressType.html index 3a72ed78..ed5969fd 100644 --- a/docs/api/LiteNetLib.NatAddressType.html +++ b/docs/api/LiteNetLib.NatAddressType.html @@ -112,7 +112,7 @@

Fields diff --git a/docs/api/LiteNetLib.NatPunchModule.html b/docs/api/LiteNetLib.NatPunchModule.html index d6f0eb40..185ac2f0 100644 --- a/docs/api/LiteNetLib.NatPunchModule.html +++ b/docs/api/LiteNetLib.NatPunchModule.html @@ -304,7 +304,7 @@

Parameters
diff --git a/docs/api/LiteNetLib.NetConstants.html b/docs/api/LiteNetLib.NetConstants.html index 67a78ace..075c478b 100644 --- a/docs/api/LiteNetLib.NetConstants.html +++ b/docs/api/LiteNetLib.NetConstants.html @@ -139,12 +139,12 @@
Field Value
-

FragmentedHeaderTotalSize

+

FragmentHeaderSize

Declaration
-
public const int FragmentedHeaderTotalSize = 10
+
public const int FragmentHeaderSize = 6
Field Value
@@ -163,12 +163,12 @@
Field Value
-

FragmentHeaderSize

+

FragmentedHeaderTotalSize

Declaration
-
public const int FragmentHeaderSize = 6
+
public const int FragmentedHeaderTotalSize = 10
Field Value
@@ -388,7 +388,7 @@
Field Value
diff --git a/docs/api/LiteNetLib.NetDebug.html b/docs/api/LiteNetLib.NetDebug.html index e89dfa84..9cef6dac 100644 --- a/docs/api/LiteNetLib.NetDebug.html +++ b/docs/api/LiteNetLib.NetDebug.html @@ -125,7 +125,7 @@
Field Value
diff --git a/docs/api/LiteNetLib.NetLogLevel.html b/docs/api/LiteNetLib.NetLogLevel.html index db1fd024..61298f6c 100644 --- a/docs/api/LiteNetLib.NetLogLevel.html +++ b/docs/api/LiteNetLib.NetLogLevel.html @@ -120,7 +120,7 @@

Fields diff --git a/docs/api/LiteNetLib.NetManager.NetPeerEnumerator.html b/docs/api/LiteNetLib.NetManager.NetPeerEnumerator.html index fcb2c4d9..729887a2 100644 --- a/docs/api/LiteNetLib.NetManager.NetPeerEnumerator.html +++ b/docs/api/LiteNetLib.NetManager.NetPeerEnumerator.html @@ -122,7 +122,8 @@

Properties

Current

-
+

Gets the element in the collection at the current position of the enumerator.

+
Declaration
@@ -139,7 +140,8 @@
Property Value
- +
NetPeer

The element in the collection at the current position of the enumerator.

+
@@ -160,7 +162,8 @@
Declaration

MoveNext()

-
+

Advances the enumerator to the next element of the collection.

+
Declaration
@@ -177,7 +180,24 @@
Returns
bool - +

true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection.

+ + + + +
Exceptions
+ + + + + + + + + + +
TypeCondition
InvalidOperationException

The collection was modified after the enumerator was created.

+
@@ -185,12 +205,29 @@
Returns

Reset()

-
+

Sets the enumerator to its initial position, which is before the first element in the collection.

+
Declaration
public void Reset()
+
Exceptions
+ + + + + + + + + + + + + +
TypeCondition
InvalidOperationException

The collection was modified after the enumerator was created.

+

Implements

IEnumerator<T> @@ -212,7 +249,7 @@

Implements

diff --git a/docs/api/LiteNetLib.NetManager.html b/docs/api/LiteNetLib.NetManager.html index ffd90695..27c74cd4 100644 --- a/docs/api/LiteNetLib.NetManager.html +++ b/docs/api/LiteNetLib.NetManager.html @@ -1458,13 +1458,13 @@
Parameters
-

CreateNtpRequest(string, int)

-

Create the requests for NTP server

+

CreateNtpRequest(string)

+

Create the requests for NTP server (default port)

Declaration
-
public void CreateNtpRequest(string ntpServerAddress, int port)
+
public void CreateNtpRequest(string ntpServerAddress)
Parameters
@@ -1480,12 +1480,6 @@
Parameters
- - - - - @@ -1493,13 +1487,13 @@
Parameters
-

CreateNtpRequest(string)

-

Create the requests for NTP server (default port)

+

CreateNtpRequest(string, int)

+

Create the requests for NTP server

Declaration
-
public void CreateNtpRequest(string ntpServerAddress)
+
public void CreateNtpRequest(string ntpServerAddress, int port)
Parameters
string ntpServerAddress

NTP Server address.

-
intport

port

@@ -1515,6 +1509,12 @@
Parameters
+ + + + + @@ -1574,13 +1574,13 @@
Parameters
-

DisconnectPeer(NetPeer, NetDataWriter)

-

Disconnect peer from server and send additional data (Size must be less or equal MTU - 8)

+

DisconnectPeer(NetPeer)

+

Disconnect peer from server

Declaration
-
public void DisconnectPeer(NetPeer peer, NetDataWriter writer)
+
public void DisconnectPeer(NetPeer peer)
Parameters
string ntpServerAddress

NTP Server address.

+
intport

port

@@ -1596,12 +1596,6 @@
Parameters
- - - - - @@ -1609,13 +1603,13 @@
Parameters
-

DisconnectPeer(NetPeer, byte[], int, int)

+

DisconnectPeer(NetPeer, NetDataWriter)

Disconnect peer from server and send additional data (Size must be less or equal MTU - 8)

Declaration
-
public void DisconnectPeer(NetPeer peer, byte[] data, int start, int count)
+
public void DisconnectPeer(NetPeer peer, NetDataWriter writer)
Parameters
NetPeer peer

peer to disconnect

-
NetDataWriterwriter

additional data

@@ -1634,21 +1628,9 @@
Parameters
- - + + - - - - - - - - - - @@ -1691,13 +1673,13 @@
Parameters
-

DisconnectPeer(NetPeer)

-

Disconnect peer from server

+

DisconnectPeer(NetPeer, byte[], int, int)

+

Disconnect peer from server and send additional data (Size must be less or equal MTU - 8)

Declaration
-
public void DisconnectPeer(NetPeer peer)
+
public void DisconnectPeer(NetPeer peer, byte[] data, int start, int count)
Parameters
byte[]dataNetDataWriterwriter

additional data

-
intstart

data start

-
intcount

data length

@@ -1713,6 +1695,24 @@
Parameters
+ + + + + + + + + + + + + + + @@ -1987,12 +1987,12 @@
Returns
-

SendBroadcast(byte[], int, int, int)

+

SendBroadcast(byte[], int)

Declaration
-
public bool SendBroadcast(byte[] data, int start, int length, int port)
+
public bool SendBroadcast(byte[] data, int port)
Parameters
NetPeer peer

peer to disconnect

+
byte[]data

additional data

+
intstart

data start

+
intcount

data length

@@ -2009,16 +2009,6 @@
Parameters
- - - - - - - - - - @@ -2044,12 +2034,12 @@
Returns
-

SendBroadcast(byte[], int)

+

SendBroadcast(byte[], int, int, int)

Declaration
-
public bool SendBroadcast(byte[] data, int port)
+
public bool SendBroadcast(byte[] data, int start, int length, int port)
Parameters
data
intstart
intlength
int port
@@ -2066,6 +2056,16 @@
Parameters
+ + + + + + + + + + @@ -2091,13 +2091,13 @@
Returns
-

SendToAll(NetDataWriter, DeliveryMethod, NetPeer)

+

SendToAll(NetDataWriter, DeliveryMethod)

Send data to all connected peers (channel - 0)

Declaration
-
public void SendToAll(NetDataWriter writer, DeliveryMethod options, NetPeer excludePeer)
+
public void SendToAll(NetDataWriter writer, DeliveryMethod options)
Parameters
data
intstart
intlength
int port
@@ -2119,12 +2119,6 @@
Parameters
- - - - - @@ -2132,13 +2126,13 @@
Parameters
-

SendToAll(NetDataWriter, DeliveryMethod)

+

SendToAll(NetDataWriter, DeliveryMethod, NetPeer)

Send data to all connected peers (channel - 0)

Declaration
-
public void SendToAll(NetDataWriter writer, DeliveryMethod options)
+
public void SendToAll(NetDataWriter writer, DeliveryMethod options, NetPeer excludePeer)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

-
NetPeerexcludePeer

Excluded peer

@@ -2160,6 +2154,12 @@
Parameters
+ + + + + @@ -2167,13 +2167,13 @@
Parameters
-

SendToAll(NetDataWriter, byte, DeliveryMethod, NetPeer)

+

SendToAll(NetDataWriter, byte, DeliveryMethod)

Send data to all connected peers

Declaration
-
public void SendToAll(NetDataWriter writer, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
+
public void SendToAll(NetDataWriter writer, byte channelNumber, DeliveryMethod options)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

+
NetPeerexcludePeer

Excluded peer

@@ -2201,12 +2201,6 @@
Parameters
- - - - - @@ -2214,13 +2208,13 @@
Parameters
-

SendToAll(NetDataWriter, byte, DeliveryMethod)

+

SendToAll(NetDataWriter, byte, DeliveryMethod, NetPeer)

Send data to all connected peers

Declaration
-
public void SendToAll(NetDataWriter writer, byte channelNumber, DeliveryMethod options)
+
public void SendToAll(NetDataWriter writer, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

-
NetPeerexcludePeer

Excluded peer

@@ -2248,6 +2242,12 @@
Parameters
+ + + + + @@ -2255,13 +2255,13 @@
Parameters
-

SendToAll(byte[], DeliveryMethod, NetPeer)

+

SendToAll(byte[], DeliveryMethod)

Send data to all connected peers (channel - 0)

Declaration
-
public void SendToAll(byte[] data, DeliveryMethod options, NetPeer excludePeer)
+
public void SendToAll(byte[] data, DeliveryMethod options)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

+
NetPeerexcludePeer

Excluded peer

@@ -2283,12 +2283,6 @@
Parameters
- - - - - @@ -2296,13 +2290,13 @@
Parameters
-

SendToAll(byte[], DeliveryMethod)

+

SendToAll(byte[], DeliveryMethod, NetPeer)

Send data to all connected peers (channel - 0)

Declaration
-
public void SendToAll(byte[] data, DeliveryMethod options)
+
public void SendToAll(byte[] data, DeliveryMethod options, NetPeer excludePeer)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

-
NetPeerexcludePeer

Excluded peer

@@ -2324,6 +2318,12 @@
Parameters
+ + + + + @@ -2331,13 +2331,13 @@
Parameters
-

SendToAll(byte[], byte, DeliveryMethod, NetPeer)

+

SendToAll(byte[], byte, DeliveryMethod)

Send data to all connected peers

Declaration
-
public void SendToAll(byte[] data, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
+
public void SendToAll(byte[] data, byte channelNumber, DeliveryMethod options)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

+
NetPeerexcludePeer

Excluded peer

@@ -2365,12 +2365,6 @@
Parameters
- - - - - @@ -2378,13 +2372,13 @@
Parameters
-

SendToAll(byte[], byte, DeliveryMethod)

+

SendToAll(byte[], byte, DeliveryMethod, NetPeer)

Send data to all connected peers

Declaration
-
public void SendToAll(byte[] data, byte channelNumber, DeliveryMethod options)
+
public void SendToAll(byte[] data, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

-
NetPeerexcludePeer

Excluded peer

@@ -2412,6 +2406,12 @@
Parameters
+ + + + + @@ -2419,13 +2419,13 @@
Parameters
-

SendToAll(byte[], int, int, DeliveryMethod, NetPeer)

+

SendToAll(byte[], int, int, DeliveryMethod)

Send data to all connected peers (channel - 0)

Declaration
-
public void SendToAll(byte[] data, int start, int length, DeliveryMethod options, NetPeer excludePeer)
+
public void SendToAll(byte[] data, int start, int length, DeliveryMethod options)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

+
NetPeerexcludePeer

Excluded peer

@@ -2459,12 +2459,6 @@
Parameters
- - - - - @@ -2472,13 +2466,13 @@
Parameters
-

SendToAll(byte[], int, int, DeliveryMethod)

+

SendToAll(byte[], int, int, DeliveryMethod, NetPeer)

Send data to all connected peers (channel - 0)

Declaration
-
public void SendToAll(byte[] data, int start, int length, DeliveryMethod options)
+
public void SendToAll(byte[] data, int start, int length, DeliveryMethod options, NetPeer excludePeer)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

-
NetPeerexcludePeer

Excluded peer

@@ -2512,6 +2506,12 @@
Parameters
+ + + + + @@ -2519,13 +2519,13 @@
Parameters
-

SendToAll(byte[], int, int, byte, DeliveryMethod, NetPeer)

+

SendToAll(byte[], int, int, byte, DeliveryMethod)

Send data to all connected peers

Declaration
-
public void SendToAll(byte[] data, int start, int length, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
+
public void SendToAll(byte[] data, int start, int length, byte channelNumber, DeliveryMethod options)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

+
NetPeerexcludePeer

Excluded peer

@@ -2565,12 +2565,6 @@
Parameters
- - - - - @@ -2578,13 +2572,13 @@
Parameters
-

SendToAll(byte[], int, int, byte, DeliveryMethod)

+

SendToAll(byte[], int, int, byte, DeliveryMethod, NetPeer)

Send data to all connected peers

Declaration
-
public void SendToAll(byte[] data, int start, int length, byte channelNumber, DeliveryMethod options)
+
public void SendToAll(byte[] data, int start, int length, byte channelNumber, DeliveryMethod options, NetPeer excludePeer)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

-
NetPeerexcludePeer

Excluded peer

@@ -2624,6 +2618,12 @@
Parameters
+ + + + + @@ -2631,13 +2631,13 @@
Parameters
-

SendToAll(ReadOnlySpan<byte>, DeliveryMethod, NetPeer)

+

SendToAll(ReadOnlySpan<byte>, DeliveryMethod)

Send data to all connected peers (channel - 0)

Declaration
-
public void SendToAll(ReadOnlySpan<byte> data, DeliveryMethod options, NetPeer excludePeer)
+
public void SendToAll(ReadOnlySpan<byte> data, DeliveryMethod options)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

+
NetPeerexcludePeer

Excluded peer

@@ -2659,12 +2659,6 @@
Parameters
- - - - - @@ -2672,13 +2666,13 @@
Parameters
-

SendToAll(ReadOnlySpan<byte>, DeliveryMethod)

+

SendToAll(ReadOnlySpan<byte>, DeliveryMethod, NetPeer)

Send data to all connected peers (channel - 0)

Declaration
-
public void SendToAll(ReadOnlySpan<byte> data, DeliveryMethod options)
+
public void SendToAll(ReadOnlySpan<byte> data, DeliveryMethod options, NetPeer excludePeer)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

-
NetPeerexcludePeer

Excluded peer

@@ -2700,6 +2694,12 @@
Parameters
+ + + + + @@ -3048,13 +3048,13 @@
Returns
-

Start(IPAddress, IPAddress, int, bool)

+

Start(IPAddress, IPAddress, int)

Start logic thread and listening on selected port

Declaration
-
public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode)
+
public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port)
Parameters
DeliveryMethod options

Send options (reliable, unreliable, etc.)

+
NetPeerexcludePeer

Excluded peer

@@ -3082,12 +3082,6 @@
Parameters
- - - - - @@ -3110,13 +3104,13 @@
Returns
-

Start(IPAddress, IPAddress, int)

+

Start(IPAddress, IPAddress, int, bool)

Start logic thread and listening on selected port

Declaration
-
public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port)
+
public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode)
Parameters
int port

port to listen

-
boolmanualMode

mode of library

@@ -3144,6 +3138,12 @@
Parameters
+ + + + + @@ -3504,7 +3504,7 @@

Implements

diff --git a/docs/api/LiteNetLib.NetPacketReader.html b/docs/api/LiteNetLib.NetPacketReader.html index 00602912..87cf9b13 100644 --- a/docs/api/LiteNetLib.NetPacketReader.html +++ b/docs/api/LiteNetLib.NetPacketReader.html @@ -404,7 +404,7 @@
Declaration
diff --git a/docs/api/LiteNetLib.NetPeer.html b/docs/api/LiteNetLib.NetPeer.html index 40b7f38e..5539d422 100644 --- a/docs/api/LiteNetLib.NetPeer.html +++ b/docs/api/LiteNetLib.NetPeer.html @@ -522,12 +522,12 @@
Parameters
-

Disconnect(byte[], int, int)

+

Disconnect(byte[])

Declaration
-
public void Disconnect(byte[] data, int start, int count)
+
public void Disconnect(byte[] data)
Parameters
int port

port to listen

+
boolmanualMode

mode of library

@@ -544,27 +544,17 @@
Parameters
- - - - - - - - - -
data
intstart
intcount
-

Disconnect(byte[])

+

Disconnect(byte[], int, int)

Declaration
-
public void Disconnect(byte[] data)
+
public void Disconnect(byte[] data, int start, int count)
Parameters
@@ -581,13 +571,24 @@
Parameters
+ + + + + + + + + +
data
intstart
intcount

GetHashCode()

-
+

Returns a hash value for a IPEndPoint instance.

+
Declaration
@@ -604,7 +605,8 @@
Returns
int - +

An integer hash value.

+ @@ -1517,7 +1519,7 @@
Overrides
diff --git a/docs/api/LiteNetLib.NetStatistics.html b/docs/api/LiteNetLib.NetStatistics.html index 467a448d..3283b0bf 100644 --- a/docs/api/LiteNetLib.NetStatistics.html +++ b/docs/api/LiteNetLib.NetStatistics.html @@ -365,7 +365,8 @@
Declaration

ToString()

-
+

Returns a string that represents the current object.

+
Declaration
@@ -382,7 +383,8 @@
Returns
string - +

A string that represents the current object.

+ @@ -399,7 +401,7 @@
Overrides
diff --git a/docs/api/LiteNetLib.NetUtils.html b/docs/api/LiteNetLib.NetUtils.html index a982d647..acb748f6 100644 --- a/docs/api/LiteNetLib.NetUtils.html +++ b/docs/api/LiteNetLib.NetUtils.html @@ -264,12 +264,12 @@
Returns
-

ResolveAddress(string, AddressFamily)

+

ResolveAddress(string)

Declaration
-
public static IPAddress ResolveAddress(string hostStr, AddressFamily addressFamily)
+
public static IPAddress ResolveAddress(string hostStr)
Parameters
@@ -286,11 +286,6 @@
Parameters
- - - - -
hostStr
AddressFamilyaddressFamily
Returns
@@ -311,12 +306,12 @@
Returns
-

ResolveAddress(string)

+

ResolveAddress(string, AddressFamily)

Declaration
-
public static IPAddress ResolveAddress(string hostStr)
+
public static IPAddress ResolveAddress(string hostStr, AddressFamily addressFamily)
Parameters
@@ -333,6 +328,11 @@
Parameters
+ + + + +
hostStr
AddressFamilyaddressFamily
Returns
@@ -361,7 +361,7 @@
Returns
diff --git a/docs/api/LiteNetLib.PooledPacket.html b/docs/api/LiteNetLib.PooledPacket.html index abe69e6e..23467e19 100644 --- a/docs/api/LiteNetLib.PooledPacket.html +++ b/docs/api/LiteNetLib.PooledPacket.html @@ -172,7 +172,7 @@
Property Value
diff --git a/docs/api/LiteNetLib.TooBigPacketException.html b/docs/api/LiteNetLib.TooBigPacketException.html index e693f28b..48c940da 100644 --- a/docs/api/LiteNetLib.TooBigPacketException.html +++ b/docs/api/LiteNetLib.TooBigPacketException.html @@ -183,7 +183,7 @@

Implements

diff --git a/docs/api/LiteNetLib.UnconnectedMessageType.html b/docs/api/LiteNetLib.UnconnectedMessageType.html index f1d4a9c8..65865180 100644 --- a/docs/api/LiteNetLib.UnconnectedMessageType.html +++ b/docs/api/LiteNetLib.UnconnectedMessageType.html @@ -113,7 +113,7 @@

Fields diff --git a/docs/api/LiteNetLib.Utils.CRC32C.html b/docs/api/LiteNetLib.Utils.CRC32C.html index bf01f7aa..86671d66 100644 --- a/docs/api/LiteNetLib.Utils.CRC32C.html +++ b/docs/api/LiteNetLib.Utils.CRC32C.html @@ -182,7 +182,7 @@

Returns
diff --git a/docs/api/LiteNetLib.Utils.FastBitConverter.html b/docs/api/LiteNetLib.Utils.FastBitConverter.html index 13a8c291..7745f3d6 100644 --- a/docs/api/LiteNetLib.Utils.FastBitConverter.html +++ b/docs/api/LiteNetLib.Utils.FastBitConverter.html @@ -151,7 +151,7 @@
Type Parameters
diff --git a/docs/api/LiteNetLib.Utils.INetSerializable.html b/docs/api/LiteNetLib.Utils.INetSerializable.html index b01448e3..5c3316db 100644 --- a/docs/api/LiteNetLib.Utils.INetSerializable.html +++ b/docs/api/LiteNetLib.Utils.INetSerializable.html @@ -148,7 +148,7 @@
Parameters
diff --git a/docs/api/LiteNetLib.Utils.InvalidTypeException.html b/docs/api/LiteNetLib.Utils.InvalidTypeException.html index e7b08274..0f00ff1d 100644 --- a/docs/api/LiteNetLib.Utils.InvalidTypeException.html +++ b/docs/api/LiteNetLib.Utils.InvalidTypeException.html @@ -182,7 +182,7 @@

Implements

diff --git a/docs/api/LiteNetLib.Utils.NetDataReader.html b/docs/api/LiteNetLib.Utils.NetDataReader.html index 75e15722..253c3d14 100644 --- a/docs/api/LiteNetLib.Utils.NetDataReader.html +++ b/docs/api/LiteNetLib.Utils.NetDataReader.html @@ -129,12 +129,12 @@
Parameters
-

NetDataReader(byte[], int, int)

+

NetDataReader(byte[])

Declaration
-
public NetDataReader(byte[] source, int offset, int maxSize)
+
public NetDataReader(byte[] source)
Parameters
@@ -151,27 +151,17 @@
Parameters
- - - - - - - - - -
source
intoffset
intmaxSize
-

NetDataReader(byte[])

+

NetDataReader(byte[], int, int)

Declaration
-
public NetDataReader(byte[] source)
+
public NetDataReader(byte[] source, int offset, int maxSize)
Parameters
@@ -188,6 +178,16 @@
Parameters
+ + + + + + + + + +
source
intoffset
intmaxSize

Fields @@ -751,12 +751,12 @@

Parameters
-

Get(out string, int)

+

Get(out string)

Declaration
-
public void Get(out string result, int maxLength)
+
public void Get(out string result)
Parameters
@@ -773,22 +773,17 @@
Parameters
- - - - -
result
intmaxLength
-

Get(out string)

+

Get(out string, int)

Declaration
-
public void Get(out string result)
+
public void Get(out string result, int maxLength)
Parameters
@@ -805,6 +800,11 @@
Parameters
+ + + + +
result
intmaxLength
@@ -890,192 +890,6 @@
Parameters
- -

Get<T>()

-
-
-
Declaration
-
-
public T Get<T>() where T : struct, INetSerializable
-
-
Returns
- - - - - - - - - - - - - -
TypeDescription
T
-
Type Parameters
- - - - - - - - - - - - - -
NameDescription
T
- - - -

Get<T>(out T, Func<T>)

-
-
-
Declaration
-
-
public void Get<T>(out T result, Func<T> constructor) where T : class, INetSerializable
-
-
Parameters
- - - - - - - - - - - - - - - - - - - - -
TypeNameDescription
Tresult
Func<T>constructor
-
Type Parameters
- - - - - - - - - - - - - -
NameDescription
T
- - - -

Get<T>(out T)

-
-
-
Declaration
-
-
public void Get<T>(out T result) where T : struct, INetSerializable
-
-
Parameters
- - - - - - - - - - - - - - - -
TypeNameDescription
Tresult
-
Type Parameters
- - - - - - - - - - - - - -
NameDescription
T
- - - -

Get<T>(Func<T>)

-
-
-
Declaration
-
-
public T Get<T>(Func<T> constructor) where T : class, INetSerializable
-
-
Parameters
- - - - - - - - - - - - - - - -
TypeNameDescription
Func<T>constructor
-
Returns
- - - - - - - - - - - - - -
TypeDescription
T
-
Type Parameters
- - - - - - - - - - - - - -
NameDescription
T
- -

GetArray<T>(ushort)

@@ -1209,12 +1023,12 @@
Returns
-

GetBytes(byte[], int, int)

+

GetBytes(byte[], int)

Declaration
-
public void GetBytes(byte[] destination, int start, int count)
+
public void GetBytes(byte[] destination, int count)
Parameters
@@ -1231,11 +1045,6 @@
Parameters
- - - - - @@ -1246,12 +1055,12 @@
Parameters
-

GetBytes(byte[], int)

+

GetBytes(byte[], int, int)

Declaration
-
public void GetBytes(byte[] destination, int count)
+
public void GetBytes(byte[] destination, int start, int count)
Parameters
destination
intstart
int count
@@ -1268,6 +1077,11 @@
Parameters
+ + + + + @@ -2057,6 +1871,192 @@
Returns
destination
intstart
int count
+ +

Get<T>()

+
+
+
Declaration
+
+
public T Get<T>() where T : struct, INetSerializable
+
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
T
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T
+ + + +

Get<T>(Func<T>)

+
+
+
Declaration
+
+
public T Get<T>(Func<T> constructor) where T : class, INetSerializable
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
Func<T>constructor
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
T
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T
+ + + +

Get<T>(out T)

+
+
+
Declaration
+
+
public void Get<T>(out T result) where T : struct, INetSerializable
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
Tresult
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T
+ + + +

Get<T>(out T, Func<T>)

+
+
+
Declaration
+
+
public void Get<T>(out T result, Func<T> constructor) where T : class, INetSerializable
+
+
Parameters
+ + + + + + + + + + + + + + + + + + + + +
TypeNameDescription
Tresult
Func<T>constructor
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T
+ +

PeekBool()

@@ -2480,12 +2480,12 @@
Parameters
-

SetSource(byte[], int, int)

+

SetSource(byte[])

Declaration
-
public void SetSource(byte[] source, int offset, int maxSize)
+
public void SetSource(byte[] source)
Parameters
@@ -2502,27 +2502,17 @@
Parameters
- - - - - - - - - -
source
intoffset
intmaxSize
-

SetSource(byte[])

+

SetSource(byte[], int, int)

Declaration
-
public void SetSource(byte[] source)
+
public void SetSource(byte[] source, int offset, int maxSize)
Parameters
@@ -2539,6 +2529,16 @@
Parameters
+ + + + + + + + + +
source
intoffset
intmaxSize
@@ -3209,7 +3209,7 @@
Returns
diff --git a/docs/api/LiteNetLib.Utils.NetDataWriter.html b/docs/api/LiteNetLib.Utils.NetDataWriter.html index ad9fd94a..93719d42 100644 --- a/docs/api/LiteNetLib.Utils.NetDataWriter.html +++ b/docs/api/LiteNetLib.Utils.NetDataWriter.html @@ -101,12 +101,12 @@
Declaration
-

NetDataWriter(bool, int)

+

NetDataWriter(bool)

Declaration
-
public NetDataWriter(bool autoResize, int initialSize)
+
public NetDataWriter(bool autoResize)
Parameters
@@ -123,22 +123,17 @@
Parameters
- - - - -
autoResize
intinitialSize
-

NetDataWriter(bool)

+

NetDataWriter(bool, int)

Declaration
-
public NetDataWriter(bool autoResize)
+
public NetDataWriter(bool autoResize, int initialSize)
Parameters
@@ -155,18 +150,23 @@
Parameters
+ + + + +
autoResize
intinitialSize

Fields

-

_data

+

StringBufferMaxLength

Declaration
-
protected byte[] _data
+
public const int StringBufferMaxLength = 65535
Field Value
@@ -178,19 +178,19 @@
Field Value
- +
byte[]int
-

_position

+

_data

Declaration
-
protected int _position
+
protected byte[] _data
Field Value
@@ -202,19 +202,19 @@
Field Value
- +
intbyte[]
-

StringBufferMaxLength

+

_position

Declaration
-
public const int StringBufferMaxLength = 65535
+
protected int _position
Field Value
@@ -591,12 +591,12 @@
Parameters
-

Put(byte[], int, int)

+

Put(byte[])

Declaration
-
public void Put(byte[] data, int offset, int length)
+
public void Put(byte[] data)
Parameters
@@ -613,27 +613,17 @@
Parameters
- - - - - - - - - -
data
intoffset
intlength
-

Put(byte[])

+

Put(byte[], int, int)

Declaration
-
public void Put(byte[] data)
+
public void Put(byte[] data, int offset, int length)
Parameters
@@ -650,6 +640,16 @@
Parameters
+ + + + + + + + + +
data
intoffset
intlength
@@ -871,13 +871,12 @@
Parameters
-

Put(string, int)

-

Note that "maxLength" only limits the number of characters in a string, not its size in bytes.

-
+

Put(string)

+
Declaration
-
public void Put(string value, int maxLength)
+
public void Put(string value)
Parameters
@@ -894,22 +893,18 @@
Parameters
- - - - -
value
intmaxLength
-

Put(string)

-
+

Put(string, int)

+

Note that "maxLength" only limits the number of characters in a string, not its size in bytes.

+
Declaration
-
public void Put(string value)
+
public void Put(string value, int maxLength)
Parameters
@@ -926,6 +921,11 @@
Parameters
+ + + + +
value
intmaxLength
@@ -1011,48 +1011,6 @@
Parameters
- -

Put<T>(T)

-
-
-
Declaration
-
-
public void Put<T>(T obj) where T : INetSerializable
-
-
Parameters
- - - - - - - - - - - - - - - -
TypeNameDescription
Tobj
-
Type Parameters
- - - - - - - - - - - - - -
NameDescription
T
- -

PutArray(Array, int)

@@ -1248,12 +1206,12 @@
Parameters
-

PutArray(string[], int)

+

PutArray(string[])

Declaration
-
public void PutArray(string[] value, int strMaxLength)
+
public void PutArray(string[] value)
Parameters
@@ -1270,22 +1228,17 @@
Parameters
- - - - -
value
intstrMaxLength
-

PutArray(string[])

+

PutArray(string[], int)

Declaration
-
public void PutArray(string[] value)
+
public void PutArray(string[] value, int strMaxLength)
Parameters
@@ -1302,6 +1255,11 @@
Parameters
+ + + + +
value
intstrMaxLength
@@ -1387,6 +1345,33 @@
Parameters
+ +

PutBytesWithLength(byte[])

+
+
+
Declaration
+
+
public void PutBytesWithLength(byte[] data)
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
byte[]data
+ +

PutBytesWithLength(byte[], int, ushort)

@@ -1424,13 +1409,13 @@
Parameters
- -

PutBytesWithLength(byte[])

+ +

PutSBytesWithLength(sbyte[])

Declaration
-
public void PutBytesWithLength(byte[] data)
+
public void PutSBytesWithLength(sbyte[] data)
Parameters
@@ -1443,7 +1428,7 @@
Parameters
- + @@ -1488,13 +1473,13 @@
Parameters
byte[]sbyte[] data
- -

PutSBytesWithLength(sbyte[])

+ +

Put<T>(T)

Declaration
-
public void PutSBytesWithLength(sbyte[] data)
+
public void Put<T>(T obj) where T : INetSerializable
Parameters
@@ -1507,8 +1492,23 @@
Parameters
- - + + + + + +
sbyte[]dataTobj
+
Type Parameters
+ + + + + + + + + + @@ -1633,7 +1633,7 @@
Returns
diff --git a/docs/api/LiteNetLib.Utils.NetPacketProcessor.html b/docs/api/LiteNetLib.Utils.NetPacketProcessor.html index d15f536d..c49f91fc 100644 --- a/docs/api/LiteNetLib.Utils.NetPacketProcessor.html +++ b/docs/api/LiteNetLib.Utils.NetPacketProcessor.html @@ -212,13 +212,13 @@
Type Parameters
-

ReadAllPackets(NetDataReader, object)

+

ReadAllPackets(NetDataReader)

Reads all available data from NetDataReader and calls OnReceive delegates

Declaration
-
public void ReadAllPackets(NetDataReader reader, object userData)
+
public void ReadAllPackets(NetDataReader reader)
Parameters
NameDescription
T
@@ -234,28 +234,6 @@
Parameters
- - - - - - - -
NetDataReader reader

NetDataReader with packets data

-
objectuserData

Argument that passed to OnReceivedEvent

-
-
Exceptions
- - - - - - - - - - - @@ -263,13 +241,13 @@
Exceptions
-

ReadAllPackets(NetDataReader)

+

ReadAllPackets(NetDataReader, object)

Reads all available data from NetDataReader and calls OnReceive delegates

Declaration
-
public void ReadAllPackets(NetDataReader reader)
+
public void ReadAllPackets(NetDataReader reader, object userData)
Parameters
TypeCondition
ParseException

Malformed packet

@@ -285,6 +263,28 @@
Parameters
+ + + + + + + +
NetDataReader reader

NetDataReader with packets data

+
objectuserData

Argument that passed to OnReceivedEvent

+
+
Exceptions
+ + + + + + + + + + + @@ -292,13 +292,13 @@
Parameters
-

ReadPacket(NetDataReader, object)

+

ReadPacket(NetDataReader)

Reads one packet from NetDataReader and calls OnReceive delegate

Declaration
-
public void ReadPacket(NetDataReader reader, object userData)
+
public void ReadPacket(NetDataReader reader)
Parameters
TypeCondition
ParseException

Malformed packet

@@ -314,12 +314,6 @@
Parameters
- - - - - @@ -343,13 +337,13 @@
Exceptions
-

ReadPacket(NetDataReader)

+

ReadPacket(NetDataReader, object)

Reads one packet from NetDataReader and calls OnReceive delegate

Declaration
-
public void ReadPacket(NetDataReader reader)
+
public void ReadPacket(NetDataReader reader, object userData)
Parameters
NetDataReader reader

NetDataReader with packet

-
objectuserData

Argument that passed to OnReceivedEvent

@@ -365,6 +359,12 @@
Parameters
+ + + + + @@ -549,14 +549,13 @@
Type Parameters
NetDataReader reader

NetDataReader with packet

+
objectuserData

Argument that passed to OnReceivedEvent

- -

Subscribe<T>(Action<T>, Func<T>)

-

Register and subscribe to packet receive event

-
+ +

SubscribeNetSerializable<T>(Action<T>)

+
Declaration
-
public void Subscribe<T>(Action<T> onReceive, Func<T> packetConstructor) where T : class, new()
+
public void SubscribeNetSerializable<T>(Action<T> onReceive) where T : INetSerializable, new()
Parameters
@@ -571,14 +570,7 @@
Parameters
- - - - - - +
Action<T> onReceive

event that will be called when packet deserialized with ReadPacket method

-
Func<T>packetConstructor

Method that constructs packet instead of slow Activator.CreateInstance

-
@@ -597,32 +589,15 @@
Type Parameters
-
Exceptions
- - - - - - - - - - - - - -
TypeCondition
InvalidTypeException

T's fields are not supported, or it has no fields

-
- -

Subscribe<T, TUserData>(Action<T, TUserData>, Func<T>)

-

Register and subscribe to packet receive event (with userData)

-
+ +

SubscribeNetSerializable<T>(Action<T>, Func<T>)

+
Declaration
-
public void Subscribe<T, TUserData>(Action<T, TUserData> onReceive, Func<T> packetConstructor) where T : class, new()
+
public void SubscribeNetSerializable<T>(Action<T> onReceive, Func<T> packetConstructor) where T : INetSerializable
Parameters
@@ -635,16 +610,14 @@
Parameters
- + - + - +
Action<T, TUserData>Action<T> onReceive

event that will be called when packet deserialized with ReadPacket method

-
Func<T> packetConstructor

Method that constructs packet instead of slow Activator.CreateInstance

-
@@ -661,37 +634,17 @@
Type Parameters
T - - TUserData - - - - -
Exceptions
- - - - - - - - - - - -
TypeCondition
InvalidTypeException

T's fields are not supported, or it has no fields

-
-

SubscribeNetSerializable<T>(Action<T>, Func<T>)

+

SubscribeNetSerializable<T, TUserData>(Action<T, TUserData>)

Declaration
-
public void SubscribeNetSerializable<T>(Action<T> onReceive, Func<T> packetConstructor) where T : INetSerializable
+
public void SubscribeNetSerializable<T, TUserData>(Action<T, TUserData> onReceive) where T : INetSerializable, new()
Parameters
@@ -704,15 +657,10 @@
Parameters
- + - - - - -
Action<T>Action<T, TUserData> onReceive
Func<T>packetConstructor
Type Parameters
@@ -728,17 +676,21 @@
Type Parameters
T + + TUserData + + -

SubscribeNetSerializable<T>(Action<T>)

+

SubscribeNetSerializable<T, TUserData>(Action<T, TUserData>, Func<T>)

Declaration
-
public void SubscribeNetSerializable<T>(Action<T> onReceive) where T : INetSerializable, new()
+
public void SubscribeNetSerializable<T, TUserData>(Action<T, TUserData> onReceive, Func<T> packetConstructor) where T : INetSerializable
Parameters
@@ -751,10 +703,15 @@
Parameters
- + + + + + +
Action<T>Action<T, TUserData> onReceive
Func<T>packetConstructor
Type Parameters
@@ -770,17 +727,23 @@
Type Parameters
T + + TUserData + + - -

SubscribeNetSerializable<T, TUserData>(Action<T, TUserData>, Func<T>)

-
+ +

SubscribeReusable<T>(Action<T>)

+

Register and subscribe to packet receive event +This method will overwrite last received packet class on receive (less garbage)

+
Declaration
-
public void SubscribeNetSerializable<T, TUserData>(Action<T, TUserData> onReceive, Func<T> packetConstructor) where T : INetSerializable
+
public void SubscribeReusable<T>(Action<T> onReceive) where T : class, new()
Parameters
@@ -793,14 +756,10 @@
Parameters
- + - - - - - - +
Action<T, TUserData>Action<T> onReceive
Func<T>packetConstructor

event that will be called when packet deserialized with ReadPacket method

+
@@ -817,21 +776,35 @@
Type Parameters
T + + +
Exceptions
+ + - - + + + + + + + +
TUserDataTypeCondition
InvalidTypeException

T's fields are not supported, or it has no fields

+
- -

SubscribeNetSerializable<T, TUserData>(Action<T, TUserData>)

-
+ +

SubscribeReusable<T, TUserData>(Action<T, TUserData>)

+

Register and subscribe to packet receive event +This method will overwrite last received packet class on receive (less garbage)

+
Declaration
-
public void SubscribeNetSerializable<T, TUserData>(Action<T, TUserData> onReceive) where T : INetSerializable, new()
+
public void SubscribeReusable<T, TUserData>(Action<T, TUserData> onReceive) where T : class, new()
Parameters
@@ -846,7 +819,8 @@
Parameters
- +
Action<T, TUserData> onReceive

event that will be called when packet deserialized with ReadPacket method

+
@@ -869,17 +843,32 @@
Type Parameters
+
Exceptions
+ + + + + + + + + + + + + +
TypeCondition
InvalidTypeException

T's fields are not supported, or it has no fields

+
- -

SubscribeReusable<T>(Action<T>)

-

Register and subscribe to packet receive event -This method will overwrite last received packet class on receive (less garbage)

+ +

Subscribe<T>(Action<T>, Func<T>)

+

Register and subscribe to packet receive event

Declaration
-
public void SubscribeReusable<T>(Action<T> onReceive) where T : class, new()
+
public void Subscribe<T>(Action<T> onReceive, Func<T> packetConstructor) where T : class, new()
Parameters
@@ -895,6 +884,12 @@
Parameters
+ + + + + @@ -932,15 +927,14 @@
Exceptions
Action<T> onReceive

event that will be called when packet deserialized with ReadPacket method

+
Func<T>packetConstructor

Method that constructs packet instead of slow Activator.CreateInstance

- -

SubscribeReusable<T, TUserData>(Action<T, TUserData>)

-

Register and subscribe to packet receive event -This method will overwrite last received packet class on receive (less garbage)

+ +

Subscribe<T, TUserData>(Action<T, TUserData>, Func<T>)

+

Register and subscribe to packet receive event (with userData)

Declaration
-
public void SubscribeReusable<T, TUserData>(Action<T, TUserData> onReceive) where T : class, new()
+
public void Subscribe<T, TUserData>(Action<T, TUserData> onReceive, Func<T> packetConstructor) where T : class, new()
Parameters
@@ -956,6 +950,12 @@
Parameters
+ + + + + @@ -997,13 +997,13 @@
Exceptions
Action<T, TUserData> onReceive

event that will be called when packet deserialized with ReadPacket method

+
Func<T>packetConstructor

Method that constructs packet instead of slow Activator.CreateInstance

- -

Write<T>(NetDataWriter, T)

+ +

WriteHash<T>(NetDataWriter)

Declaration
-
public void Write<T>(NetDataWriter writer, T packet) where T : class, new()
+
protected virtual void WriteHash<T>(NetDataWriter writer)
Parameters
@@ -1020,11 +1020,6 @@
Parameters
- - - - -
writer
Tpacket
Type Parameters
@@ -1044,13 +1039,13 @@
Type Parameters
- -

WriteHash<T>(NetDataWriter)

+ +

WriteNetSerializable<T>(NetDataWriter, ref T)

Declaration
-
protected virtual void WriteHash<T>(NetDataWriter writer)
+
public void WriteNetSerializable<T>(NetDataWriter writer, ref T packet) where T : INetSerializable
Parameters
@@ -1067,6 +1062,11 @@
Parameters
+ + + + +
writer
Tpacket
Type Parameters
@@ -1086,13 +1086,13 @@
Type Parameters
- -

WriteNetSerializable<T>(NetDataWriter, ref T)

+ +

Write<T>(NetDataWriter, T)

Declaration
-
public void WriteNetSerializable<T>(NetDataWriter writer, ref T packet) where T : INetSerializable
+
public void Write<T>(NetDataWriter writer, T packet) where T : class, new()
Parameters
@@ -1142,7 +1142,7 @@
Type Parameters
diff --git a/docs/api/LiteNetLib.Utils.NetSerializer.html b/docs/api/LiteNetLib.Utils.NetSerializer.html index 15d99753..a39f26e5 100644 --- a/docs/api/LiteNetLib.Utils.NetSerializer.html +++ b/docs/api/LiteNetLib.Utils.NetSerializer.html @@ -130,13 +130,13 @@

Methods -

Deserialize<T>(NetDataReader, T)

-

Reads packet with known type (non alloc variant)

+

Deserialize<T>(NetDataReader)

+

Reads packet with known type

Declaration
-
public bool Deserialize<T>(NetDataReader reader, T target) where T : class, new()
+
public T Deserialize<T>(NetDataReader reader) where T : class, new()
Parameters
@@ -152,12 +152,6 @@
Parameters
- - - - - @@ -172,8 +166,8 @@
Returns
- - + @@ -212,13 +206,13 @@
Exceptions
-

Deserialize<T>(NetDataReader)

-

Reads packet with known type

+

Deserialize<T>(NetDataReader, T)

+

Reads packet with known type (non alloc variant)

Declaration
-
public T Deserialize<T>(NetDataReader reader) where T : class, new()
+
public bool Deserialize<T>(NetDataReader reader, T target) where T : class, new()
Parameters
NetDataReader reader

NetDataReader with packet

-
Ttarget

Deserialization target

bool

Returns true if packet in reader is matched type

+
T

Returns packet if packet in reader is matched type

@@ -236,65 +230,30 @@
Parameters
- -

NetDataReader with packet

-
Returns
- - - - - - - - - +
TypeDescription
T

Returns packet if packet in reader is matched type

+
target

Deserialization target

-
Type Parameters
- - - - - - - - - - - - - -
NameDescription
T
-
Exceptions
+
Returns
- + - - +
TypeConditionDescription
InvalidTypeException

T's fields are not supported, or it has no fields

+
bool

Returns true if packet in reader is matched type

- - - -

Register<T>()

-
-
-
Declaration
-
-
public void Register<T>()
-
Type Parameters
@@ -450,64 +409,45 @@
Type Parameters
- -

Serialize<T>(T)

-

Serialize object to byte array

-
+ +

Register<T>()

+
Declaration
-
public byte[] Serialize<T>(T obj) where T : class, new()
+
public void Register<T>()
-
Parameters
+
Type Parameters
- - - - + +
Type Name Description
Tobj

Object to serialize

-
T
-
Returns
+
Exceptions
- + - - +
TypeDescriptionCondition
byte[]

byte array with serialized data

+
InvalidTypeException

T's fields are not supported, or it has no fields

-
Type Parameters
- - - - - - - - - - - - - -
NameDescription
T
@@ -575,6 +515,66 @@
Exceptions
+ + +

Serialize<T>(T)

+

Serialize object to byte array

+
+
+
Declaration
+
+
public byte[] Serialize<T>(T obj) where T : class, new()
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
Tobj

Object to serialize

+
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
byte[]

byte array with serialized data

+
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T
+
@@ -585,7 +585,7 @@
Exceptions
diff --git a/docs/api/LiteNetLib.Utils.NtpLeapIndicator.html b/docs/api/LiteNetLib.Utils.NtpLeapIndicator.html index a41b662d..c797e09d 100644 --- a/docs/api/LiteNetLib.Utils.NtpLeapIndicator.html +++ b/docs/api/LiteNetLib.Utils.NtpLeapIndicator.html @@ -129,7 +129,7 @@
See Also
diff --git a/docs/api/LiteNetLib.Utils.NtpMode.html b/docs/api/LiteNetLib.Utils.NtpMode.html index 7a203a2c..e1e29604 100644 --- a/docs/api/LiteNetLib.Utils.NtpMode.html +++ b/docs/api/LiteNetLib.Utils.NtpMode.html @@ -119,7 +119,7 @@
See Also
diff --git a/docs/api/LiteNetLib.Utils.NtpPacket.html b/docs/api/LiteNetLib.Utils.NtpPacket.html index 313c36cf..fa85dae3 100644 --- a/docs/api/LiteNetLib.Utils.NtpPacket.html +++ b/docs/api/LiteNetLib.Utils.NtpPacket.html @@ -731,7 +731,7 @@
Returns
diff --git a/docs/api/LiteNetLib.Utils.ParseException.html b/docs/api/LiteNetLib.Utils.ParseException.html index f3659548..eb121abc 100644 --- a/docs/api/LiteNetLib.Utils.ParseException.html +++ b/docs/api/LiteNetLib.Utils.ParseException.html @@ -177,7 +177,7 @@

Implements

diff --git a/docs/api/LiteNetLib.Utils.PreserveAttribute.html b/docs/api/LiteNetLib.Utils.PreserveAttribute.html index 8a61f6c0..7dc49e53 100644 --- a/docs/api/LiteNetLib.Utils.PreserveAttribute.html +++ b/docs/api/LiteNetLib.Utils.PreserveAttribute.html @@ -214,7 +214,7 @@
Syntax
diff --git a/docs/api/LiteNetLib.Utils.html b/docs/api/LiteNetLib.Utils.html index d7951740..fadfa6fa 100644 --- a/docs/api/LiteNetLib.Utils.html +++ b/docs/api/LiteNetLib.Utils.html @@ -74,7 +74,8 @@

Namespa
-

Classes +

+Classes

CRC32C

@@ -98,11 +99,13 @@

ParseExceptionPreserveAttribute

PreserveAttribute prevents byte code stripping from removing a class, method, field, or property.

-

Interfaces +

+Interfaces

INetSerializable

-

Enums +

+Enums

NtpLeapIndicator

Represents leap second warning from the server that instructs the client to add or remove leap second.

@@ -122,7 +125,7 @@

NtpMode

diff --git a/docs/api/LiteNetLib.html b/docs/api/LiteNetLib.html index 9e5bc4e8..e947bfd3 100644 --- a/docs/api/LiteNetLib.html +++ b/docs/api/LiteNetLib.html @@ -74,7 +74,8 @@

Namespace LiteNetLi
-

Classes +

+Classes

ConnectionRequest

@@ -109,7 +110,8 @@

NetUtils

TooBigPacketException

-

Structs +

+Structs

DisconnectInfo

Additional information about disconnection

@@ -118,7 +120,8 @@

NetManag

PooledPacket

-

Interfaces +

+Interfaces

IDeliveryEventListener

@@ -133,7 +136,8 @@

INtpEventListener

IPeerAddressChangedListener

-

Enums +

+Enums

ConnectionState

Peer connection state

@@ -166,7 +170,7 @@

UnconnectedMes diff --git a/docs/api/index.html b/docs/api/index.html index 85e708e6..3f2ccb15 100644 --- a/docs/api/index.html +++ b/docs/api/index.html @@ -68,6 +68,7 @@

LiteNetLib

+
@@ -78,7 +79,7 @@

LiteNetLib

diff --git a/docs/api/toc.html b/docs/api/toc.html index 12210740..17d678aa 100644 --- a/docs/api/toc.html +++ b/docs/api/toc.html @@ -5,7 +5,7 @@
- +
- \ No newline at end of file + diff --git a/docs/api/toc.json b/docs/api/toc.json new file mode 100644 index 00000000..9c70d1f3 --- /dev/null +++ b/docs/api/toc.json @@ -0,0 +1,2 @@ + +{"items":[{"name":"LiteNetLib","href":"LiteNetLib.html","topicHref":"LiteNetLib.html","topicUid":"LiteNetLib","items":[{"name":"ConnectionRequest","href":"LiteNetLib.ConnectionRequest.html","topicHref":"LiteNetLib.ConnectionRequest.html","topicUid":"LiteNetLib.ConnectionRequest"},{"name":"ConnectionState","href":"LiteNetLib.ConnectionState.html","topicHref":"LiteNetLib.ConnectionState.html","topicUid":"LiteNetLib.ConnectionState"},{"name":"DeliveryMethod","href":"LiteNetLib.DeliveryMethod.html","topicHref":"LiteNetLib.DeliveryMethod.html","topicUid":"LiteNetLib.DeliveryMethod"},{"name":"DisconnectInfo","href":"LiteNetLib.DisconnectInfo.html","topicHref":"LiteNetLib.DisconnectInfo.html","topicUid":"LiteNetLib.DisconnectInfo"},{"name":"DisconnectReason","href":"LiteNetLib.DisconnectReason.html","topicHref":"LiteNetLib.DisconnectReason.html","topicUid":"LiteNetLib.DisconnectReason"},{"name":"EventBasedNatPunchListener","href":"LiteNetLib.EventBasedNatPunchListener.html","topicHref":"LiteNetLib.EventBasedNatPunchListener.html","topicUid":"LiteNetLib.EventBasedNatPunchListener"},{"name":"EventBasedNetListener","href":"LiteNetLib.EventBasedNetListener.html","topicHref":"LiteNetLib.EventBasedNetListener.html","topicUid":"LiteNetLib.EventBasedNetListener"},{"name":"IDeliveryEventListener","href":"LiteNetLib.IDeliveryEventListener.html","topicHref":"LiteNetLib.IDeliveryEventListener.html","topicUid":"LiteNetLib.IDeliveryEventListener"},{"name":"INatPunchListener","href":"LiteNetLib.INatPunchListener.html","topicHref":"LiteNetLib.INatPunchListener.html","topicUid":"LiteNetLib.INatPunchListener"},{"name":"INetEventListener","href":"LiteNetLib.INetEventListener.html","topicHref":"LiteNetLib.INetEventListener.html","topicUid":"LiteNetLib.INetEventListener"},{"name":"INetLogger","href":"LiteNetLib.INetLogger.html","topicHref":"LiteNetLib.INetLogger.html","topicUid":"LiteNetLib.INetLogger"},{"name":"INtpEventListener","href":"LiteNetLib.INtpEventListener.html","topicHref":"LiteNetLib.INtpEventListener.html","topicUid":"LiteNetLib.INtpEventListener"},{"name":"IPeerAddressChangedListener","href":"LiteNetLib.IPeerAddressChangedListener.html","topicHref":"LiteNetLib.IPeerAddressChangedListener.html","topicUid":"LiteNetLib.IPeerAddressChangedListener"},{"name":"InvalidPacketException","href":"LiteNetLib.InvalidPacketException.html","topicHref":"LiteNetLib.InvalidPacketException.html","topicUid":"LiteNetLib.InvalidPacketException"},{"name":"LocalAddrType","href":"LiteNetLib.LocalAddrType.html","topicHref":"LiteNetLib.LocalAddrType.html","topicUid":"LiteNetLib.LocalAddrType"},{"name":"NatAddressType","href":"LiteNetLib.NatAddressType.html","topicHref":"LiteNetLib.NatAddressType.html","topicUid":"LiteNetLib.NatAddressType"},{"name":"NatPunchModule","href":"LiteNetLib.NatPunchModule.html","topicHref":"LiteNetLib.NatPunchModule.html","topicUid":"LiteNetLib.NatPunchModule"},{"name":"NetConstants","href":"LiteNetLib.NetConstants.html","topicHref":"LiteNetLib.NetConstants.html","topicUid":"LiteNetLib.NetConstants"},{"name":"NetDebug","href":"LiteNetLib.NetDebug.html","topicHref":"LiteNetLib.NetDebug.html","topicUid":"LiteNetLib.NetDebug"},{"name":"NetLogLevel","href":"LiteNetLib.NetLogLevel.html","topicHref":"LiteNetLib.NetLogLevel.html","topicUid":"LiteNetLib.NetLogLevel"},{"name":"NetManager","href":"LiteNetLib.NetManager.html","topicHref":"LiteNetLib.NetManager.html","topicUid":"LiteNetLib.NetManager"},{"name":"NetManager.NetPeerEnumerator","href":"LiteNetLib.NetManager.NetPeerEnumerator.html","topicHref":"LiteNetLib.NetManager.NetPeerEnumerator.html","topicUid":"LiteNetLib.NetManager.NetPeerEnumerator"},{"name":"NetPacketReader","href":"LiteNetLib.NetPacketReader.html","topicHref":"LiteNetLib.NetPacketReader.html","topicUid":"LiteNetLib.NetPacketReader"},{"name":"NetPeer","href":"LiteNetLib.NetPeer.html","topicHref":"LiteNetLib.NetPeer.html","topicUid":"LiteNetLib.NetPeer"},{"name":"NetStatistics","href":"LiteNetLib.NetStatistics.html","topicHref":"LiteNetLib.NetStatistics.html","topicUid":"LiteNetLib.NetStatistics"},{"name":"NetUtils","href":"LiteNetLib.NetUtils.html","topicHref":"LiteNetLib.NetUtils.html","topicUid":"LiteNetLib.NetUtils"},{"name":"PooledPacket","href":"LiteNetLib.PooledPacket.html","topicHref":"LiteNetLib.PooledPacket.html","topicUid":"LiteNetLib.PooledPacket"},{"name":"TooBigPacketException","href":"LiteNetLib.TooBigPacketException.html","topicHref":"LiteNetLib.TooBigPacketException.html","topicUid":"LiteNetLib.TooBigPacketException"},{"name":"UnconnectedMessageType","href":"LiteNetLib.UnconnectedMessageType.html","topicHref":"LiteNetLib.UnconnectedMessageType.html","topicUid":"LiteNetLib.UnconnectedMessageType"}]},{"name":"LiteNetLib.Layers","href":"LiteNetLib.Layers.html","topicHref":"LiteNetLib.Layers.html","topicUid":"LiteNetLib.Layers","items":[{"name":"Crc32cLayer","href":"LiteNetLib.Layers.Crc32cLayer.html","topicHref":"LiteNetLib.Layers.Crc32cLayer.html","topicUid":"LiteNetLib.Layers.Crc32cLayer"},{"name":"PacketLayerBase","href":"LiteNetLib.Layers.PacketLayerBase.html","topicHref":"LiteNetLib.Layers.PacketLayerBase.html","topicUid":"LiteNetLib.Layers.PacketLayerBase"},{"name":"XorEncryptLayer","href":"LiteNetLib.Layers.XorEncryptLayer.html","topicHref":"LiteNetLib.Layers.XorEncryptLayer.html","topicUid":"LiteNetLib.Layers.XorEncryptLayer"}]},{"name":"LiteNetLib.Utils","href":"LiteNetLib.Utils.html","topicHref":"LiteNetLib.Utils.html","topicUid":"LiteNetLib.Utils","items":[{"name":"CRC32C","href":"LiteNetLib.Utils.CRC32C.html","topicHref":"LiteNetLib.Utils.CRC32C.html","topicUid":"LiteNetLib.Utils.CRC32C"},{"name":"FastBitConverter","href":"LiteNetLib.Utils.FastBitConverter.html","topicHref":"LiteNetLib.Utils.FastBitConverter.html","topicUid":"LiteNetLib.Utils.FastBitConverter"},{"name":"INetSerializable","href":"LiteNetLib.Utils.INetSerializable.html","topicHref":"LiteNetLib.Utils.INetSerializable.html","topicUid":"LiteNetLib.Utils.INetSerializable"},{"name":"InvalidTypeException","href":"LiteNetLib.Utils.InvalidTypeException.html","topicHref":"LiteNetLib.Utils.InvalidTypeException.html","topicUid":"LiteNetLib.Utils.InvalidTypeException"},{"name":"NetDataReader","href":"LiteNetLib.Utils.NetDataReader.html","topicHref":"LiteNetLib.Utils.NetDataReader.html","topicUid":"LiteNetLib.Utils.NetDataReader"},{"name":"NetDataWriter","href":"LiteNetLib.Utils.NetDataWriter.html","topicHref":"LiteNetLib.Utils.NetDataWriter.html","topicUid":"LiteNetLib.Utils.NetDataWriter"},{"name":"NetPacketProcessor","href":"LiteNetLib.Utils.NetPacketProcessor.html","topicHref":"LiteNetLib.Utils.NetPacketProcessor.html","topicUid":"LiteNetLib.Utils.NetPacketProcessor"},{"name":"NetSerializer","href":"LiteNetLib.Utils.NetSerializer.html","topicHref":"LiteNetLib.Utils.NetSerializer.html","topicUid":"LiteNetLib.Utils.NetSerializer"},{"name":"NtpLeapIndicator","href":"LiteNetLib.Utils.NtpLeapIndicator.html","topicHref":"LiteNetLib.Utils.NtpLeapIndicator.html","topicUid":"LiteNetLib.Utils.NtpLeapIndicator"},{"name":"NtpMode","href":"LiteNetLib.Utils.NtpMode.html","topicHref":"LiteNetLib.Utils.NtpMode.html","topicUid":"LiteNetLib.Utils.NtpMode"},{"name":"NtpPacket","href":"LiteNetLib.Utils.NtpPacket.html","topicHref":"LiteNetLib.Utils.NtpPacket.html","topicUid":"LiteNetLib.Utils.NtpPacket"},{"name":"ParseException","href":"LiteNetLib.Utils.ParseException.html","topicHref":"LiteNetLib.Utils.ParseException.html","topicUid":"LiteNetLib.Utils.ParseException"},{"name":"PreserveAttribute","href":"LiteNetLib.Utils.PreserveAttribute.html","topicHref":"LiteNetLib.Utils.PreserveAttribute.html","topicUid":"LiteNetLib.Utils.PreserveAttribute"}]}],"memberLayout":"SamePage"} diff --git a/docs/articles/netserializerusage.html b/docs/articles/netserializerusage.html index aaae5e4f..77bc445d 100644 --- a/docs/articles/netserializerusage.html +++ b/docs/articles/netserializerusage.html @@ -227,6 +227,7 @@

Mini FAQ

Q: NetPacketProcessor throws "Undefined packet in NetDataReader" but all packets are registered.
A: This can happen when packet definitions resides in different namespaces. Check that registered packet classes/structs are in the same namespace on both ends. To avoid this error altogether, use shared code/-assembly for packets.

+ @@ -237,7 +238,7 @@

Mini FAQ

diff --git a/docs/articles/toc.html b/docs/articles/toc.html index db355290..8de463ca 100644 --- a/docs/articles/toc.html +++ b/docs/articles/toc.html @@ -5,7 +5,7 @@
- +
@@ -19,4 +19,4 @@
- \ No newline at end of file + diff --git a/docs/articles/toc.json b/docs/articles/toc.json new file mode 100644 index 00000000..a67e5ac5 --- /dev/null +++ b/docs/articles/toc.json @@ -0,0 +1,2 @@ + +{"items":[{"name":"NetSerializer usage","href":"netserializerusage.html","topicHref":"netserializerusage.html"}]} diff --git a/docs/index.html b/docs/index.html index ea6e98b2..fba02201 100644 --- a/docs/index.html +++ b/docs/index.html @@ -246,6 +246,7 @@

NetManager settings description

+ @@ -256,7 +257,7 @@

NetManager settings description

diff --git a/docs/manifest.json b/docs/manifest.json index a0c5141c..ac7fb948 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1,6 +1,5 @@ { - "homepages": [], - "source_base_path": "e:/Projects/LiteNetLib/docfx_project", + "source_base_path": "E:/Projects/LiteNetLib/docfx_project", "xrefmap": "xrefmap.yml", "files": [ { @@ -509,6 +508,9 @@ "output": { ".html": { "relative_path": "api/toc.html" + }, + ".json": { + "relative_path": "api/toc.json" } }, "version": "" @@ -529,6 +531,9 @@ "output": { ".html": { "relative_path": "articles/toc.html" + }, + ".json": { + "relative_path": "articles/toc.json" } }, "version": "" @@ -549,12 +554,14 @@ "output": { ".html": { "relative_path": "toc.html" + }, + ".json": { + "relative_path": "toc.json" } }, "version": "" } ], - "version_info": {}, "groups": [ { "xrefmap": "xrefmap.yml" diff --git a/docs/styles/docfx.css b/docs/styles/docfx.css index 34ee31bb..7d80d139 100644 --- a/docs/styles/docfx.css +++ b/docs/styles/docfx.css @@ -1,4 +1,7 @@ -/* Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License.txt in the project root for license information. */ +/** + * Licensed to the .NET Foundation under one or more agreements. + * The .NET Foundation licenses this file to you under the MIT license. + */ html, body { font-family: 'Segoe UI', Tahoma, Helvetica, sans-serif; @@ -108,10 +111,6 @@ span.languagekeyword{ font-weight: bold; } -svg:hover path { - fill: #ffffff; -} - .hljs { display: inline; background-color: inherit; @@ -826,7 +825,7 @@ footer { .toc .level1 > li { display: block; } - + .toc .level1 > li:after { display: none; } @@ -1034,3 +1033,9 @@ div.embeddedvideo iframe { font-weight: bold; margin-top: 2em; } + +@media print { + @page { + margin: .4in; + } +} diff --git a/docs/styles/docfx.js b/docs/styles/docfx.js index 16bafe8c..5bd62e28 100644 --- a/docs/styles/docfx.js +++ b/docs/styles/docfx.js @@ -1,4 +1,5 @@ -// Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information. +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. $(function () { var active = 'active'; var expanded = 'in'; @@ -127,13 +128,10 @@ $(function () { return; } try { - var worker = new Worker(relHref + 'styles/search-worker.min.js'); - if (!worker && !window.worker) { - localSearch(); - } else { - webWorkerSearch(); + if(!window.Worker){ + return; } - + webWorkerSearch(); renderSearchBox(); highlightKeywords(); addSearchEvent(); @@ -163,50 +161,14 @@ $(function () { } } - // Search factory - function localSearch() { - console.log("using local search"); - var lunrIndex = lunr(function () { - this.ref('href'); - this.field('title', { boost: 50 }); - this.field('keywords', { boost: 20 }); - }); - lunr.tokenizer.seperator = /[\s\-\.]+/; - var searchData = {}; - var searchDataRequest = new XMLHttpRequest(); - - var indexPath = relHref + "index.json"; - if (indexPath) { - searchDataRequest.open('GET', indexPath); - searchDataRequest.onload = function () { - if (this.status != 200) { - return; - } - searchData = JSON.parse(this.responseText); - for (var prop in searchData) { - if (searchData.hasOwnProperty(prop)) { - lunrIndex.add(searchData[prop]); - } - } - } - searchDataRequest.send(); - } - - $("body").bind("queryReady", function () { - var hits = lunrIndex.search(query); - var results = []; - hits.forEach(function (hit) { - var item = searchData[hit.ref]; - results.push({ 'href': item.href, 'title': item.title, 'keywords': item.keywords }); - }); - handleSearchResults(results); - }); - } - function webWorkerSearch() { - console.log("using Web Worker"); var indexReady = $.Deferred(); + var worker = new Worker(relHref + 'styles/search-worker.min.js'); + worker.onerror = function (oEvent) { + console.error('Error occurred at search-worker. message: ' + oEvent.message); + } + worker.onmessage = function (oEvent) { switch (oEvent.data.e) { case 'index-ready': @@ -251,7 +213,7 @@ $(function () { $('#search-query').keyup(function () { query = $(this).val(); - if (query.length < 3) { + if (query === '') { flipContents("show"); } else { flipContents("hide"); @@ -306,7 +268,7 @@ $(function () { pagination.removeData("twbs-pagination"); if (hits.length === 0) { $('#search-results>.sr-items').html('

No results found

'); - } else { + } else { pagination.twbsPagination({ first: pagination.data('first'), prev: pagination.data('prev'), @@ -354,7 +316,7 @@ $(function () { renderBreadcrumb(); showSearch(); } - + function showSearch() { if ($('#search-results').length !== 0) { $('#search').show(); @@ -443,7 +405,7 @@ $(function () { function registerTocEvents() { var tocFilterInput = $('#toc_filter_input'); var tocFilterClearButton = $('#toc_filter_clear'); - + $('.toc .nav > li > .expand-stub').click(function (e) { $(e.target).parent().toggleClass(expanded); }); @@ -477,7 +439,7 @@ $(function () { parent.removeClass(show); parent.removeClass(filtered); }) - + // Get leaf nodes $('#toc li>a').filter(function (i, e) { return $(e).siblings().length === 0 @@ -518,7 +480,7 @@ $(function () { return false; } }); - + // toc filter clear button tocFilterClearButton.hide(); tocFilterClearButton.on("click", function(e){ diff --git a/docs/styles/docfx.vendor.min.css b/docs/styles/docfx.vendor.min.css index b809553e..0faa137a 100644 --- a/docs/styles/docfx.vendor.min.css +++ b/docs/styles/docfx.vendor.min.css @@ -1,4 +1,4 @@ -html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*,*:before,*:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:Glyphicons Halflings;src:url(./glyphicons-halflings-regular-PIHUWCJO.eot);src:url(./glyphicons-halflings-regular-PIHUWCJO.eot?#iefix) format("embedded-opentype"),url(./glyphicons-halflings-regular-W4DYDFZM.woff2) format("woff2"),url(./glyphicons-halflings-regular-JOUF32XT.woff) format("woff"),url(./glyphicons-halflings-regular-ACNUA6UY.ttf) format("truetype"),url(./glyphicons-halflings-regular-QXYEM3FU.svg#glyphicons_halflingsregular) format("svg")}.glyphicon{position:relative;top:1px;display:inline-block;font-family:Glyphicons Halflings;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"*"}.glyphicon-plus:before{content:"+"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\a5"}.glyphicon-jpy:before{content:"\a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eeeeee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width: 768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover,a.text-primary:focus{color:#286090}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover,a.bg-primary:focus{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eeeeee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width: 768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eeeeee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:"\2014\a0"}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eeeeee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:""}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:"\a0\2014"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Courier New,monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px #00000040}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 768px){.container{width:750px}}@media (min-width: 992px){.container{width:970px}}@media (min-width: 1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.row-no-gutters{margin-right:0;margin-left:0}.row-no-gutters [class*=col-]{padding-right:0;padding-left:0}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width: 768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width: 992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width: 1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:transparent}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width: 767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \ ;line-height:normal}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px #00000013,0 0 8px #66afe999}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio: 0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month]{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \ ;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px #00000013,0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px #00000013,0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px #00000013,0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width: 768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width: 768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width: 768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width: 768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px #00000020}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;background-image:none;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;background-image:none;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;background-image:none;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;background-image:none;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;background-image:none;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \ ;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px #0000002d}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;inset:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid \ }.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width: 768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px #00000020}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child:not(:first-child){border-radius:0 0 4px 4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width: 768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width: 768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width: 768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width: 768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width: 768px){.navbar{border-radius:4px}}@media (min-width: 768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px #ffffff1a;-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width: 768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width: 480px) and (orientation: landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}@media (min-width: 768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width: 768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width: 768px){.navbar-static-top{border-radius:0}}.navbar-brand{float:left;height:50px;padding:15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width: 768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-right:15px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width: 768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width: 767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width: 768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin:8px -15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px #ffffff1a,0 1px #ffffff1a}@media (min-width: 768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width: 767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width: 768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-radius:4px 4px 0 0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width: 768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width: 768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width: 767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width: 767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width: 768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px #0000001a}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px #00000026;-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px #0000000d}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px #0000000d}.well blockquote{border-color:#ddd;border-color:#00000026}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;inset:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out,-o-transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px #00000080;outline:0}.modal-backdrop{position:fixed;inset:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px #00000080}.modal-sm{width:300px}}@media (min-width: 992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:12px;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px #0003}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover>.arrow{border-width:11px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:#00000040;border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:#00000040;border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:#00000040}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:#00000040}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0,0,0);transform:translateZ(0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:#0000;filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#80000000",endColorstr="#00000000",GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#00000000",endColorstr="#80000000",GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;outline:0;filter:alpha(opacity=90);opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \ ;background-color:#0000;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width: 768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width: 767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width: 767px){.visible-xs-block{display:block!important}}@media (max-width: 767px){.visible-xs-inline{display:inline!important}}@media (max-width: 767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-block{display:block!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-inline{display:inline!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-block{display:block!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-inline{display:inline!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width: 1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width: 1200px){.visible-lg-block{display:block!important}}@media (min-width: 1200px){.visible-lg-inline{display:inline!important}}@media (min-width: 1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width: 767px){.hidden-xs{display:none!important}}@media (min-width: 768px) and (max-width: 991px){.hidden-sm{display:none!important}}@media (min-width: 992px) and (max-width: 1199px){.hidden-md{display:none!important}}@media (min-width: 1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0} +html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*,*:before,*:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:Glyphicons Halflings;src:url("./glyphicons-halflings-regular-PIHUWCJO.eot");src:url("./glyphicons-halflings-regular-PIHUWCJO.eot?#iefix") format("embedded-opentype"),url("./glyphicons-halflings-regular-W4DYDFZM.woff2") format("woff2"),url("./glyphicons-halflings-regular-JOUF32XT.woff") format("woff"),url("./glyphicons-halflings-regular-ACNUA6UY.ttf") format("truetype"),url("./glyphicons-halflings-regular-QXYEM3FU.svg#glyphicons_halflingsregular") format("svg")}.glyphicon{position:relative;top:1px;display:inline-block;font-family:Glyphicons Halflings;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"*"}.glyphicon-plus:before{content:"+"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\a5"}.glyphicon-jpy:before{content:"\a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eeeeee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width: 768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover,a.text-primary:focus{color:#286090}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover,a.bg-primary:focus{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eeeeee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width: 768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eeeeee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:"\2014\a0"}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eeeeee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:""}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:"\a0\2014"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,Courier New,monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px #00000040}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width: 768px){.container{width:750px}}@media (min-width: 992px){.container{width:970px}}@media (min-width: 1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.row-no-gutters{margin-right:0;margin-left:0}.row-no-gutters [class*=col-]{padding-right:0;padding-left:0}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width: 768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width: 992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width: 1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:transparent}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width: 767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \ ;line-height:normal}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px #00000013,0 0 8px #66afe999}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio: 0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month]{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \ ;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px #00000013,0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px #00000013,0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px #00000013}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px #00000013,0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width: 768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width: 768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width: 768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width: 768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px #00000020}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;background-image:none;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;background-image:none;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;background-image:none;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;background-image:none;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;background-image:none;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \ ;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px #0000002d}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;inset:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid \ }.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width: 768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px #00000020}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-radius:4px 4px 0 0}.btn-group-vertical>.btn:last-child:not(:first-child){border-radius:0 0 4px 4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width: 768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width: 768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width: 768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width: 768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width: 768px){.navbar{border-radius:4px}}@media (min-width: 768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px #ffffff1a;-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width: 768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width: 480px) and (orientation: landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}@media (min-width: 768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width: 768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width: 768px){.navbar-static-top{border-radius:0}}.navbar-brand{float:left;height:50px;padding:15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width: 768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-right:15px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width: 768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width: 767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width: 768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin:8px -15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px #ffffff1a,0 1px #ffffff1a}@media (min-width: 768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width: 767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width: 768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-radius:4px 4px 0 0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width: 768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width: 768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width: 767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width: 767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width: 768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px #0000001a}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px #00000026;-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px #0000000d}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px #0000000d}.well blockquote{border-color:#ddd;border-color:#00000026}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;inset:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translateY(-25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out,-o-transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px #00000080;outline:0}.modal-backdrop{position:fixed;inset:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width: 768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px #00000080}.modal-sm{width:300px}}@media (min-width: 992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:12px;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px #0003}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover>.arrow{border-width:11px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:#00000040;border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:#00000040;border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:#00000040}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:#00000040}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0,0,0);transform:translateZ(0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:#0000;filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0%,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#80000000",endColorstr="#00000000",GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0%,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#00000000",endColorstr="#80000000",GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;outline:0;filter:alpha(opacity=90);opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \ ;background-color:#0000;border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width: 768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width: 767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width: 767px){.visible-xs-block{display:block!important}}@media (max-width: 767px){.visible-xs-inline{display:inline!important}}@media (max-width: 767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-block{display:block!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-inline{display:inline!important}}@media (min-width: 768px) and (max-width: 991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-block{display:block!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-inline{display:inline!important}}@media (min-width: 992px) and (max-width: 1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width: 1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width: 1200px){.visible-lg-block{display:block!important}}@media (min-width: 1200px){.visible-lg-inline{display:inline!important}}@media (min-width: 1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width: 767px){.hidden-xs{display:none!important}}@media (min-width: 768px) and (max-width: 991px){.hidden-sm{display:none!important}}@media (min-width: 992px) and (max-width: 1199px){.hidden-md{display:none!important}}@media (min-width: 1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0} /*! Bundled license information: @default/bootstrap/dist/css/bootstrap.css: diff --git a/docs/styles/docfx.vendor.min.css.map b/docs/styles/docfx.vendor.min.css.map index 31cf61ec..ddb7afef 100644 --- a/docs/styles/docfx.vendor.min.css.map +++ b/docs/styles/docfx.vendor.min.css.map @@ -2,6 +2,6 @@ "version": 3, "sources": ["../../node_modules/@default/bootstrap/dist/css/bootstrap.css", "../../node_modules/@default/bootstrap/dist/css/less/normalize.less", "../../node_modules/@default/bootstrap/dist/css/less/print.less", "../../node_modules/@default/bootstrap/dist/css/less/glyphicons.less", "../../node_modules/@default/bootstrap/dist/css/less/scaffolding.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/vendor-prefixes.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/tab-focus.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/image.less", "../../node_modules/@default/bootstrap/dist/css/less/type.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/text-emphasis.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/background-variant.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/text-overflow.less", "../../node_modules/@default/bootstrap/dist/css/less/code.less", "../../node_modules/@default/bootstrap/dist/css/less/grid.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/grid.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/grid-framework.less", "../../node_modules/@default/bootstrap/dist/css/less/tables.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/table-row.less", "../../node_modules/@default/bootstrap/dist/css/less/forms.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/forms.less", "../../node_modules/@default/bootstrap/dist/css/less/buttons.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/buttons.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/opacity.less", "../../node_modules/@default/bootstrap/dist/css/less/component-animations.less", "../../node_modules/@default/bootstrap/dist/css/less/dropdowns.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/nav-divider.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/reset-filter.less", "../../node_modules/@default/bootstrap/dist/css/less/button-groups.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/border-radius.less", "../../node_modules/@default/bootstrap/dist/css/less/input-groups.less", "../../node_modules/@default/bootstrap/dist/css/less/navs.less", "../../node_modules/@default/bootstrap/dist/css/less/navbar.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/nav-vertical-align.less", "../../node_modules/@default/bootstrap/dist/css/less/utilities.less", "../../node_modules/@default/bootstrap/dist/css/less/breadcrumbs.less", "../../node_modules/@default/bootstrap/dist/css/less/pagination.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/pagination.less", "../../node_modules/@default/bootstrap/dist/css/less/pager.less", "../../node_modules/@default/bootstrap/dist/css/less/labels.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/labels.less", "../../node_modules/@default/bootstrap/dist/css/less/badges.less", "../../node_modules/@default/bootstrap/dist/css/less/jumbotron.less", "../../node_modules/@default/bootstrap/dist/css/less/thumbnails.less", "../../node_modules/@default/bootstrap/dist/css/less/alerts.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/alerts.less", "../../node_modules/@default/bootstrap/dist/css/less/progress-bars.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/gradients.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/progress-bar.less", "../../node_modules/@default/bootstrap/dist/css/less/media.less", "../../node_modules/@default/bootstrap/dist/css/less/list-group.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/list-group.less", "../../node_modules/@default/bootstrap/dist/css/less/panels.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/panels.less", "../../node_modules/@default/bootstrap/dist/css/less/responsive-embed.less", "../../node_modules/@default/bootstrap/dist/css/less/wells.less", "../../node_modules/@default/bootstrap/dist/css/less/close.less", "../../node_modules/@default/bootstrap/dist/css/less/modals.less", "../../node_modules/@default/bootstrap/dist/css/less/tooltip.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/reset-text.less", "../../node_modules/@default/bootstrap/dist/css/less/popovers.less", "../../node_modules/@default/bootstrap/dist/css/less/carousel.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/clearfix.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/center-block.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/hide-text.less", "../../node_modules/@default/bootstrap/dist/css/less/responsive-utilities.less", "../../node_modules/@default/bootstrap/dist/css/less/mixins/responsive-visibility.less", "../../node_modules/@default/highlight.js/styles/github.css"], "sourcesContent": ["/*!\n * Bootstrap v3.4.1 (https://getbootstrap.com/)\n * Copyright 2011-2019 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n font-family: sans-serif;\n -ms-text-size-adjust: 100%;\n -webkit-text-size-adjust: 100%;\n}\nbody {\n margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block;\n vertical-align: baseline;\n}\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n[hidden],\ntemplate {\n display: none;\n}\na {\n background-color: transparent;\n}\na:active,\na:hover {\n outline: 0;\n}\nabbr[title] {\n border-bottom: none;\n text-decoration: underline;\n text-decoration: underline dotted;\n}\nb,\nstrong {\n font-weight: bold;\n}\ndfn {\n font-style: italic;\n}\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\nmark {\n background: #ff0;\n color: #000;\n}\nsmall {\n font-size: 80%;\n}\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\nsup {\n top: -0.5em;\n}\nsub {\n bottom: -0.25em;\n}\nimg {\n border: 0;\n}\nsvg:not(:root) {\n overflow: hidden;\n}\nfigure {\n margin: 1em 40px;\n}\nhr {\n box-sizing: content-box;\n height: 0;\n}\npre {\n overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit;\n font: inherit;\n margin: 0;\n}\nbutton {\n overflow: visible;\n}\nbutton,\nselect {\n text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button;\n cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\ninput {\n line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box;\n padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\ninput[type=\"search\"] {\n -webkit-appearance: textfield;\n box-sizing: content-box;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\nlegend {\n border: 0;\n padding: 0;\n}\ntextarea {\n overflow: auto;\n}\noptgroup {\n font-weight: bold;\n}\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\ntd,\nth {\n padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important;\n text-shadow: none !important;\n background: transparent !important;\n box-shadow: none !important;\n }\n a,\n a:visited {\n text-decoration: underline;\n }\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n thead {\n display: table-header-group;\n }\n tr,\n img {\n page-break-inside: avoid;\n }\n img {\n max-width: 100% !important;\n }\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n h2,\n h3 {\n page-break-after: avoid;\n }\n .navbar {\n display: none;\n }\n .btn > .caret,\n .dropup > .btn > .caret {\n border-top-color: #000 !important;\n }\n .label {\n border: 1px solid #000;\n }\n .table {\n border-collapse: collapse !important;\n }\n .table td,\n .table th {\n background-color: #fff !important;\n }\n .table-bordered th,\n .table-bordered td {\n border: 1px solid #ddd !important;\n }\n}\n@font-face {\n font-family: \"Glyphicons Halflings\";\n src: url(\"../fonts/glyphicons-halflings-regular.eot\");\n src: url(\"../fonts/glyphicons-halflings-regular.eot?#iefix\") format(\"embedded-opentype\"), url(\"../fonts/glyphicons-halflings-regular.woff2\") format(\"woff2\"), url(\"../fonts/glyphicons-halflings-regular.woff\") format(\"woff\"), url(\"../fonts/glyphicons-halflings-regular.ttf\") format(\"truetype\"), url(\"../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular\") format(\"svg\");\n}\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: \"Glyphicons Halflings\";\n font-style: normal;\n font-weight: 400;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n content: \"\\002a\";\n}\n.glyphicon-plus:before {\n content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n content: \"\\270f\";\n}\n.glyphicon-glass:before {\n content: \"\\e001\";\n}\n.glyphicon-music:before {\n content: \"\\e002\";\n}\n.glyphicon-search:before {\n content: \"\\e003\";\n}\n.glyphicon-heart:before {\n content: \"\\e005\";\n}\n.glyphicon-star:before {\n content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n content: \"\\e007\";\n}\n.glyphicon-user:before {\n content: \"\\e008\";\n}\n.glyphicon-film:before {\n content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n content: \"\\e010\";\n}\n.glyphicon-th:before {\n content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n content: \"\\e012\";\n}\n.glyphicon-ok:before {\n content: \"\\e013\";\n}\n.glyphicon-remove:before {\n content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n content: \"\\e016\";\n}\n.glyphicon-off:before {\n content: \"\\e017\";\n}\n.glyphicon-signal:before {\n content: \"\\e018\";\n}\n.glyphicon-cog:before {\n content: \"\\e019\";\n}\n.glyphicon-trash:before {\n content: \"\\e020\";\n}\n.glyphicon-home:before {\n content: \"\\e021\";\n}\n.glyphicon-file:before {\n content: \"\\e022\";\n}\n.glyphicon-time:before {\n content: \"\\e023\";\n}\n.glyphicon-road:before {\n content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n content: \"\\e025\";\n}\n.glyphicon-download:before {\n content: \"\\e026\";\n}\n.glyphicon-upload:before {\n content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n content: \"\\e032\";\n}\n.glyphicon-lock:before {\n content: \"\\e033\";\n}\n.glyphicon-flag:before {\n content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n content: \"\\e040\";\n}\n.glyphicon-tag:before {\n content: \"\\e041\";\n}\n.glyphicon-tags:before {\n content: \"\\e042\";\n}\n.glyphicon-book:before {\n content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n content: \"\\e044\";\n}\n.glyphicon-print:before {\n content: \"\\e045\";\n}\n.glyphicon-camera:before {\n content: \"\\e046\";\n}\n.glyphicon-font:before {\n content: \"\\e047\";\n}\n.glyphicon-bold:before {\n content: \"\\e048\";\n}\n.glyphicon-italic:before {\n content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n content: \"\\e055\";\n}\n.glyphicon-list:before {\n content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n content: \"\\e059\";\n}\n.glyphicon-picture:before {\n content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n content: \"\\e063\";\n}\n.glyphicon-tint:before {\n content: \"\\e064\";\n}\n.glyphicon-edit:before {\n content: \"\\e065\";\n}\n.glyphicon-share:before {\n content: \"\\e066\";\n}\n.glyphicon-check:before {\n content: \"\\e067\";\n}\n.glyphicon-move:before {\n content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n content: \"\\e070\";\n}\n.glyphicon-backward:before {\n content: \"\\e071\";\n}\n.glyphicon-play:before {\n content: \"\\e072\";\n}\n.glyphicon-pause:before {\n content: \"\\e073\";\n}\n.glyphicon-stop:before {\n content: \"\\e074\";\n}\n.glyphicon-forward:before {\n content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n content: \"\\e077\";\n}\n.glyphicon-eject:before {\n content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n content: \"\\e101\";\n}\n.glyphicon-gift:before {\n content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n content: \"\\e103\";\n}\n.glyphicon-fire:before {\n content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n content: \"\\e107\";\n}\n.glyphicon-plane:before {\n content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n content: \"\\e109\";\n}\n.glyphicon-random:before {\n content: \"\\e110\";\n}\n.glyphicon-comment:before {\n content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n content: \"\\e122\";\n}\n.glyphicon-bell:before {\n content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n content: \"\\e134\";\n}\n.glyphicon-globe:before {\n content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n content: \"\\e137\";\n}\n.glyphicon-filter:before {\n content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n content: \"\\e143\";\n}\n.glyphicon-link:before {\n content: \"\\e144\";\n}\n.glyphicon-phone:before {\n content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n content: \"\\e146\";\n}\n.glyphicon-usd:before {\n content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n content: \"\\e149\";\n}\n.glyphicon-sort:before {\n content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n content: \"\\e157\";\n}\n.glyphicon-expand:before {\n content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n content: \"\\e161\";\n}\n.glyphicon-flash:before {\n content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n content: \"\\e164\";\n}\n.glyphicon-record:before {\n content: \"\\e165\";\n}\n.glyphicon-save:before {\n content: \"\\e166\";\n}\n.glyphicon-open:before {\n content: \"\\e167\";\n}\n.glyphicon-saved:before {\n content: \"\\e168\";\n}\n.glyphicon-import:before {\n content: \"\\e169\";\n}\n.glyphicon-export:before {\n content: \"\\e170\";\n}\n.glyphicon-send:before {\n content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n content: \"\\e179\";\n}\n.glyphicon-header:before {\n content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n content: \"\\e183\";\n}\n.glyphicon-tower:before {\n content: \"\\e184\";\n}\n.glyphicon-stats:before {\n content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n content: \"\\e200\";\n}\n.glyphicon-cd:before {\n content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n content: \"\\e204\";\n}\n.glyphicon-copy:before {\n content: \"\\e205\";\n}\n.glyphicon-paste:before {\n content: \"\\e206\";\n}\n.glyphicon-alert:before {\n content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n content: \"\\e210\";\n}\n.glyphicon-king:before {\n content: \"\\e211\";\n}\n.glyphicon-queen:before {\n content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n content: \"\\e214\";\n}\n.glyphicon-knight:before {\n content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n content: \"\\e216\";\n}\n.glyphicon-tent:before {\n content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n content: \"\\e218\";\n}\n.glyphicon-bed:before {\n content: \"\\e219\";\n}\n.glyphicon-apple:before {\n content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n content: \"\\e227\";\n}\n.glyphicon-btc:before {\n content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n content: \"\\e227\";\n}\n.glyphicon-yen:before {\n content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n content: \"\\e232\";\n}\n.glyphicon-education:before {\n content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n content: \"\\e237\";\n}\n.glyphicon-oil:before {\n content: \"\\e238\";\n}\n.glyphicon-grain:before {\n content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n content: \"\\e253\";\n}\n.glyphicon-console:before {\n content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n content: \"\\e260\";\n}\n* {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\n*:before,\n*:after {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n}\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-size: 14px;\n line-height: 1.42857143;\n color: #333333;\n background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\na {\n color: #337ab7;\n text-decoration: none;\n}\na:hover,\na:focus {\n color: #23527c;\n text-decoration: underline;\n}\na:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\nfigure {\n margin: 0;\n}\nimg {\n vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n display: block;\n max-width: 100%;\n height: auto;\n}\n.img-rounded {\n border-radius: 6px;\n}\n.img-thumbnail {\n padding: 4px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: all 0.2s ease-in-out;\n -o-transition: all 0.2s ease-in-out;\n transition: all 0.2s ease-in-out;\n display: inline-block;\n max-width: 100%;\n height: auto;\n}\n.img-circle {\n border-radius: 50%;\n}\nhr {\n margin-top: 20px;\n margin-bottom: 20px;\n border: 0;\n border-top: 1px solid #eeeeee;\n}\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n}\n[role=\"button\"] {\n cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n font-family: inherit;\n font-weight: 500;\n line-height: 1.1;\n color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n font-weight: 400;\n line-height: 1;\n color: #777777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n margin-top: 20px;\n margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n margin-top: 10px;\n margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n font-size: 75%;\n}\nh1,\n.h1 {\n font-size: 36px;\n}\nh2,\n.h2 {\n font-size: 30px;\n}\nh3,\n.h3 {\n font-size: 24px;\n}\nh4,\n.h4 {\n font-size: 18px;\n}\nh5,\n.h5 {\n font-size: 14px;\n}\nh6,\n.h6 {\n font-size: 12px;\n}\np {\n margin: 0 0 10px;\n}\n.lead {\n margin-bottom: 20px;\n font-size: 16px;\n font-weight: 300;\n line-height: 1.4;\n}\n@media (min-width: 768px) {\n .lead {\n font-size: 21px;\n }\n}\nsmall,\n.small {\n font-size: 85%;\n}\nmark,\n.mark {\n padding: 0.2em;\n background-color: #fcf8e3;\n}\n.text-left {\n text-align: left;\n}\n.text-right {\n text-align: right;\n}\n.text-center {\n text-align: center;\n}\n.text-justify {\n text-align: justify;\n}\n.text-nowrap {\n white-space: nowrap;\n}\n.text-lowercase {\n text-transform: lowercase;\n}\n.text-uppercase {\n text-transform: uppercase;\n}\n.text-capitalize {\n text-transform: capitalize;\n}\n.text-muted {\n color: #777777;\n}\n.text-primary {\n color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n color: #286090;\n}\n.text-success {\n color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n color: #2b542c;\n}\n.text-info {\n color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n color: #245269;\n}\n.text-warning {\n color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n color: #66512c;\n}\n.text-danger {\n color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n color: #843534;\n}\n.bg-primary {\n color: #fff;\n background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n background-color: #286090;\n}\n.bg-success {\n background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n background-color: #c1e2b3;\n}\n.bg-info {\n background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n background-color: #afd9ee;\n}\n.bg-warning {\n background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n background-color: #f7ecb5;\n}\n.bg-danger {\n background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n background-color: #e4b9b9;\n}\n.page-header {\n padding-bottom: 9px;\n margin: 40px 0 20px;\n border-bottom: 1px solid #eeeeee;\n}\nul,\nol {\n margin-top: 0;\n margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n margin-bottom: 0;\n}\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n.list-inline {\n padding-left: 0;\n list-style: none;\n margin-left: -5px;\n}\n.list-inline > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n}\ndl {\n margin-top: 0;\n margin-bottom: 20px;\n}\ndt,\ndd {\n line-height: 1.42857143;\n}\ndt {\n font-weight: 700;\n}\ndd {\n margin-left: 0;\n}\n@media (min-width: 768px) {\n .dl-horizontal dt {\n float: left;\n width: 160px;\n clear: left;\n text-align: right;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .dl-horizontal dd {\n margin-left: 180px;\n }\n}\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\nblockquote {\n padding: 10px 20px;\n margin: 0 0 20px;\n font-size: 17.5px;\n border-left: 5px solid #eeeeee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n display: block;\n font-size: 80%;\n line-height: 1.42857143;\n color: #777777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n content: \"\\2014 \\00A0\";\n}\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid #eeeeee;\n border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n content: \"\";\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n content: \"\\00A0 \\2014\";\n}\naddress {\n margin-bottom: 20px;\n font-style: normal;\n line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: #c7254e;\n background-color: #f9f2f4;\n border-radius: 4px;\n}\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: #fff;\n background-color: #333;\n border-radius: 3px;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\nkbd kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n box-shadow: none;\n}\npre {\n display: block;\n padding: 9.5px;\n margin: 0 0 10px;\n font-size: 13px;\n line-height: 1.42857143;\n color: #333333;\n word-break: break-all;\n word-wrap: break-word;\n background-color: #f5f5f5;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\npre code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n}\n.pre-scrollable {\n max-height: 340px;\n overflow-y: scroll;\n}\n.container {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n@media (min-width: 768px) {\n .container {\n width: 750px;\n }\n}\n@media (min-width: 992px) {\n .container {\n width: 970px;\n }\n}\n@media (min-width: 1200px) {\n .container {\n width: 1170px;\n }\n}\n.container-fluid {\n padding-right: 15px;\n padding-left: 15px;\n margin-right: auto;\n margin-left: auto;\n}\n.row {\n margin-right: -15px;\n margin-left: -15px;\n}\n.row-no-gutters {\n margin-right: 0;\n margin-left: 0;\n}\n.row-no-gutters [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n}\n.col-xs-1,\n.col-sm-1,\n.col-md-1,\n.col-lg-1,\n.col-xs-2,\n.col-sm-2,\n.col-md-2,\n.col-lg-2,\n.col-xs-3,\n.col-sm-3,\n.col-md-3,\n.col-lg-3,\n.col-xs-4,\n.col-sm-4,\n.col-md-4,\n.col-lg-4,\n.col-xs-5,\n.col-sm-5,\n.col-md-5,\n.col-lg-5,\n.col-xs-6,\n.col-sm-6,\n.col-md-6,\n.col-lg-6,\n.col-xs-7,\n.col-sm-7,\n.col-md-7,\n.col-lg-7,\n.col-xs-8,\n.col-sm-8,\n.col-md-8,\n.col-lg-8,\n.col-xs-9,\n.col-sm-9,\n.col-md-9,\n.col-lg-9,\n.col-xs-10,\n.col-sm-10,\n.col-md-10,\n.col-lg-10,\n.col-xs-11,\n.col-sm-11,\n.col-md-11,\n.col-lg-11,\n.col-xs-12,\n.col-sm-12,\n.col-md-12,\n.col-lg-12 {\n position: relative;\n min-height: 1px;\n padding-right: 15px;\n padding-left: 15px;\n}\n.col-xs-1,\n.col-xs-2,\n.col-xs-3,\n.col-xs-4,\n.col-xs-5,\n.col-xs-6,\n.col-xs-7,\n.col-xs-8,\n.col-xs-9,\n.col-xs-10,\n.col-xs-11,\n.col-xs-12 {\n float: left;\n}\n.col-xs-12 {\n width: 100%;\n}\n.col-xs-11 {\n width: 91.66666667%;\n}\n.col-xs-10 {\n width: 83.33333333%;\n}\n.col-xs-9 {\n width: 75%;\n}\n.col-xs-8 {\n width: 66.66666667%;\n}\n.col-xs-7 {\n width: 58.33333333%;\n}\n.col-xs-6 {\n width: 50%;\n}\n.col-xs-5 {\n width: 41.66666667%;\n}\n.col-xs-4 {\n width: 33.33333333%;\n}\n.col-xs-3 {\n width: 25%;\n}\n.col-xs-2 {\n width: 16.66666667%;\n}\n.col-xs-1 {\n width: 8.33333333%;\n}\n.col-xs-pull-12 {\n right: 100%;\n}\n.col-xs-pull-11 {\n right: 91.66666667%;\n}\n.col-xs-pull-10 {\n right: 83.33333333%;\n}\n.col-xs-pull-9 {\n right: 75%;\n}\n.col-xs-pull-8 {\n right: 66.66666667%;\n}\n.col-xs-pull-7 {\n right: 58.33333333%;\n}\n.col-xs-pull-6 {\n right: 50%;\n}\n.col-xs-pull-5 {\n right: 41.66666667%;\n}\n.col-xs-pull-4 {\n right: 33.33333333%;\n}\n.col-xs-pull-3 {\n right: 25%;\n}\n.col-xs-pull-2 {\n right: 16.66666667%;\n}\n.col-xs-pull-1 {\n right: 8.33333333%;\n}\n.col-xs-pull-0 {\n right: auto;\n}\n.col-xs-push-12 {\n left: 100%;\n}\n.col-xs-push-11 {\n left: 91.66666667%;\n}\n.col-xs-push-10 {\n left: 83.33333333%;\n}\n.col-xs-push-9 {\n left: 75%;\n}\n.col-xs-push-8 {\n left: 66.66666667%;\n}\n.col-xs-push-7 {\n left: 58.33333333%;\n}\n.col-xs-push-6 {\n left: 50%;\n}\n.col-xs-push-5 {\n left: 41.66666667%;\n}\n.col-xs-push-4 {\n left: 33.33333333%;\n}\n.col-xs-push-3 {\n left: 25%;\n}\n.col-xs-push-2 {\n left: 16.66666667%;\n}\n.col-xs-push-1 {\n left: 8.33333333%;\n}\n.col-xs-push-0 {\n left: auto;\n}\n.col-xs-offset-12 {\n margin-left: 100%;\n}\n.col-xs-offset-11 {\n margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n margin-left: 75%;\n}\n.col-xs-offset-8 {\n margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n margin-left: 50%;\n}\n.col-xs-offset-5 {\n margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n margin-left: 25%;\n}\n.col-xs-offset-2 {\n margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n margin-left: 0%;\n}\n@media (min-width: 768px) {\n .col-sm-1,\n .col-sm-2,\n .col-sm-3,\n .col-sm-4,\n .col-sm-5,\n .col-sm-6,\n .col-sm-7,\n .col-sm-8,\n .col-sm-9,\n .col-sm-10,\n .col-sm-11,\n .col-sm-12 {\n float: left;\n }\n .col-sm-12 {\n width: 100%;\n }\n .col-sm-11 {\n width: 91.66666667%;\n }\n .col-sm-10 {\n width: 83.33333333%;\n }\n .col-sm-9 {\n width: 75%;\n }\n .col-sm-8 {\n width: 66.66666667%;\n }\n .col-sm-7 {\n width: 58.33333333%;\n }\n .col-sm-6 {\n width: 50%;\n }\n .col-sm-5 {\n width: 41.66666667%;\n }\n .col-sm-4 {\n width: 33.33333333%;\n }\n .col-sm-3 {\n width: 25%;\n }\n .col-sm-2 {\n width: 16.66666667%;\n }\n .col-sm-1 {\n width: 8.33333333%;\n }\n .col-sm-pull-12 {\n right: 100%;\n }\n .col-sm-pull-11 {\n right: 91.66666667%;\n }\n .col-sm-pull-10 {\n right: 83.33333333%;\n }\n .col-sm-pull-9 {\n right: 75%;\n }\n .col-sm-pull-8 {\n right: 66.66666667%;\n }\n .col-sm-pull-7 {\n right: 58.33333333%;\n }\n .col-sm-pull-6 {\n right: 50%;\n }\n .col-sm-pull-5 {\n right: 41.66666667%;\n }\n .col-sm-pull-4 {\n right: 33.33333333%;\n }\n .col-sm-pull-3 {\n right: 25%;\n }\n .col-sm-pull-2 {\n right: 16.66666667%;\n }\n .col-sm-pull-1 {\n right: 8.33333333%;\n }\n .col-sm-pull-0 {\n right: auto;\n }\n .col-sm-push-12 {\n left: 100%;\n }\n .col-sm-push-11 {\n left: 91.66666667%;\n }\n .col-sm-push-10 {\n left: 83.33333333%;\n }\n .col-sm-push-9 {\n left: 75%;\n }\n .col-sm-push-8 {\n left: 66.66666667%;\n }\n .col-sm-push-7 {\n left: 58.33333333%;\n }\n .col-sm-push-6 {\n left: 50%;\n }\n .col-sm-push-5 {\n left: 41.66666667%;\n }\n .col-sm-push-4 {\n left: 33.33333333%;\n }\n .col-sm-push-3 {\n left: 25%;\n }\n .col-sm-push-2 {\n left: 16.66666667%;\n }\n .col-sm-push-1 {\n left: 8.33333333%;\n }\n .col-sm-push-0 {\n left: auto;\n }\n .col-sm-offset-12 {\n margin-left: 100%;\n }\n .col-sm-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-sm-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-sm-offset-9 {\n margin-left: 75%;\n }\n .col-sm-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-sm-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-sm-offset-6 {\n margin-left: 50%;\n }\n .col-sm-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-sm-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-sm-offset-3 {\n margin-left: 25%;\n }\n .col-sm-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-sm-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-sm-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 992px) {\n .col-md-1,\n .col-md-2,\n .col-md-3,\n .col-md-4,\n .col-md-5,\n .col-md-6,\n .col-md-7,\n .col-md-8,\n .col-md-9,\n .col-md-10,\n .col-md-11,\n .col-md-12 {\n float: left;\n }\n .col-md-12 {\n width: 100%;\n }\n .col-md-11 {\n width: 91.66666667%;\n }\n .col-md-10 {\n width: 83.33333333%;\n }\n .col-md-9 {\n width: 75%;\n }\n .col-md-8 {\n width: 66.66666667%;\n }\n .col-md-7 {\n width: 58.33333333%;\n }\n .col-md-6 {\n width: 50%;\n }\n .col-md-5 {\n width: 41.66666667%;\n }\n .col-md-4 {\n width: 33.33333333%;\n }\n .col-md-3 {\n width: 25%;\n }\n .col-md-2 {\n width: 16.66666667%;\n }\n .col-md-1 {\n width: 8.33333333%;\n }\n .col-md-pull-12 {\n right: 100%;\n }\n .col-md-pull-11 {\n right: 91.66666667%;\n }\n .col-md-pull-10 {\n right: 83.33333333%;\n }\n .col-md-pull-9 {\n right: 75%;\n }\n .col-md-pull-8 {\n right: 66.66666667%;\n }\n .col-md-pull-7 {\n right: 58.33333333%;\n }\n .col-md-pull-6 {\n right: 50%;\n }\n .col-md-pull-5 {\n right: 41.66666667%;\n }\n .col-md-pull-4 {\n right: 33.33333333%;\n }\n .col-md-pull-3 {\n right: 25%;\n }\n .col-md-pull-2 {\n right: 16.66666667%;\n }\n .col-md-pull-1 {\n right: 8.33333333%;\n }\n .col-md-pull-0 {\n right: auto;\n }\n .col-md-push-12 {\n left: 100%;\n }\n .col-md-push-11 {\n left: 91.66666667%;\n }\n .col-md-push-10 {\n left: 83.33333333%;\n }\n .col-md-push-9 {\n left: 75%;\n }\n .col-md-push-8 {\n left: 66.66666667%;\n }\n .col-md-push-7 {\n left: 58.33333333%;\n }\n .col-md-push-6 {\n left: 50%;\n }\n .col-md-push-5 {\n left: 41.66666667%;\n }\n .col-md-push-4 {\n left: 33.33333333%;\n }\n .col-md-push-3 {\n left: 25%;\n }\n .col-md-push-2 {\n left: 16.66666667%;\n }\n .col-md-push-1 {\n left: 8.33333333%;\n }\n .col-md-push-0 {\n left: auto;\n }\n .col-md-offset-12 {\n margin-left: 100%;\n }\n .col-md-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-md-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-md-offset-9 {\n margin-left: 75%;\n }\n .col-md-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-md-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-md-offset-6 {\n margin-left: 50%;\n }\n .col-md-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-md-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-md-offset-3 {\n margin-left: 25%;\n }\n .col-md-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-md-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-md-offset-0 {\n margin-left: 0%;\n }\n}\n@media (min-width: 1200px) {\n .col-lg-1,\n .col-lg-2,\n .col-lg-3,\n .col-lg-4,\n .col-lg-5,\n .col-lg-6,\n .col-lg-7,\n .col-lg-8,\n .col-lg-9,\n .col-lg-10,\n .col-lg-11,\n .col-lg-12 {\n float: left;\n }\n .col-lg-12 {\n width: 100%;\n }\n .col-lg-11 {\n width: 91.66666667%;\n }\n .col-lg-10 {\n width: 83.33333333%;\n }\n .col-lg-9 {\n width: 75%;\n }\n .col-lg-8 {\n width: 66.66666667%;\n }\n .col-lg-7 {\n width: 58.33333333%;\n }\n .col-lg-6 {\n width: 50%;\n }\n .col-lg-5 {\n width: 41.66666667%;\n }\n .col-lg-4 {\n width: 33.33333333%;\n }\n .col-lg-3 {\n width: 25%;\n }\n .col-lg-2 {\n width: 16.66666667%;\n }\n .col-lg-1 {\n width: 8.33333333%;\n }\n .col-lg-pull-12 {\n right: 100%;\n }\n .col-lg-pull-11 {\n right: 91.66666667%;\n }\n .col-lg-pull-10 {\n right: 83.33333333%;\n }\n .col-lg-pull-9 {\n right: 75%;\n }\n .col-lg-pull-8 {\n right: 66.66666667%;\n }\n .col-lg-pull-7 {\n right: 58.33333333%;\n }\n .col-lg-pull-6 {\n right: 50%;\n }\n .col-lg-pull-5 {\n right: 41.66666667%;\n }\n .col-lg-pull-4 {\n right: 33.33333333%;\n }\n .col-lg-pull-3 {\n right: 25%;\n }\n .col-lg-pull-2 {\n right: 16.66666667%;\n }\n .col-lg-pull-1 {\n right: 8.33333333%;\n }\n .col-lg-pull-0 {\n right: auto;\n }\n .col-lg-push-12 {\n left: 100%;\n }\n .col-lg-push-11 {\n left: 91.66666667%;\n }\n .col-lg-push-10 {\n left: 83.33333333%;\n }\n .col-lg-push-9 {\n left: 75%;\n }\n .col-lg-push-8 {\n left: 66.66666667%;\n }\n .col-lg-push-7 {\n left: 58.33333333%;\n }\n .col-lg-push-6 {\n left: 50%;\n }\n .col-lg-push-5 {\n left: 41.66666667%;\n }\n .col-lg-push-4 {\n left: 33.33333333%;\n }\n .col-lg-push-3 {\n left: 25%;\n }\n .col-lg-push-2 {\n left: 16.66666667%;\n }\n .col-lg-push-1 {\n left: 8.33333333%;\n }\n .col-lg-push-0 {\n left: auto;\n }\n .col-lg-offset-12 {\n margin-left: 100%;\n }\n .col-lg-offset-11 {\n margin-left: 91.66666667%;\n }\n .col-lg-offset-10 {\n margin-left: 83.33333333%;\n }\n .col-lg-offset-9 {\n margin-left: 75%;\n }\n .col-lg-offset-8 {\n margin-left: 66.66666667%;\n }\n .col-lg-offset-7 {\n margin-left: 58.33333333%;\n }\n .col-lg-offset-6 {\n margin-left: 50%;\n }\n .col-lg-offset-5 {\n margin-left: 41.66666667%;\n }\n .col-lg-offset-4 {\n margin-left: 33.33333333%;\n }\n .col-lg-offset-3 {\n margin-left: 25%;\n }\n .col-lg-offset-2 {\n margin-left: 16.66666667%;\n }\n .col-lg-offset-1 {\n margin-left: 8.33333333%;\n }\n .col-lg-offset-0 {\n margin-left: 0%;\n }\n}\ntable {\n background-color: transparent;\n}\ntable col[class*=\"col-\"] {\n position: static;\n display: table-column;\n float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n position: static;\n display: table-cell;\n float: none;\n}\ncaption {\n padding-top: 8px;\n padding-bottom: 8px;\n color: #777777;\n text-align: left;\n}\nth {\n text-align: left;\n}\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n padding: 8px;\n line-height: 1.42857143;\n vertical-align: top;\n border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n border-top: 0;\n}\n.table > tbody + tbody {\n border-top: 2px solid #ddd;\n}\n.table .table {\n background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n padding: 5px;\n}\n.table-bordered {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n background-color: #f5f5f5;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n background-color: #ebcccc;\n}\n.table-responsive {\n min-height: 0.01%;\n overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n .table-responsive {\n width: 100%;\n margin-bottom: 15px;\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid #ddd;\n }\n .table-responsive > .table {\n margin-bottom: 0;\n }\n .table-responsive > .table > thead > tr > th,\n .table-responsive > .table > tbody > tr > th,\n .table-responsive > .table > tfoot > tr > th,\n .table-responsive > .table > thead > tr > td,\n .table-responsive > .table > tbody > tr > td,\n .table-responsive > .table > tfoot > tr > td {\n white-space: nowrap;\n }\n .table-responsive > .table-bordered {\n border: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:first-child,\n .table-responsive > .table-bordered > tbody > tr > th:first-child,\n .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n .table-responsive > .table-bordered > thead > tr > td:first-child,\n .table-responsive > .table-bordered > tbody > tr > td:first-child,\n .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n }\n .table-responsive > .table-bordered > thead > tr > th:last-child,\n .table-responsive > .table-bordered > tbody > tr > th:last-child,\n .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n .table-responsive > .table-bordered > thead > tr > td:last-child,\n .table-responsive > .table-bordered > tbody > tr > td:last-child,\n .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n }\n .table-responsive > .table-bordered > tbody > tr:last-child > th,\n .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n .table-responsive > .table-bordered > tbody > tr:last-child > td,\n .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n border-bottom: 0;\n }\n}\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: 20px;\n font-size: 21px;\n line-height: inherit;\n color: #333333;\n border: 0;\n border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n display: inline-block;\n max-width: 100%;\n margin-bottom: 5px;\n font-weight: 700;\n}\ninput[type=\"search\"] {\n -webkit-box-sizing: border-box;\n -moz-box-sizing: border-box;\n box-sizing: border-box;\n -webkit-appearance: none;\n appearance: none;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9;\n line-height: normal;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n cursor: not-allowed;\n}\ninput[type=\"file\"] {\n display: block;\n}\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\nselect[multiple],\nselect[size] {\n height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\noutput {\n display: block;\n padding-top: 7px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n}\n.form-control {\n display: block;\n width: 100%;\n height: 34px;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n color: #555555;\n background-color: #fff;\n background-image: none;\n border: 1px solid #ccc;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n border-color: #66afe9;\n outline: 0;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.form-control::-moz-placeholder {\n color: #999;\n opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n color: #999;\n}\n.form-control::-webkit-input-placeholder {\n color: #999;\n}\n.form-control::-ms-expand {\n background-color: transparent;\n border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n background-color: #eeeeee;\n opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n cursor: not-allowed;\n}\ntextarea.form-control {\n height: auto;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n input[type=\"date\"].form-control,\n input[type=\"time\"].form-control,\n input[type=\"datetime-local\"].form-control,\n input[type=\"month\"].form-control {\n line-height: 34px;\n }\n input[type=\"date\"].input-sm,\n input[type=\"time\"].input-sm,\n input[type=\"datetime-local\"].input-sm,\n input[type=\"month\"].input-sm,\n .input-group-sm input[type=\"date\"],\n .input-group-sm input[type=\"time\"],\n .input-group-sm input[type=\"datetime-local\"],\n .input-group-sm input[type=\"month\"] {\n line-height: 30px;\n }\n input[type=\"date\"].input-lg,\n input[type=\"time\"].input-lg,\n input[type=\"datetime-local\"].input-lg,\n input[type=\"month\"].input-lg,\n .input-group-lg input[type=\"date\"],\n .input-group-lg input[type=\"time\"],\n .input-group-lg input[type=\"datetime-local\"],\n .input-group-lg input[type=\"month\"] {\n line-height: 46px;\n }\n}\n.form-group {\n margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n position: relative;\n display: block;\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n cursor: not-allowed;\n}\n.radio label,\n.checkbox label {\n min-height: 20px;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: 400;\n cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-top: 4px \\9;\n margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n position: relative;\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: 400;\n vertical-align: middle;\n cursor: pointer;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n cursor: not-allowed;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px;\n}\n.form-control-static {\n min-height: 34px;\n padding-top: 7px;\n padding-bottom: 7px;\n margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n padding-right: 0;\n padding-left: 0;\n}\n.input-sm {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-sm {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n height: auto;\n}\n.form-group-sm .form-control {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.form-group-sm select.form-control {\n height: 30px;\n line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n height: auto;\n}\n.form-group-sm .form-control-static {\n height: 30px;\n min-height: 32px;\n padding: 6px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.input-lg {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-lg {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n height: auto;\n}\n.form-group-lg .form-control {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.form-group-lg select.form-control {\n height: 46px;\n line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n height: auto;\n}\n.form-group-lg .form-control-static {\n height: 46px;\n min-height: 38px;\n padding: 11px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.has-feedback {\n position: relative;\n}\n.has-feedback .form-control {\n padding-right: 42.5px;\n}\n.form-control-feedback {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n display: block;\n width: 34px;\n height: 34px;\n line-height: 34px;\n text-align: center;\n pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n width: 46px;\n height: 46px;\n line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n width: 30px;\n height: 30px;\n line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n color: #3c763d;\n}\n.has-success .form-control {\n border-color: #3c763d;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-success .form-control:focus {\n border-color: #2b542c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n color: #8a6d3b;\n}\n.has-warning .form-control {\n border-color: #8a6d3b;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-warning .form-control:focus {\n border-color: #66512c;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n color: #a94442;\n}\n.has-error .form-control {\n border-color: #a94442;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n.has-error .form-control:focus {\n border-color: #843534;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n color: #a94442;\n background-color: #f2dede;\n border-color: #a94442;\n}\n.has-error .form-control-feedback {\n color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n top: 0;\n}\n.help-block {\n display: block;\n margin-top: 5px;\n margin-bottom: 10px;\n color: #737373;\n}\n@media (min-width: 768px) {\n .form-inline .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .form-inline .form-control-static {\n display: inline-block;\n }\n .form-inline .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .form-inline .input-group .input-group-addon,\n .form-inline .input-group .input-group-btn,\n .form-inline .input-group .form-control {\n width: auto;\n }\n .form-inline .input-group > .form-control {\n width: 100%;\n }\n .form-inline .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio,\n .form-inline .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .form-inline .radio label,\n .form-inline .checkbox label {\n padding-left: 0;\n }\n .form-inline .radio input[type=\"radio\"],\n .form-inline .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .form-inline .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n padding-top: 7px;\n margin-top: 0;\n margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n min-height: 27px;\n}\n.form-horizontal .form-group {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .control-label {\n padding-top: 7px;\n margin-bottom: 0;\n text-align: right;\n }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n right: 15px;\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-lg .control-label {\n padding-top: 11px;\n font-size: 18px;\n }\n}\n@media (min-width: 768px) {\n .form-horizontal .form-group-sm .control-label {\n padding-top: 6px;\n font-size: 12px;\n }\n}\n.btn {\n display: inline-block;\n margin-bottom: 0;\n font-weight: normal;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n touch-action: manipulation;\n cursor: pointer;\n background-image: none;\n border: 1px solid transparent;\n padding: 6px 12px;\n font-size: 14px;\n line-height: 1.42857143;\n border-radius: 4px;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n color: #333;\n text-decoration: none;\n}\n.btn:active,\n.btn.active {\n background-image: none;\n outline: 0;\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n cursor: not-allowed;\n filter: alpha(opacity=65);\n opacity: 0.65;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n pointer-events: none;\n}\n.btn-default {\n color: #333;\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n color: #333;\n background-color: #e6e6e6;\n border-color: #8c8c8c;\n}\n.btn-default:hover {\n color: #333;\n background-color: #e6e6e6;\n border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n color: #333;\n background-color: #e6e6e6;\n background-image: none;\n border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n color: #333;\n background-color: #d4d4d4;\n border-color: #8c8c8c;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n background-color: #fff;\n border-color: #ccc;\n}\n.btn-default .badge {\n color: #fff;\n background-color: #333;\n}\n.btn-primary {\n color: #fff;\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n color: #fff;\n background-color: #286090;\n border-color: #122b40;\n}\n.btn-primary:hover {\n color: #fff;\n background-color: #286090;\n border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n color: #fff;\n background-color: #286090;\n background-image: none;\n border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n color: #fff;\n background-color: #204d74;\n border-color: #122b40;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n background-color: #337ab7;\n border-color: #2e6da4;\n}\n.btn-primary .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.btn-success {\n color: #fff;\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n color: #fff;\n background-color: #449d44;\n border-color: #255625;\n}\n.btn-success:hover {\n color: #fff;\n background-color: #449d44;\n border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n color: #fff;\n background-color: #449d44;\n background-image: none;\n border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n color: #fff;\n background-color: #398439;\n border-color: #255625;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n background-color: #5cb85c;\n border-color: #4cae4c;\n}\n.btn-success .badge {\n color: #5cb85c;\n background-color: #fff;\n}\n.btn-info {\n color: #fff;\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n color: #fff;\n background-color: #31b0d5;\n border-color: #1b6d85;\n}\n.btn-info:hover {\n color: #fff;\n background-color: #31b0d5;\n border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n color: #fff;\n background-color: #31b0d5;\n background-image: none;\n border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n color: #fff;\n background-color: #269abc;\n border-color: #1b6d85;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n background-color: #5bc0de;\n border-color: #46b8da;\n}\n.btn-info .badge {\n color: #5bc0de;\n background-color: #fff;\n}\n.btn-warning {\n color: #fff;\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n color: #fff;\n background-color: #ec971f;\n border-color: #985f0d;\n}\n.btn-warning:hover {\n color: #fff;\n background-color: #ec971f;\n border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n color: #fff;\n background-color: #ec971f;\n background-image: none;\n border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n color: #fff;\n background-color: #d58512;\n border-color: #985f0d;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n background-color: #f0ad4e;\n border-color: #eea236;\n}\n.btn-warning .badge {\n color: #f0ad4e;\n background-color: #fff;\n}\n.btn-danger {\n color: #fff;\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n color: #fff;\n background-color: #c9302c;\n border-color: #761c19;\n}\n.btn-danger:hover {\n color: #fff;\n background-color: #c9302c;\n border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n color: #fff;\n background-color: #c9302c;\n background-image: none;\n border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n color: #fff;\n background-color: #ac2925;\n border-color: #761c19;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n background-color: #d9534f;\n border-color: #d43f3a;\n}\n.btn-danger .badge {\n color: #d9534f;\n background-color: #fff;\n}\n.btn-link {\n font-weight: 400;\n color: #337ab7;\n border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n background-color: transparent;\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n color: #23527c;\n text-decoration: underline;\n background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n color: #777777;\n text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n padding: 1px 5px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\n.btn-block {\n display: block;\n width: 100%;\n}\n.btn-block + .btn-block {\n margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n width: 100%;\n}\n.fade {\n opacity: 0;\n -webkit-transition: opacity 0.15s linear;\n -o-transition: opacity 0.15s linear;\n transition: opacity 0.15s linear;\n}\n.fade.in {\n opacity: 1;\n}\n.collapse {\n display: none;\n}\n.collapse.in {\n display: block;\n}\ntr.collapse.in {\n display: table-row;\n}\ntbody.collapse.in {\n display: table-row-group;\n}\n.collapsing {\n position: relative;\n height: 0;\n overflow: hidden;\n -webkit-transition-property: height, visibility;\n transition-property: height, visibility;\n -webkit-transition-duration: 0.35s;\n transition-duration: 0.35s;\n -webkit-transition-timing-function: ease;\n transition-timing-function: ease;\n}\n.caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px dashed;\n border-top: 4px solid \\9;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n position: relative;\n}\n.dropdown-toggle:focus {\n outline: 0;\n}\n.dropdown-menu {\n position: absolute;\n top: 100%;\n left: 0;\n z-index: 1000;\n display: none;\n float: left;\n min-width: 160px;\n padding: 5px 0;\n margin: 2px 0 0;\n font-size: 14px;\n text-align: left;\n list-style: none;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.15);\n border-radius: 4px;\n -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n}\n.dropdown-menu.pull-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu .divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n display: block;\n padding: 3px 20px;\n clear: both;\n font-weight: 400;\n line-height: 1.42857143;\n color: #333333;\n white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n color: #262626;\n text-decoration: none;\n background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n color: #fff;\n text-decoration: none;\n background-color: #337ab7;\n outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n color: #777777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n background-image: none;\n filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n display: block;\n}\n.open > a {\n outline: 0;\n}\n.dropdown-menu-right {\n right: 0;\n left: auto;\n}\n.dropdown-menu-left {\n right: auto;\n left: 0;\n}\n.dropdown-header {\n display: block;\n padding: 3px 20px;\n font-size: 12px;\n line-height: 1.42857143;\n color: #777777;\n white-space: nowrap;\n}\n.dropdown-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 990;\n}\n.pull-right > .dropdown-menu {\n right: 0;\n left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n content: \"\";\n border-top: 0;\n border-bottom: 4px dashed;\n border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n top: auto;\n bottom: 100%;\n margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n .navbar-right .dropdown-menu {\n right: 0;\n left: auto;\n }\n .navbar-right .dropdown-menu-left {\n right: auto;\n left: 0;\n }\n}\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-block;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n margin-left: -1px;\n}\n.btn-toolbar {\n margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n border-radius: 0;\n}\n.btn-group > .btn:first-child {\n margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n padding-right: 8px;\n padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n padding-right: 12px;\n padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n -webkit-box-shadow: none;\n box-shadow: none;\n}\n.btn .caret {\n margin-left: 0;\n}\n.btn-lg .caret {\n border-width: 5px 5px 0;\n border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n display: block;\n float: none;\n width: 100%;\n max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n margin-top: -1px;\n margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.btn-group-justified {\n display: table;\n width: 100%;\n table-layout: fixed;\n border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n display: table-cell;\n float: none;\n width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.input-group {\n position: relative;\n display: table;\n border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n float: none;\n padding-right: 0;\n padding-left: 0;\n}\n.input-group .form-control {\n position: relative;\n z-index: 2;\n float: left;\n width: 100%;\n margin-bottom: 0;\n}\n.input-group .form-control:focus {\n z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n height: 46px;\n line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n height: 30px;\n line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n width: 1%;\n white-space: nowrap;\n vertical-align: middle;\n}\n.input-group-addon {\n padding: 6px 12px;\n font-size: 14px;\n font-weight: 400;\n line-height: 1;\n color: #555555;\n text-align: center;\n background-color: #eeeeee;\n border: 1px solid #ccc;\n border-radius: 4px;\n}\n.input-group-addon.input-sm {\n padding: 5px 10px;\n font-size: 12px;\n border-radius: 3px;\n}\n.input-group-addon.input-lg {\n padding: 10px 16px;\n font-size: 18px;\n border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n border-left: 0;\n}\n.input-group-btn {\n position: relative;\n font-size: 0;\n white-space: nowrap;\n}\n.input-group-btn > .btn {\n position: relative;\n}\n.input-group-btn > .btn + .btn {\n margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n z-index: 2;\n margin-left: -1px;\n}\n.nav {\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n.nav > li {\n position: relative;\n display: block;\n}\n.nav > li > a {\n position: relative;\n display: block;\n padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.nav > li.disabled > a {\n color: #777777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n color: #777777;\n text-decoration: none;\n cursor: not-allowed;\n background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n background-color: #eeeeee;\n border-color: #337ab7;\n}\n.nav .nav-divider {\n height: 1px;\n margin: 9px 0;\n overflow: hidden;\n background-color: #e5e5e5;\n}\n.nav > li > a > img {\n max-width: none;\n}\n.nav-tabs {\n border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n float: left;\n margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n margin-right: 2px;\n line-height: 1.42857143;\n border: 1px solid transparent;\n border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n border-color: #eeeeee #eeeeee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n color: #555555;\n cursor: default;\n background-color: #fff;\n border: 1px solid #ddd;\n border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n width: 100%;\n border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n float: none;\n}\n.nav-tabs.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-tabs.nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs.nav-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs.nav-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs.nav-justified > .active > a,\n .nav-tabs.nav-justified > .active > a:hover,\n .nav-tabs.nav-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.nav-pills > li {\n float: left;\n}\n.nav-pills > li > a {\n border-radius: 4px;\n}\n.nav-pills > li + li {\n margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n color: #fff;\n background-color: #337ab7;\n}\n.nav-stacked > li {\n float: none;\n}\n.nav-stacked > li + li {\n margin-top: 2px;\n margin-left: 0;\n}\n.nav-justified {\n width: 100%;\n}\n.nav-justified > li {\n float: none;\n}\n.nav-justified > li > a {\n margin-bottom: 5px;\n text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n top: auto;\n left: auto;\n}\n@media (min-width: 768px) {\n .nav-justified > li {\n display: table-cell;\n width: 1%;\n }\n .nav-justified > li > a {\n margin-bottom: 0;\n }\n}\n.nav-tabs-justified {\n border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n margin-right: 0;\n border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n .nav-tabs-justified > li > a {\n border-bottom: 1px solid #ddd;\n border-radius: 4px 4px 0 0;\n }\n .nav-tabs-justified > .active > a,\n .nav-tabs-justified > .active > a:hover,\n .nav-tabs-justified > .active > a:focus {\n border-bottom-color: #fff;\n }\n}\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n.nav-tabs .dropdown-menu {\n margin-top: -1px;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar {\n position: relative;\n min-height: 50px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n .navbar {\n border-radius: 4px;\n }\n}\n@media (min-width: 768px) {\n .navbar-header {\n float: left;\n }\n}\n.navbar-collapse {\n padding-right: 15px;\n padding-left: 15px;\n overflow-x: visible;\n border-top: 1px solid transparent;\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n -webkit-overflow-scrolling: touch;\n}\n.navbar-collapse.in {\n overflow-y: auto;\n}\n@media (min-width: 768px) {\n .navbar-collapse {\n width: auto;\n border-top: 0;\n box-shadow: none;\n }\n .navbar-collapse.collapse {\n display: block !important;\n height: auto !important;\n padding-bottom: 0;\n overflow: visible !important;\n }\n .navbar-collapse.in {\n overflow-y: visible;\n }\n .navbar-fixed-top .navbar-collapse,\n .navbar-static-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n padding-right: 0;\n padding-left: 0;\n }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n position: fixed;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n .navbar-fixed-top .navbar-collapse,\n .navbar-fixed-bottom .navbar-collapse {\n max-height: 200px;\n }\n}\n@media (min-width: 768px) {\n .navbar-fixed-top,\n .navbar-fixed-bottom {\n border-radius: 0;\n }\n}\n.navbar-fixed-top {\n top: 0;\n border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n bottom: 0;\n margin-bottom: 0;\n border-width: 1px 0 0;\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n margin-right: -15px;\n margin-left: -15px;\n}\n@media (min-width: 768px) {\n .container > .navbar-header,\n .container-fluid > .navbar-header,\n .container > .navbar-collapse,\n .container-fluid > .navbar-collapse {\n margin-right: 0;\n margin-left: 0;\n }\n}\n.navbar-static-top {\n z-index: 1000;\n border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n .navbar-static-top {\n border-radius: 0;\n }\n}\n.navbar-brand {\n float: left;\n height: 50px;\n padding: 15px 15px;\n font-size: 18px;\n line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n text-decoration: none;\n}\n.navbar-brand > img {\n display: block;\n}\n@media (min-width: 768px) {\n .navbar > .container .navbar-brand,\n .navbar > .container-fluid .navbar-brand {\n margin-left: -15px;\n }\n}\n.navbar-toggle {\n position: relative;\n float: right;\n padding: 9px 10px;\n margin-right: 15px;\n margin-top: 8px;\n margin-bottom: 8px;\n background-color: transparent;\n background-image: none;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.navbar-toggle:focus {\n outline: 0;\n}\n.navbar-toggle .icon-bar {\n display: block;\n width: 22px;\n height: 2px;\n border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n margin-top: 4px;\n}\n@media (min-width: 768px) {\n .navbar-toggle {\n display: none;\n }\n}\n.navbar-nav {\n margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n padding-top: 10px;\n padding-bottom: 10px;\n line-height: 20px;\n}\n@media (max-width: 767px) {\n .navbar-nav .open .dropdown-menu {\n position: static;\n float: none;\n width: auto;\n margin-top: 0;\n background-color: transparent;\n border: 0;\n box-shadow: none;\n }\n .navbar-nav .open .dropdown-menu > li > a,\n .navbar-nav .open .dropdown-menu .dropdown-header {\n padding: 5px 15px 5px 25px;\n }\n .navbar-nav .open .dropdown-menu > li > a {\n line-height: 20px;\n }\n .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-nav .open .dropdown-menu > li > a:focus {\n background-image: none;\n }\n}\n@media (min-width: 768px) {\n .navbar-nav {\n float: left;\n margin: 0;\n }\n .navbar-nav > li {\n float: left;\n }\n .navbar-nav > li > a {\n padding-top: 15px;\n padding-bottom: 15px;\n }\n}\n.navbar-form {\n padding: 10px 15px;\n margin-right: -15px;\n margin-left: -15px;\n border-top: 1px solid transparent;\n border-bottom: 1px solid transparent;\n -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n margin-top: 8px;\n margin-bottom: 8px;\n}\n@media (min-width: 768px) {\n .navbar-form .form-group {\n display: inline-block;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .form-control {\n display: inline-block;\n width: auto;\n vertical-align: middle;\n }\n .navbar-form .form-control-static {\n display: inline-block;\n }\n .navbar-form .input-group {\n display: inline-table;\n vertical-align: middle;\n }\n .navbar-form .input-group .input-group-addon,\n .navbar-form .input-group .input-group-btn,\n .navbar-form .input-group .form-control {\n width: auto;\n }\n .navbar-form .input-group > .form-control {\n width: 100%;\n }\n .navbar-form .control-label {\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio,\n .navbar-form .checkbox {\n display: inline-block;\n margin-top: 0;\n margin-bottom: 0;\n vertical-align: middle;\n }\n .navbar-form .radio label,\n .navbar-form .checkbox label {\n padding-left: 0;\n }\n .navbar-form .radio input[type=\"radio\"],\n .navbar-form .checkbox input[type=\"checkbox\"] {\n position: relative;\n margin-left: 0;\n }\n .navbar-form .has-feedback .form-control-feedback {\n top: 0;\n }\n}\n@media (max-width: 767px) {\n .navbar-form .form-group {\n margin-bottom: 5px;\n }\n .navbar-form .form-group:last-child {\n margin-bottom: 0;\n }\n}\n@media (min-width: 768px) {\n .navbar-form {\n width: auto;\n padding-top: 0;\n padding-bottom: 0;\n margin-right: 0;\n margin-left: 0;\n border: 0;\n -webkit-box-shadow: none;\n box-shadow: none;\n }\n}\n.navbar-nav > li > .dropdown-menu {\n margin-top: 0;\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n margin-bottom: 0;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.navbar-btn {\n margin-top: 8px;\n margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n margin-top: 14px;\n margin-bottom: 14px;\n}\n.navbar-text {\n margin-top: 15px;\n margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n .navbar-text {\n float: left;\n margin-right: 15px;\n margin-left: 15px;\n }\n}\n@media (min-width: 768px) {\n .navbar-left {\n float: left !important;\n }\n .navbar-right {\n float: right !important;\n margin-right: -15px;\n }\n .navbar-right ~ .navbar-right {\n margin-right: 0;\n }\n}\n.navbar-default {\n background-color: #f8f8f8;\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n color: #5e5e5e;\n background-color: transparent;\n}\n.navbar-default .navbar-text {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n color: #333;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n color: #555;\n background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n color: #777;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #333;\n background-color: transparent;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #555;\n background-color: #e7e7e7;\n }\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #ccc;\n background-color: transparent;\n }\n}\n.navbar-default .navbar-toggle {\n border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n border-color: #e7e7e7;\n}\n.navbar-default .navbar-link {\n color: #777;\n}\n.navbar-default .navbar-link:hover {\n color: #333;\n}\n.navbar-default .btn-link {\n color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n color: #ccc;\n}\n.navbar-inverse {\n background-color: #222;\n border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n color: #fff;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n color: #fff;\n background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n color: #fff;\n background-color: #080808;\n}\n@media (max-width: 767px) {\n .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n border-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n color: #9d9d9d;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n color: #fff;\n background-color: transparent;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n color: #fff;\n background-color: #080808;\n }\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n color: #444;\n background-color: transparent;\n }\n}\n.navbar-inverse .navbar-toggle {\n border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n border-color: #101010;\n}\n.navbar-inverse .navbar-link {\n color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n color: #fff;\n}\n.navbar-inverse .btn-link {\n color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n color: #444;\n}\n.breadcrumb {\n padding: 8px 15px;\n margin-bottom: 20px;\n list-style: none;\n background-color: #f5f5f5;\n border-radius: 4px;\n}\n.breadcrumb > li {\n display: inline-block;\n}\n.breadcrumb > li + li:before {\n padding: 0 5px;\n color: #ccc;\n content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n color: #777777;\n}\n.pagination {\n display: inline-block;\n padding-left: 0;\n margin: 20px 0;\n border-radius: 4px;\n}\n.pagination > li {\n display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n position: relative;\n float: left;\n padding: 6px 12px;\n margin-left: -1px;\n line-height: 1.42857143;\n color: #337ab7;\n text-decoration: none;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n z-index: 2;\n color: #23527c;\n background-color: #eeeeee;\n border-color: #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n margin-left: 0;\n border-top-left-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n border-top-right-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n z-index: 3;\n color: #fff;\n cursor: default;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n color: #777777;\n cursor: not-allowed;\n background-color: #fff;\n border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n padding: 10px 16px;\n font-size: 18px;\n line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n padding: 5px 10px;\n font-size: 12px;\n line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n border-top-left-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n border-top-right-radius: 3px;\n border-bottom-right-radius: 3px;\n}\n.pager {\n padding-left: 0;\n margin: 20px 0;\n text-align: center;\n list-style: none;\n}\n.pager li {\n display: inline;\n}\n.pager li > a,\n.pager li > span {\n display: inline-block;\n padding: 5px 14px;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n text-decoration: none;\n background-color: #eeeeee;\n}\n.pager .next > a,\n.pager .next > span {\n float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n color: #777777;\n cursor: not-allowed;\n background-color: #fff;\n}\n.label {\n display: inline;\n padding: 0.2em 0.6em 0.3em;\n font-size: 75%;\n font-weight: 700;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: 0.25em;\n}\na.label:hover,\na.label:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.label:empty {\n display: none;\n}\n.btn .label {\n position: relative;\n top: -1px;\n}\n.label-default {\n background-color: #777777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n background-color: #5e5e5e;\n}\n.label-primary {\n background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n background-color: #286090;\n}\n.label-success {\n background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n background-color: #449d44;\n}\n.label-info {\n background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n background-color: #31b0d5;\n}\n.label-warning {\n background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n background-color: #ec971f;\n}\n.label-danger {\n background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n background-color: #c9302c;\n}\n.badge {\n display: inline-block;\n min-width: 10px;\n padding: 3px 7px;\n font-size: 12px;\n font-weight: bold;\n line-height: 1;\n color: #fff;\n text-align: center;\n white-space: nowrap;\n vertical-align: middle;\n background-color: #777777;\n border-radius: 10px;\n}\n.badge:empty {\n display: none;\n}\n.btn .badge {\n position: relative;\n top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n top: 0;\n padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n color: #fff;\n text-decoration: none;\n cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.list-group-item > .badge {\n float: right;\n}\n.list-group-item > .badge + .badge {\n margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n margin-left: 3px;\n}\n.jumbotron {\n padding-top: 30px;\n padding-bottom: 30px;\n margin-bottom: 30px;\n color: inherit;\n background-color: #eeeeee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n color: inherit;\n}\n.jumbotron p {\n margin-bottom: 15px;\n font-size: 21px;\n font-weight: 200;\n}\n.jumbotron > hr {\n border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n padding-right: 15px;\n padding-left: 15px;\n border-radius: 6px;\n}\n.jumbotron .container {\n max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n .jumbotron {\n padding-top: 48px;\n padding-bottom: 48px;\n }\n .container .jumbotron,\n .container-fluid .jumbotron {\n padding-right: 60px;\n padding-left: 60px;\n }\n .jumbotron h1,\n .jumbotron .h1 {\n font-size: 63px;\n }\n}\n.thumbnail {\n display: block;\n padding: 4px;\n margin-bottom: 20px;\n line-height: 1.42857143;\n background-color: #fff;\n border: 1px solid #ddd;\n border-radius: 4px;\n -webkit-transition: border 0.2s ease-in-out;\n -o-transition: border 0.2s ease-in-out;\n transition: border 0.2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n margin-right: auto;\n margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n border-color: #337ab7;\n}\n.thumbnail .caption {\n padding: 9px;\n color: #333333;\n}\n.alert {\n padding: 15px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n}\n.alert h4 {\n margin-top: 0;\n color: inherit;\n}\n.alert .alert-link {\n font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n margin-bottom: 0;\n}\n.alert > p + p {\n margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n position: relative;\n top: -2px;\n right: -21px;\n color: inherit;\n}\n.alert-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.alert-success hr {\n border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n color: #2b542c;\n}\n.alert-info {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.alert-info hr {\n border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n color: #245269;\n}\n.alert-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.alert-warning hr {\n border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n color: #66512c;\n}\n.alert-danger {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.alert-danger hr {\n border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n@keyframes progress-bar-stripes {\n from {\n background-position: 40px 0;\n }\n to {\n background-position: 0 0;\n }\n}\n.progress {\n height: 20px;\n margin-bottom: 20px;\n overflow: hidden;\n background-color: #f5f5f5;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n.progress-bar {\n float: left;\n width: 0%;\n height: 100%;\n font-size: 12px;\n line-height: 20px;\n color: #fff;\n text-align: center;\n background-color: #337ab7;\n -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n -webkit-transition: width 0.6s ease;\n -o-transition: width 0.6s ease;\n transition: width 0.6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n -webkit-animation: progress-bar-stripes 2s linear infinite;\n -o-animation: progress-bar-stripes 2s linear infinite;\n animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n.media {\n margin-top: 15px;\n}\n.media:first-child {\n margin-top: 0;\n}\n.media,\n.media-body {\n overflow: hidden;\n zoom: 1;\n}\n.media-body {\n width: 10000px;\n}\n.media-object {\n display: block;\n}\n.media-object.img-thumbnail {\n max-width: none;\n}\n.media-right,\n.media > .pull-right {\n padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n display: table-cell;\n vertical-align: top;\n}\n.media-middle {\n vertical-align: middle;\n}\n.media-bottom {\n vertical-align: bottom;\n}\n.media-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.media-list {\n padding-left: 0;\n list-style: none;\n}\n.list-group {\n padding-left: 0;\n margin-bottom: 20px;\n}\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n margin-bottom: -1px;\n background-color: #fff;\n border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n margin-bottom: 0;\n border-bottom-right-radius: 4px;\n border-bottom-left-radius: 4px;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n color: #777777;\n cursor: not-allowed;\n background-color: #eeeeee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n color: #777777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n z-index: 2;\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n color: #c7ddef;\n}\na.list-group-item,\nbutton.list-group-item {\n color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n color: #555;\n text-decoration: none;\n background-color: #f5f5f5;\n}\nbutton.list-group-item {\n width: 100%;\n text-align: left;\n}\n.list-group-item-success {\n color: #3c763d;\n background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n color: #3c763d;\n background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n color: #fff;\n background-color: #3c763d;\n border-color: #3c763d;\n}\n.list-group-item-info {\n color: #31708f;\n background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n color: #31708f;\n background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n color: #fff;\n background-color: #31708f;\n border-color: #31708f;\n}\n.list-group-item-warning {\n color: #8a6d3b;\n background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n color: #8a6d3b;\n background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n color: #fff;\n background-color: #8a6d3b;\n border-color: #8a6d3b;\n}\n.list-group-item-danger {\n color: #a94442;\n background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n color: #a94442;\n background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n color: #fff;\n background-color: #a94442;\n border-color: #a94442;\n}\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n.panel {\n margin-bottom: 20px;\n background-color: #fff;\n border: 1px solid transparent;\n border-radius: 4px;\n -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.panel-body {\n padding: 15px;\n}\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n color: inherit;\n}\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: 16px;\n color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n color: inherit;\n}\n.panel-footer {\n padding: 10px 15px;\n background-color: #f5f5f5;\n border-top: 1px solid #ddd;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n border-top: 0;\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n border-bottom: 0;\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n border-top-width: 0;\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n padding-right: 15px;\n padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n border-top-left-radius: 3px;\n border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n border-bottom-right-radius: 3px;\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n border-bottom: 0;\n}\n.panel > .table-responsive {\n margin-bottom: 0;\n border: 0;\n}\n.panel-group {\n margin-bottom: 20px;\n}\n.panel-group .panel {\n margin-bottom: 0;\n border-radius: 4px;\n}\n.panel-group .panel + .panel {\n margin-top: 5px;\n}\n.panel-group .panel-heading {\n border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n border-bottom: 1px solid #ddd;\n}\n.panel-default {\n border-color: #ddd;\n}\n.panel-default > .panel-heading {\n color: #333333;\n background-color: #f5f5f5;\n border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n color: #f5f5f5;\n background-color: #333333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ddd;\n}\n.panel-primary {\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n color: #fff;\n background-color: #337ab7;\n border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n color: #337ab7;\n background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #337ab7;\n}\n.panel-success {\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n color: #dff0d8;\n background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #d6e9c6;\n}\n.panel-info {\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n color: #31708f;\n background-color: #d9edf7;\n border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n color: #d9edf7;\n background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #bce8f1;\n}\n.panel-warning {\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n color: #8a6d3b;\n background-color: #fcf8e3;\n border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n color: #fcf8e3;\n background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #faebcc;\n}\n.panel-danger {\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n color: #f2dede;\n background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n}\n.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n padding-bottom: 75%;\n}\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: #f5f5f5;\n border: 1px solid #e3e3e3;\n border-radius: 4px;\n -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n.well blockquote {\n border-color: #ddd;\n border-color: rgba(0, 0, 0, 0.15);\n}\n.well-lg {\n padding: 24px;\n border-radius: 6px;\n}\n.well-sm {\n padding: 9px;\n border-radius: 3px;\n}\n.close {\n float: right;\n font-size: 21px;\n font-weight: bold;\n line-height: 1;\n color: #000;\n text-shadow: 0 1px 0 #fff;\n filter: alpha(opacity=20);\n opacity: 0.2;\n}\n.close:hover,\n.close:focus {\n color: #000;\n text-decoration: none;\n cursor: pointer;\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\nbutton.close {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n appearance: none;\n}\n.modal-open {\n overflow: hidden;\n}\n.modal {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1050;\n display: none;\n overflow: hidden;\n -webkit-overflow-scrolling: touch;\n outline: 0;\n}\n.modal.fade .modal-dialog {\n -webkit-transform: translate(0, -25%);\n -ms-transform: translate(0, -25%);\n -o-transform: translate(0, -25%);\n transform: translate(0, -25%);\n -webkit-transition: -webkit-transform 0.3s ease-out;\n -moz-transition: -moz-transform 0.3s ease-out;\n -o-transition: -o-transform 0.3s ease-out;\n transition: transform 0.3s ease-out;\n}\n.modal.in .modal-dialog {\n -webkit-transform: translate(0, 0);\n -ms-transform: translate(0, 0);\n -o-transform: translate(0, 0);\n transform: translate(0, 0);\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n.modal-content {\n position: relative;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #999;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n outline: 0;\n}\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1040;\n background-color: #000;\n}\n.modal-backdrop.fade {\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.modal-backdrop.in {\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\n.modal-header {\n padding: 15px;\n border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n margin-top: -2px;\n}\n.modal-title {\n margin: 0;\n line-height: 1.42857143;\n}\n.modal-body {\n position: relative;\n padding: 15px;\n}\n.modal-footer {\n padding: 15px;\n text-align: right;\n border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n margin-bottom: 0;\n margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n margin-left: 0;\n}\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n@media (min-width: 768px) {\n .modal-dialog {\n width: 600px;\n margin: 30px auto;\n }\n .modal-content {\n -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n }\n .modal-sm {\n width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg {\n width: 900px;\n }\n}\n.tooltip {\n position: absolute;\n z-index: 1070;\n display: block;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: 400;\n line-height: 1.42857143;\n line-break: auto;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n font-size: 12px;\n filter: alpha(opacity=0);\n opacity: 0;\n}\n.tooltip.in {\n filter: alpha(opacity=90);\n opacity: 0.9;\n}\n.tooltip.top {\n padding: 5px 0;\n margin-top: -3px;\n}\n.tooltip.right {\n padding: 0 5px;\n margin-left: 3px;\n}\n.tooltip.bottom {\n padding: 5px 0;\n margin-top: 3px;\n}\n.tooltip.left {\n padding: 0 5px;\n margin-left: -3px;\n}\n.tooltip.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n right: 5px;\n bottom: 0;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n bottom: 0;\n left: 5px;\n margin-bottom: -5px;\n border-width: 5px 5px 0;\n border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -5px;\n border-width: 5px 5px 5px 0;\n border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -5px;\n border-width: 5px 0 5px 5px;\n border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n top: 0;\n right: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n top: 0;\n left: 5px;\n margin-top: -5px;\n border-width: 0 5px 5px;\n border-bottom-color: #000;\n}\n.tooltip-inner {\n max-width: 200px;\n padding: 3px 8px;\n color: #fff;\n text-align: center;\n background-color: #000;\n border-radius: 4px;\n}\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 1060;\n display: none;\n max-width: 276px;\n padding: 1px;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n font-style: normal;\n font-weight: 400;\n line-height: 1.42857143;\n line-break: auto;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n word-spacing: normal;\n word-wrap: normal;\n white-space: normal;\n font-size: 14px;\n background-color: #fff;\n background-clip: padding-box;\n border: 1px solid #ccc;\n border: 1px solid rgba(0, 0, 0, 0.2);\n border-radius: 6px;\n -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n}\n.popover.top {\n margin-top: -10px;\n}\n.popover.right {\n margin-left: 10px;\n}\n.popover.bottom {\n margin-top: 10px;\n}\n.popover.left {\n margin-left: -10px;\n}\n.popover > .arrow {\n border-width: 11px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.popover > .arrow:after {\n content: \"\";\n border-width: 10px;\n}\n.popover.top > .arrow {\n bottom: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-color: #999999;\n border-top-color: rgba(0, 0, 0, 0.25);\n border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n bottom: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-color: #fff;\n border-bottom-width: 0;\n}\n.popover.right > .arrow {\n top: 50%;\n left: -11px;\n margin-top: -11px;\n border-right-color: #999999;\n border-right-color: rgba(0, 0, 0, 0.25);\n border-left-width: 0;\n}\n.popover.right > .arrow:after {\n bottom: -10px;\n left: 1px;\n content: \" \";\n border-right-color: #fff;\n border-left-width: 0;\n}\n.popover.bottom > .arrow {\n top: -11px;\n left: 50%;\n margin-left: -11px;\n border-top-width: 0;\n border-bottom-color: #999999;\n border-bottom-color: rgba(0, 0, 0, 0.25);\n}\n.popover.bottom > .arrow:after {\n top: 1px;\n margin-left: -10px;\n content: \" \";\n border-top-width: 0;\n border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n top: 50%;\n right: -11px;\n margin-top: -11px;\n border-right-width: 0;\n border-left-color: #999999;\n border-left-color: rgba(0, 0, 0, 0.25);\n}\n.popover.left > .arrow:after {\n right: 1px;\n bottom: -10px;\n content: \" \";\n border-right-width: 0;\n border-left-color: #fff;\n}\n.popover-title {\n padding: 8px 14px;\n margin: 0;\n font-size: 14px;\n background-color: #f7f7f7;\n border-bottom: 1px solid #ebebeb;\n border-radius: 5px 5px 0 0;\n}\n.popover-content {\n padding: 9px 14px;\n}\n.carousel {\n position: relative;\n}\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n.carousel-inner > .item {\n position: relative;\n display: none;\n -webkit-transition: 0.6s ease-in-out left;\n -o-transition: 0.6s ease-in-out left;\n transition: 0.6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n .carousel-inner > .item {\n -webkit-transition: -webkit-transform 0.6s ease-in-out;\n -moz-transition: -moz-transform 0.6s ease-in-out;\n -o-transition: -o-transform 0.6s ease-in-out;\n transition: transform 0.6s ease-in-out;\n -webkit-backface-visibility: hidden;\n -moz-backface-visibility: hidden;\n backface-visibility: hidden;\n -webkit-perspective: 1000px;\n -moz-perspective: 1000px;\n perspective: 1000px;\n }\n .carousel-inner > .item.next,\n .carousel-inner > .item.active.right {\n -webkit-transform: translate3d(100%, 0, 0);\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.prev,\n .carousel-inner > .item.active.left {\n -webkit-transform: translate3d(-100%, 0, 0);\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n .carousel-inner > .item.next.left,\n .carousel-inner > .item.prev.right,\n .carousel-inner > .item.active {\n -webkit-transform: translate3d(0, 0, 0);\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n display: block;\n}\n.carousel-inner > .active {\n left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n}\n.carousel-inner > .next {\n left: 100%;\n}\n.carousel-inner > .prev {\n left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n left: 0;\n}\n.carousel-inner > .active.left {\n left: -100%;\n}\n.carousel-inner > .active.right {\n left: 100%;\n}\n.carousel-control {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 0;\n width: 15%;\n font-size: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n background-color: rgba(0, 0, 0, 0);\n filter: alpha(opacity=50);\n opacity: 0.5;\n}\n.carousel-control.left {\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control.right {\n right: 0;\n left: auto;\n background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%);\n filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n filter: alpha(opacity=90);\n opacity: 0.9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n width: 20px;\n height: 20px;\n font-family: serif;\n line-height: 1;\n}\n.carousel-control .icon-prev:before {\n content: \"\\2039\";\n}\n.carousel-control .icon-next:before {\n content: \"\\203a\";\n}\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n padding-left: 0;\n margin-left: -30%;\n text-align: center;\n list-style: none;\n}\n.carousel-indicators li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #000 \\9;\n background-color: rgba(0, 0, 0, 0);\n border: 1px solid #fff;\n border-radius: 10px;\n}\n.carousel-indicators .active {\n width: 12px;\n height: 12px;\n margin: 0;\n background-color: #fff;\n}\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 20px;\n left: 15%;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: #fff;\n text-align: center;\n text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n.carousel-caption .btn {\n text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-prev,\n .carousel-control .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -10px;\n font-size: 30px;\n }\n .carousel-control .glyphicon-chevron-left,\n .carousel-control .icon-prev {\n margin-left: -10px;\n }\n .carousel-control .glyphicon-chevron-right,\n .carousel-control .icon-next {\n margin-right: -10px;\n }\n .carousel-caption {\n right: 20%;\n left: 20%;\n padding-bottom: 30px;\n }\n .carousel-indicators {\n bottom: 20px;\n }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n display: table;\n content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n clear: both;\n}\n.center-block {\n display: block;\n margin-right: auto;\n margin-left: auto;\n}\n.pull-right {\n float: right !important;\n}\n.pull-left {\n float: left !important;\n}\n.hide {\n display: none !important;\n}\n.show {\n display: block !important;\n}\n.invisible {\n visibility: hidden;\n}\n.text-hide {\n font: 0/0 a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n.hidden {\n display: none !important;\n}\n.affix {\n position: fixed;\n}\n@-ms-viewport {\n width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n@media (max-width: 767px) {\n .visible-xs {\n display: block !important;\n }\n table.visible-xs {\n display: table !important;\n }\n tr.visible-xs {\n display: table-row !important;\n }\n th.visible-xs,\n td.visible-xs {\n display: table-cell !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-block {\n display: block !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline {\n display: inline !important;\n }\n}\n@media (max-width: 767px) {\n .visible-xs-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm {\n display: block !important;\n }\n table.visible-sm {\n display: table !important;\n }\n tr.visible-sm {\n display: table-row !important;\n }\n th.visible-sm,\n td.visible-sm {\n display: table-cell !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-block {\n display: block !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline {\n display: inline !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .visible-sm-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md {\n display: block !important;\n }\n table.visible-md {\n display: table !important;\n }\n tr.visible-md {\n display: table-row !important;\n }\n th.visible-md,\n td.visible-md {\n display: table-cell !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-block {\n display: block !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline {\n display: inline !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .visible-md-inline-block {\n display: inline-block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg {\n display: block !important;\n }\n table.visible-lg {\n display: table !important;\n }\n tr.visible-lg {\n display: table-row !important;\n }\n th.visible-lg,\n td.visible-lg {\n display: table-cell !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-block {\n display: block !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline {\n display: inline !important;\n }\n}\n@media (min-width: 1200px) {\n .visible-lg-inline-block {\n display: inline-block !important;\n }\n}\n@media (max-width: 767px) {\n .hidden-xs {\n display: none !important;\n }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n .hidden-sm {\n display: none !important;\n }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n .hidden-md {\n display: none !important;\n }\n}\n@media (min-width: 1200px) {\n .hidden-lg {\n display: none !important;\n }\n}\n.visible-print {\n display: none !important;\n}\n@media print {\n .visible-print {\n display: block !important;\n }\n table.visible-print {\n display: table !important;\n }\n tr.visible-print {\n display: table-row !important;\n }\n th.visible-print,\n td.visible-print {\n display: table-cell !important;\n }\n}\n.visible-print-block {\n display: none !important;\n}\n@media print {\n .visible-print-block {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n}\n@media print {\n .visible-print-inline {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n}\n@media print {\n .visible-print-inline-block {\n display: inline-block !important;\n }\n}\n@media print {\n .hidden-print {\n display: none !important;\n }\n}\n/*# sourceMappingURL=bootstrap.css.map */", "// stylelint-disable\n\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS and IE text size adjust after device orientation change,\n// without disabling user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11\n// and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background-color: transparent;\n}\n\n//\n// Improve readability of focused elements when they are also in an\n// active/hover state.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// 1. Remove the bottom border in Chrome 57- and Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n//\n\nabbr[title] {\n border-bottom: none; // 1\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome.\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n box-sizing: content-box; //2\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n", "// stylelint-disable declaration-no-important, selector-no-qualifying-type\n\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n\n// ==========================================================================\n// Print styles.\n// Inlined to avoid the additional HTTP request: h5bp.com/r\n// ==========================================================================\n\n@media print {\n *,\n *:before,\n *:after {\n color: #000 !important; // Black prints faster: h5bp.com/s\n text-shadow: none !important;\n background: transparent !important;\n box-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links that are fragment identifiers,\n // or use the `javascript:` pseudo protocol\n a[href^=\"#\"]:after,\n a[href^=\"javascript:\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Bootstrap specific changes start\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n\n td,\n th {\n background-color: #fff !important;\n }\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n}\n", "// stylelint-disable value-list-comma-newline-after, value-list-comma-space-after, indentation, declaration-colon-newline-after, font-family-no-missing-generic-family-keyword\n\n//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: \"Glyphicons Halflings\";\n src: url(\"@{icon-font-path}@{icon-font-name}.eot\");\n src: url(\"@{icon-font-path}@{icon-font-name}.eot?#iefix\") format(\"embedded-opentype\"),\n url(\"@{icon-font-path}@{icon-font-name}.woff2\") format(\"woff2\"),\n url(\"@{icon-font-path}@{icon-font-name}.woff\") format(\"woff\"),\n url(\"@{icon-font-path}@{icon-font-name}.ttf\") format(\"truetype\"),\n url(\"@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}\") format(\"svg\");\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: \"Glyphicons Halflings\";\n font-style: normal;\n font-weight: 400;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\002a\"; } }\n.glyphicon-plus { &:before { content: \"\\002b\"; } }\n.glyphicon-euro,\n.glyphicon-eur { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n.glyphicon-cd { &:before { content: \"\\e201\"; } }\n.glyphicon-save-file { &:before { content: \"\\e202\"; } }\n.glyphicon-open-file { &:before { content: \"\\e203\"; } }\n.glyphicon-level-up { &:before { content: \"\\e204\"; } }\n.glyphicon-copy { &:before { content: \"\\e205\"; } }\n.glyphicon-paste { &:before { content: \"\\e206\"; } }\n// The following 2 Glyphicons are omitted for the time being because\n// they currently use Unicode codepoints that are outside the\n// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle\n// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.\n// Notably, the bug affects some older versions of the Android Browser.\n// More info: https://github.com/twbs/bootstrap/issues/10106\n// .glyphicon-door { &:before { content: \"\\1f6aa\"; } }\n// .glyphicon-key { &:before { content: \"\\1f511\"; } }\n.glyphicon-alert { &:before { content: \"\\e209\"; } }\n.glyphicon-equalizer { &:before { content: \"\\e210\"; } }\n.glyphicon-king { &:before { content: \"\\e211\"; } }\n.glyphicon-queen { &:before { content: \"\\e212\"; } }\n.glyphicon-pawn { &:before { content: \"\\e213\"; } }\n.glyphicon-bishop { &:before { content: \"\\e214\"; } }\n.glyphicon-knight { &:before { content: \"\\e215\"; } }\n.glyphicon-baby-formula { &:before { content: \"\\e216\"; } }\n.glyphicon-tent { &:before { content: \"\\26fa\"; } }\n.glyphicon-blackboard { &:before { content: \"\\e218\"; } }\n.glyphicon-bed { &:before { content: \"\\e219\"; } }\n.glyphicon-apple { &:before { content: \"\\f8ff\"; } }\n.glyphicon-erase { &:before { content: \"\\e221\"; } }\n.glyphicon-hourglass { &:before { content: \"\\231b\"; } }\n.glyphicon-lamp { &:before { content: \"\\e223\"; } }\n.glyphicon-duplicate { &:before { content: \"\\e224\"; } }\n.glyphicon-piggy-bank { &:before { content: \"\\e225\"; } }\n.glyphicon-scissors { &:before { content: \"\\e226\"; } }\n.glyphicon-bitcoin { &:before { content: \"\\e227\"; } }\n.glyphicon-btc { &:before { content: \"\\e227\"; } }\n.glyphicon-xbt { &:before { content: \"\\e227\"; } }\n.glyphicon-yen { &:before { content: \"\\00a5\"; } }\n.glyphicon-jpy { &:before { content: \"\\00a5\"; } }\n.glyphicon-ruble { &:before { content: \"\\20bd\"; } }\n.glyphicon-rub { &:before { content: \"\\20bd\"; } }\n.glyphicon-scale { &:before { content: \"\\e230\"; } }\n.glyphicon-ice-lolly { &:before { content: \"\\e231\"; } }\n.glyphicon-ice-lolly-tasted { &:before { content: \"\\e232\"; } }\n.glyphicon-education { &:before { content: \"\\e233\"; } }\n.glyphicon-option-horizontal { &:before { content: \"\\e234\"; } }\n.glyphicon-option-vertical { &:before { content: \"\\e235\"; } }\n.glyphicon-menu-hamburger { &:before { content: \"\\e236\"; } }\n.glyphicon-modal-window { &:before { content: \"\\e237\"; } }\n.glyphicon-oil { &:before { content: \"\\e238\"; } }\n.glyphicon-grain { &:before { content: \"\\e239\"; } }\n.glyphicon-sunglasses { &:before { content: \"\\e240\"; } }\n.glyphicon-text-size { &:before { content: \"\\e241\"; } }\n.glyphicon-text-color { &:before { content: \"\\e242\"; } }\n.glyphicon-text-background { &:before { content: \"\\e243\"; } }\n.glyphicon-object-align-top { &:before { content: \"\\e244\"; } }\n.glyphicon-object-align-bottom { &:before { content: \"\\e245\"; } }\n.glyphicon-object-align-horizontal{ &:before { content: \"\\e246\"; } }\n.glyphicon-object-align-left { &:before { content: \"\\e247\"; } }\n.glyphicon-object-align-vertical { &:before { content: \"\\e248\"; } }\n.glyphicon-object-align-right { &:before { content: \"\\e249\"; } }\n.glyphicon-triangle-right { &:before { content: \"\\e250\"; } }\n.glyphicon-triangle-left { &:before { content: \"\\e251\"; } }\n.glyphicon-triangle-bottom { &:before { content: \"\\e252\"; } }\n.glyphicon-triangle-top { &:before { content: \"\\e253\"; } }\n.glyphicon-console { &:before { content: \"\\e254\"; } }\n.glyphicon-superscript { &:before { content: \"\\e255\"; } }\n.glyphicon-subscript { &:before { content: \"\\e256\"; } }\n.glyphicon-menu-left { &:before { content: \"\\e257\"; } }\n.glyphicon-menu-right { &:before { content: \"\\e258\"; } }\n.glyphicon-menu-down { &:before { content: \"\\e259\"; } }\n.glyphicon-menu-up { &:before { content: \"\\e260\"; } }\n", "//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// https://getbootstrap.com/docs/3.4/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: @link-hover-decoration;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: https://a11yproject.com/posts/how-to-hide-content\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n\n\n// iOS \"clickable elements\" fix for role=\"button\"\n//\n// Fixes \"clickability\" issue (and more generally, the firing of events such as focus as well)\n// for traditionally non-focusable elements with role=\"button\"\n// see https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile\n\n[role=\"button\"] {\n cursor: pointer;\n}\n", "// stylelint-disable indentation, property-no-vendor-prefix, selector-no-vendor-prefix\n\n// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They have been removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility) {\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n word-wrap: break-word;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n // Firefox\n &::-moz-placeholder {\n color: @color;\n opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526\n }\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n", "// WebKit-style focus\n\n.tab-focus() {\n // WebKit-specific. Other browsers will keep their default outline style.\n // (Initially tried to also force default via `outline: initial`,\n // but that seems to erroneously remove the outline in Firefox altogether.)\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n", "// stylelint-disable media-feature-name-no-vendor-prefix, media-feature-parentheses-space-inside, media-feature-name-no-unknown, indentation, at-rule-name-space-after\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n", "// stylelint-disable selector-list-comma-newline-after, selector-no-qualifying-type\n\n//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: 400;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\nmark,\n.mark {\n padding: .2em;\n background-color: @state-warning-bg;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-right: 5px;\n padding-left: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: 700;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @dl-horizontal-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[title],\nabbr[data-original-title] {\n cursor: help;\n}\n\n.initialism {\n font-size: 90%;\n .text-uppercase();\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: \"\\2014 \\00A0\"; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n text-align: right;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: \"\"; }\n &:after {\n content: \"\\00A0 \\2014\"; // nbsp, em dash\n }\n }\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n", "// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover,\n a&:focus {\n color: darken(@color, 10%);\n }\n}\n", "// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover,\n a&:focus {\n background-color: darken(@color, 10%);\n }\n}\n", "// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n", "//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n font-weight: 700;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n color: @pre-color;\n word-break: break-all;\n word-wrap: break-word;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n", "//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n.row-no-gutters {\n margin-right: 0;\n margin-left: 0;\n\n [class*=\"col-\"] {\n padding-right: 0;\n padding-left: 0;\n }\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n", "// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n padding-right: ceil((@gutter / 2));\n padding-left: floor((@gutter / 2));\n margin-right: auto;\n margin-left: auto;\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-right: floor((@gutter / -2));\n margin-left: ceil((@gutter / -2));\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-right: (@gutter / 2);\n padding-left: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n", "// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-right: floor((@grid-gutter-width / 2));\n padding-left: ceil((@grid-gutter-width / 2));\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n", "// stylelint-disable selector-max-type, selector-max-compound-selectors, selector-no-qualifying-type\n\n//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n\n // Table cell sizing\n //\n // Reset default table behavior\n\n col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n display: table-column;\n float: none;\n }\n\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9-11 (see https://github.com/twbs/bootstrap/issues/11623)\n display: table-cell;\n float: none;\n }\n }\n}\n\ncaption {\n padding-top: @table-cell-padding;\n padding-bottom: @table-cell-padding;\n color: @text-muted;\n text-align: left;\n}\n\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-of-type(odd) {\n background-color: @table-bg-accent;\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n background-color: @table-bg-hover;\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n min-height: .01%; // Workaround for IE9 bug (see https://github.com/twbs/bootstrap/issues/14837)\n overflow-x: auto;\n\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * .75);\n overflow-y: hidden;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n", "// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n", "// stylelint-disable selector-no-qualifying-type, property-no-vendor-prefix, media-feature-name-no-vendor-prefix\n\n//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: 700;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\ninput[type=\"search\"] {\n // Override content-box in Normalize (* isn't specific enough)\n .box-sizing(border-box);\n\n // Search inputs in iOS\n //\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n -webkit-appearance: none;\n appearance: none;\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n\n // Apply same disabled cursor tweak as for inputs\n // Some special care is needed because
/// Request information (EndPoint, internal id, additional data) - void OnConnectionRequest(ConnectionRequest request); + void OnConnectionRequest(LiteConnectionRequest request); /// /// Called when peer address changed (when AllowPeerAddressChange is enabled) @@ -299,7 +299,7 @@ public class EventBasedLiteNetListener : ILiteNetEventListener public delegate void OnNetworkReceive(LiteNetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod); public delegate void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType); public delegate void OnNetworkLatencyUpdate(LiteNetPeer peer, int latency); - public delegate void OnConnectionRequest(ConnectionRequest request); + public delegate void OnConnectionRequest(LiteConnectionRequest request); public delegate void OnDeliveryEvent(LiteNetPeer peer, object userData); public delegate void OnPeerAddressChangedEvent(LiteNetPeer peer, IPEndPoint previousAddress); @@ -341,7 +341,7 @@ void ILiteNetEventListener.OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint void ILiteNetEventListener.OnNetworkLatencyUpdate(LiteNetPeer peer, int latency) => NetworkLatencyUpdateEvent?.Invoke(peer, latency); - void ILiteNetEventListener.OnConnectionRequest(ConnectionRequest request) => + void ILiteNetEventListener.OnConnectionRequest(LiteConnectionRequest request) => ConnectionRequestEvent?.Invoke(request); void ILiteNetEventListener.OnMessageDelivered(LiteNetPeer peer, object userData) => diff --git a/LiteNetLib/InternalPackets.cs b/LiteNetLib/InternalPackets.cs index afce5ddf..6cd9a8db 100644 --- a/LiteNetLib/InternalPackets.cs +++ b/LiteNetLib/InternalPackets.cs @@ -4,7 +4,7 @@ namespace LiteNetLib { - internal sealed class NetConnectRequestPacket + public sealed class NetConnectRequestPacket { public const int HeaderSize = 18; public readonly long ConnectionTime; @@ -22,10 +22,10 @@ private NetConnectRequestPacket(long connectionTime, byte connectionNumber, int PeerId = localId; } - public static int GetProtocolId(NetPacket packet) => + internal static int GetProtocolId(NetPacket packet) => BitConverter.ToInt32(packet.RawData, 1); - public static NetConnectRequestPacket FromData(NetPacket packet) + internal static NetConnectRequestPacket FromData(NetPacket packet) { if (packet.ConnectionNumber >= NetConstants.MaxConnectionNumber) return null; @@ -51,7 +51,7 @@ public static NetConnectRequestPacket FromData(NetPacket packet) return new NetConnectRequestPacket(connectionTime, packet.ConnectionNumber, peerId, addressBytes, reader); } - public static NetPacket Make(ReadOnlySpan connectData, SocketAddress addressBytes, long connectTime, int localId) + internal static NetPacket Make(ReadOnlySpan connectData, SocketAddress addressBytes, long connectTime, int localId) { //Make initial packet var packet = new NetPacket(PacketProperty.ConnectRequest, connectData.Length+addressBytes.Size); diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index 2426cb96..572fd105 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -78,7 +78,7 @@ private struct OutboundDelayedPacket private NetEvent _netEventPoolHead; private readonly ILiteNetEventListener _netEventListener; - private readonly Dictionary _requestsDict = new Dictionary(); + private readonly Dictionary _requestsDict = new Dictionary(); private long _connectedPeersCount; private readonly PacketLayerBase _extraPacketLayer; @@ -331,7 +331,7 @@ private void CreateEvent( SocketError errorCode = 0, int latency = 0, DisconnectReason disconnectReason = DisconnectReason.ConnectionFailed, - ConnectionRequest connectionRequest = null, + LiteConnectionRequest connectionRequest = null, DeliveryMethod deliveryMethod = DeliveryMethod.Unreliable, byte channelNumber = 0, NetPacket readerSource = null, @@ -589,14 +589,17 @@ protected virtual LiteNetPeer CreateOutgoingPeer(IPEndPoint remoteEndPoint, int new LiteNetPeer(this, remoteEndPoint, id, connectNum, connectData); //accept - protected virtual LiteNetPeer CreateIncomingPeer(ConnectionRequest request, int id) => + protected virtual LiteNetPeer CreateIncomingPeer(LiteConnectionRequest request, int id) => new LiteNetPeer(this, request, id); //reject protected virtual LiteNetPeer CreateRejectPeer(IPEndPoint remoteEndPoint, int id) => new LiteNetPeer(this, remoteEndPoint, id); - internal LiteNetPeer OnConnectionSolved(ConnectionRequest request, byte[] rejectData, int start, int length) + protected virtual LiteConnectionRequest CreateConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket requestPacket) => + new LiteConnectionRequest(remoteEndPoint, requestPacket, this); + + internal LiteNetPeer OnConnectionSolved(LiteConnectionRequest request, byte[] rejectData, int start, int length) { LiteNetPeer netPeer = null; @@ -688,7 +691,7 @@ private void ProcessConnectRequest( NetDebug.Write($"ConnectRequest Id: {connRequest.ConnectionTime}, EP: {remoteEndPoint}"); } - ConnectionRequest req; + LiteConnectionRequest req; lock (_requestsDict) { if (_requestsDict.TryGetValue(remoteEndPoint, out req)) @@ -696,7 +699,7 @@ private void ProcessConnectRequest( req.UpdateRequest(connRequest); return; } - req = new ConnectionRequest(remoteEndPoint, connRequest, this); + req = CreateConnectionRequest(remoteEndPoint, connRequest); _requestsDict.Add(remoteEndPoint, req); } NetDebug.Write($"[NM] Creating request event: {connRequest.ConnectionTime}"); diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 0292b619..7c1d86bb 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -404,7 +404,7 @@ internal LiteNetPeer(LiteNetManager netManager, IPEndPoint remoteEndPoint, int i } //"Accept" incoming constructor - internal LiteNetPeer(LiteNetManager netManager, ConnectionRequest request, int id) + internal LiteNetPeer(LiteNetManager netManager, LiteConnectionRequest request, int id) : this(netManager, request.RemoteEndPoint, id) { _connectTime = request.InternalPacket.ConnectionTime; diff --git a/LiteNetLib/NetEvent.cs b/LiteNetLib/NetEvent.cs index 6529b707..b54f60aa 100644 --- a/LiteNetLib/NetEvent.cs +++ b/LiteNetLib/NetEvent.cs @@ -31,7 +31,7 @@ public enum EType public int Latency; public SocketError ErrorCode; public DisconnectReason DisconnectReason; - public ConnectionRequest ConnectionRequest; + public LiteConnectionRequest ConnectionRequest; public DeliveryMethod DeliveryMethod; public byte ChannelNumber; public readonly NetPacketReader DataReader; diff --git a/LiteNetLib/NetManager.cs b/LiteNetLib/NetManager.cs index d9b89763..8ff80cfe 100644 --- a/LiteNetLib/NetManager.cs +++ b/LiteNetLib/NetManager.cs @@ -129,13 +129,17 @@ protected override LiteNetPeer CreateOutgoingPeer(IPEndPoint remoteEndPoint, int new NetPeer(this, remoteEndPoint, id, connectNum, connectData); //accept - protected override LiteNetPeer CreateIncomingPeer(ConnectionRequest request, int id) => + protected override LiteNetPeer CreateIncomingPeer(LiteConnectionRequest request, int id) => new NetPeer(this, request, id); //reject protected override LiteNetPeer CreateRejectPeer(IPEndPoint remoteEndPoint, int id) => new NetPeer(this, remoteEndPoint, id); + //connection request when you use Accept for getting NetPeer instead of LiteNetPeer + protected override LiteConnectionRequest CreateConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket requestPacket) => + new ConnectionRequest(remoteEndPoint, requestPacket, this); + protected override void ProcessEvent(NetEvent evt) { NetDebug.Write("[NM] Processing event: " + evt.Type); @@ -171,7 +175,7 @@ protected override void ProcessEvent(NetEvent evt) _netEventListener.OnNetworkLatencyUpdate(netPeer, evt.Latency); break; case NetEvent.EType.ConnectionRequest: - _netEventListener.OnConnectionRequest(evt.ConnectionRequest); + _netEventListener.OnConnectionRequest((ConnectionRequest)evt.ConnectionRequest); break; case NetEvent.EType.MessageDelivered: _netEventListener.OnMessageDelivered(netPeer, evt.UserData); diff --git a/LiteNetLib/NetPeer.cs b/LiteNetLib/NetPeer.cs index e441cc9a..fcc304c5 100644 --- a/LiteNetLib/NetPeer.cs +++ b/LiteNetLib/NetPeer.cs @@ -26,7 +26,7 @@ internal NetPeer(NetManager netManager, IPEndPoint remoteEndPoint, int id, byte _channels = new BaseChannel[netManager.ChannelsCount * NetConstants.ChannelTypeCount]; } - internal NetPeer(NetManager netManager, ConnectionRequest request, int id) : base(netManager, request, id) + internal NetPeer(NetManager netManager, LiteConnectionRequest request, int id) : base(netManager, request, id) { _channels = new BaseChannel[netManager.ChannelsCount * NetConstants.ChannelTypeCount]; } From 9a3f505716a9303de1885bfb6e127fa0c76dd70a Mon Sep 17 00:00:00 2001 From: RevenantX Date: Thu, 12 Mar 2026 09:37:43 +0200 Subject: [PATCH 170/261] fix dotnet test command when both frameworks runs in parallel --- LiteNetLib.Tests/CommunicationTest.cs | 12 +++++---- LiteNetLib.Tests/LiteCommunicationTest.cs | 12 +++++---- LiteNetLib.Tests/TestUtility/TestPorts.cs | 32 +++++++++++++++++++++++ 3 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 LiteNetLib.Tests/TestUtility/TestPorts.cs diff --git a/LiteNetLib.Tests/CommunicationTest.cs b/LiteNetLib.Tests/CommunicationTest.cs index 1ffce0e6..fcc8224f 100644 --- a/LiteNetLib.Tests/CommunicationTest.cs +++ b/LiteNetLib.Tests/CommunicationTest.cs @@ -30,7 +30,9 @@ public void TearDown() ManagerStack?.Dispose(); } - private const int DefaultPort = 9050; + private static readonly int DefaultPort = TestPorts.ForFramework(9050); + private static readonly int ReconnectPort = TestPorts.ForFramework(10123); + private static readonly int ReuseClientPort = TestPorts.ForFramework(9049); private const string DefaultAppKey = "test_server"; private static readonly byte[] DefaultAppKeyBytes = [12, 0, 116, 101, 115, 116, 95, 115, 101, 114, 118, 101, 114]; @@ -270,7 +272,7 @@ public void ReconnectTest() }; client.Stop(); - client.Start(10123); + client.Start(ReconnectPort); client.Connect("127.0.0.1", DefaultPort, DefaultAppKey); while (connectCount < 2) @@ -279,7 +281,7 @@ public void ReconnectTest() { client.Stop(); Thread.Sleep(500); - client.Start(10123); + client.Start(ReconnectPort); client.Connect("127.0.0.1", DefaultPort, DefaultAppKey); reconnected = true; } @@ -465,7 +467,7 @@ public void ConnectAfterDisconnectWithSamePort() EventBasedNetListener listener = new EventBasedNetListener(); NetManager client = new NetManager(listener, new Crc32cLayer()); - Assert.That(client.Start(9049), Is.True); + Assert.That(client.Start(ReuseClientPort), Is.True); client.Connect("127.0.0.1", DefaultPort, DefaultAppKey); while (server.ConnectedPeersCount != 1) { @@ -479,7 +481,7 @@ public void ConnectAfterDisconnectWithSamePort() { connected = true; }; - Assert.That(client.Start(9049), Is.True); + Assert.That(client.Start(ReuseClientPort), Is.True); client.Connect("127.0.0.1", DefaultPort, DefaultAppKey); while (!connected) diff --git a/LiteNetLib.Tests/LiteCommunicationTest.cs b/LiteNetLib.Tests/LiteCommunicationTest.cs index 2b08f7ef..608d655d 100644 --- a/LiteNetLib.Tests/LiteCommunicationTest.cs +++ b/LiteNetLib.Tests/LiteCommunicationTest.cs @@ -30,7 +30,9 @@ public void TearDown() ManagerStack?.Dispose(); } - private const int DefaultPort = 9050; + private static readonly int DefaultPort = TestPorts.ForFramework(9050); + private static readonly int ReconnectPort = TestPorts.ForFramework(10123); + private static readonly int ReuseClientPort = TestPorts.ForFramework(9049); private const string DefaultAppKey = "test_server"; private static readonly byte[] DefaultAppKeyBytes = [12, 0, 116, 101, 115, 116, 95, 115, 101, 114, 118, 101, 114]; @@ -270,7 +272,7 @@ public void ReconnectTest() }; client.Stop(); - client.Start(10123); + client.Start(ReconnectPort); client.Connect("127.0.0.1", DefaultPort, DefaultAppKey); while (connectCount < 2) @@ -279,7 +281,7 @@ public void ReconnectTest() { client.Stop(); Thread.Sleep(500); - client.Start(10123); + client.Start(ReconnectPort); client.Connect("127.0.0.1", DefaultPort, DefaultAppKey); reconnected = true; } @@ -465,7 +467,7 @@ public void ConnectAfterDisconnectWithSamePort() var listener = new EventBasedLiteNetListener(); var client = new LiteNetManager(listener, new Crc32cLayer()); - Assert.That(client.Start(9049), Is.True); + Assert.That(client.Start(ReuseClientPort), Is.True); client.Connect("127.0.0.1", DefaultPort, DefaultAppKey); while (server.ConnectedPeersCount != 1) { @@ -479,7 +481,7 @@ public void ConnectAfterDisconnectWithSamePort() { connected = true; }; - Assert.That(client.Start(9049), Is.True); + Assert.That(client.Start(ReuseClientPort), Is.True); client.Connect("127.0.0.1", DefaultPort, DefaultAppKey); while (!connected) diff --git a/LiteNetLib.Tests/TestUtility/TestPorts.cs b/LiteNetLib.Tests/TestUtility/TestPorts.cs new file mode 100644 index 00000000..70b63934 --- /dev/null +++ b/LiteNetLib.Tests/TestUtility/TestPorts.cs @@ -0,0 +1,32 @@ +using System; +using System.Runtime.Versioning; + +namespace LiteNetLib.Tests.TestUtility +{ + internal static class TestPorts + { + private const int BaselineFrameworkMajor = 8; + private const int FrameworkPortBlockSize = 1000; + + public static int ForFramework(int basePort) + { + var frameworkAttribute = (TargetFrameworkAttribute)Attribute.GetCustomAttribute( + typeof(TestPorts).Assembly, + typeof(TargetFrameworkAttribute)); + + if (frameworkAttribute == null) + return basePort; + + const string versionMarker = "Version=v"; + var versionStart = frameworkAttribute.FrameworkName.IndexOf(versionMarker, StringComparison.Ordinal); + if (versionStart < 0) + return basePort; + + var versionText = frameworkAttribute.FrameworkName.Substring(versionStart + versionMarker.Length); + if (!Version.TryParse(versionText, out var version)) + return basePort; + + return basePort + Math.Max(0, version.Major - BaselineFrameworkMajor) * FrameworkPortBlockSize; + } + } +} From b7b1fe36672fb8a00ba75624f730f553d821c512 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Sat, 14 Mar 2026 01:46:52 +0300 Subject: [PATCH 171/261] Update NetDataReader.cs --- LiteNetLib/Utils/NetDataReader.cs | 64 +++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 16 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 745318f1..b8599e43 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -52,6 +52,14 @@ public int AvailableBytes get => _dataSize - _position; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private void EnsureAvailable(int count) + { + if (count < 0 || count > AvailableBytes) + throw new InvalidOperationException( + $"Not enough data to read {count} byte(s). Position={_position}, DataSize={_dataSize}"); + } + public void SkipBytes(int count) => _position += count; public void SetPosition(int position) => _position = position; @@ -110,12 +118,14 @@ public IPEndPoint GetIPEndPoint() //IPv4 if (GetByte() == 0) { + EnsureAvailable(4); address = new IPAddress(new ReadOnlySpan(_data, _position, 4)); _position += 4; } //IPv6 else { + EnsureAvailable(16); address = new IPAddress(new ReadOnlySpan(_data, _position, 16)); _position += 16; } @@ -128,12 +138,12 @@ public IPEndPoint GetIPEndPoint() public void Get(out char result) => result = GetChar(); public void Get(out ushort result) => result = GetUShort(); public void Get(out short result) => result = GetShort(); - public void Get(out ulong result) => result = GetULong(); + public void Get(out ulong result) => result = GetULong(); public void Get(out long result) => result = GetLong(); public void Get(out uint result) => result = GetUInt(); public void Get(out int result) => result = GetInt(); public void Get(out double result) => result = GetDouble(); - public void Get(out float result) => result = GetFloat(); + public void Get(out float result) => result = GetFloat(); public void Get(out string result) => result = GetString(); public void Get(out string result, int maxLength) => result = GetString(maxLength); public void Get(out Guid result) => result = GetGuid(); @@ -146,10 +156,15 @@ public T[] GetArray(ushort size) { ushort length = BitConverter.ToUInt16(_data, _position); _position += 2; + + int byteLength = checked(length * size); + EnsureAvailable(byteLength); + T[] result = new T[length]; - length *= size; - Buffer.BlockCopy(_data, _position, result, 0, length); - _position += length; + if (byteLength > 0) + Buffer.BlockCopy(_data, _position, result, 0, byteLength); + + _position += byteLength; return result; } @@ -283,9 +298,13 @@ public string GetString(int maxLength) return string.Empty; int actualSize = size - 1; - string result = maxLength > 0 && NetDataWriter.uTF8Encoding.GetCharCount(_data, _position, actualSize) > maxLength ? - string.Empty : - NetDataWriter.uTF8Encoding.GetString(_data, _position, actualSize); + EnsureAvailable(actualSize); + + string result = maxLength > 0 && + NetDataWriter.uTF8Encoding.GetCharCount(_data, _position, actualSize) > maxLength + ? string.Empty + : NetDataWriter.uTF8Encoding.GetString(_data, _position, actualSize); + _position += actualSize; return result; } @@ -297,6 +316,8 @@ public string GetString() return string.Empty; int actualSize = size - 1; + EnsureAvailable(actualSize); + string result = NetDataWriter.uTF8Encoding.GetString(_data, _position, actualSize); _position += actualSize; return result; @@ -307,6 +328,9 @@ public string GetLargeString() int size = GetInt(); if (size <= 0) return string.Empty; + + EnsureAvailable(size); + string result = NetDataWriter.uTF8Encoding.GetString(_data, _position, size); _position += size; return result; @@ -314,6 +338,7 @@ public string GetLargeString() public Guid GetGuid() { + EnsureAvailable(16); var result = new Guid(_data.AsSpan(_position, 16)); _position += 16; return result; @@ -321,6 +346,7 @@ public Guid GetGuid() public ArraySegment GetBytesSegment(int count) { + EnsureAvailable(count); ArraySegment segment = new ArraySegment(_data, _position, count); _position += count; return segment; @@ -329,7 +355,7 @@ public ArraySegment GetBytesSegment(int count) public ArraySegment GetRemainingBytesSegment() { ArraySegment segment = new ArraySegment(_data, _position, AvailableBytes); - _position = _data.Length; + _position = _dataSize; return segment; } @@ -359,18 +385,20 @@ public byte[] GetRemainingBytes() { byte[] outgoingData = new byte[AvailableBytes]; Buffer.BlockCopy(_data, _position, outgoingData, 0, AvailableBytes); - _position = _data.Length; + _position = _dataSize; return outgoingData; } public void GetBytes(byte[] destination, int start, int count) { + EnsureAvailable(count); Buffer.BlockCopy(_data, _position, destination, start, count); _position += count; } public void GetBytes(byte[] destination, int count) { + EnsureAvailable(count); Buffer.BlockCopy(_data, _position, destination, 0, count); _position += count; } @@ -404,9 +432,9 @@ public string PeekString(int maxLength) return string.Empty; int actualSize = size - 1; - return (maxLength > 0 && NetDataWriter.uTF8Encoding.GetCharCount(_data, _position + 2, actualSize) > maxLength) ? - string.Empty : - NetDataWriter.uTF8Encoding.GetString(_data, _position + 2, actualSize); + return (maxLength > 0 && NetDataWriter.uTF8Encoding.GetCharCount(_data, _position + 2, actualSize) > maxLength) + ? string.Empty + : NetDataWriter.uTF8Encoding.GetString(_data, _position + 2, actualSize); } public string PeekString() @@ -558,7 +586,9 @@ public bool TryGetString(out string result) if (AvailableBytes >= 2) { ushort strSize = PeekUShort(); - if (AvailableBytes >= strSize + 1) + int actualSize = strSize == 0 ? 0 : strSize - 1; + + if (AvailableBytes >= 2 + actualSize) { result = GetString(); return true; @@ -570,7 +600,8 @@ public bool TryGetString(out string result) public bool TryGetStringArray(out string[] result) { - if (!TryGetUShort(out ushort strArrayLength)) { + if (!TryGetUShort(out ushort strArrayLength)) + { result = null; return false; } @@ -593,7 +624,7 @@ public bool TryGetBytesWithLength(out byte[] result) if (AvailableBytes >= 2) { ushort length = PeekUShort(); - if (length >= 0 && AvailableBytes >= 2 + length) + if (AvailableBytes >= 2 + length) { result = GetBytesWithLength(); return true; @@ -607,6 +638,7 @@ public bool TryGetBytesWithLength(out byte[] result) public void Clear() { _position = 0; + _offset = 0; _dataSize = 0; _data = null; } From 0bdaf2843affc6b21dfc4ead1fcee1bf663123ed Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 18 Mar 2026 02:14:08 +0300 Subject: [PATCH 172/261] Improve fragment reassembly and timeout handling Add FragmentTimeout to LiteNetManager and refactor fragment reassembly logic to be safer and more memory-efficient. IncomingFragments now uses a small fixed array up to a threshold and a dictionary for larger fragment sets, tracks LastReceivedTime, and exposes helpers to Get/Set/Remove fragments and recycle packets. Added validation for FragmentsTotal/FragmentPart and metadata mismatches, an AbortReassembly helper to centralize cleanup, and more robust bounds/error checks. Maintain an _updateTime and purge expired fragment assemblies during Update to avoid stale fragments and leaks. --- LiteNetLib/LiteNetManager.cs | 5 + LiteNetLib/LiteNetPeer.cs | 172 +++++++++++++++++++++++++++-------- 2 files changed, 137 insertions(+), 40 deletions(-) diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index 572fd105..85688933 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -205,6 +205,11 @@ private struct OutboundDelayedPacket /// public ushort MaxFragmentsCount = ushort.MaxValue; + /// + /// Fragmented packet timeout + /// + public ushort FragmentTimeout = 3000; + /// /// NatPunchModule for NAT hole punching operations /// diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 7c1d86bb..8d132121 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -100,12 +100,75 @@ private set //Fragment private class IncomingFragments { - public NetPacket[] Fragments; + // Fragments with TotalFragments <= threshold use a fixed array (faster) + // Larger sets use a dictionary to avoid large upfront allocations + private const int ArrayThreshold = 64; + + private readonly NetPacket[] _array; + private readonly Dictionary _dict; + + public readonly ushort TotalFragments; + public readonly byte ChannelId; public int ReceivedCount; public int TotalSize; - public byte ChannelId; + public float LastReceivedTime; + + public IncomingFragments(ushort totalFragments, byte channelId, float now) + { + TotalFragments = totalFragments; + ChannelId = channelId; + LastReceivedTime = now; + if (totalFragments <= ArrayThreshold) + _array = new NetPacket[totalFragments]; + else + _dict = new Dictionary(); + } + + public bool Contains(ushort part) => + _array != null ? _array[part] != null : _dict.ContainsKey(part); + + public bool TryGet(ushort part, out NetPacket packet) + { + if (_array != null) + { + packet = _array[part]; + return packet != null; + } + return _dict.TryGetValue(part, out packet); + } + + public void Set(ushort part, NetPacket packet) + { + if (_array != null) + _array[part] = packet; + else + _dict[part] = packet; + } + + public void Remove(ushort part) + { + if (_array != null) + _array[part] = null; + else + _dict.Remove(part); + } + + public void RecycleAll(LiteNetManager netManager) + { + if (_array != null) + { + foreach (var p in _array) + if (p != null) netManager.PoolRecycle(p); + } + else + { + foreach (var p in _dict.Values) + netManager.PoolRecycle(p); + } + } } private int _fragmentId; + private float _updateTime; private readonly Dictionary _holdedFragments; private readonly Dictionary _deliveredFragments; @@ -754,81 +817,90 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) { if (p.IsFragmented) { - if (p.FragmentsTotal > NetManager.MaxFragmentsCount) + if (p.FragmentsTotal == 0 || p.FragmentsTotal > NetManager.MaxFragmentsCount) + { + NetManager.PoolRecycle(p); + NetDebug.WriteError($"Invalid FragmentsTotal: {p.FragmentsTotal}"); + return; + } + + if (p.FragmentPart >= p.FragmentsTotal) { NetManager.PoolRecycle(p); + NetDebug.WriteError($"FragmentPart {p.FragmentPart} >= FragmentsTotal {p.FragmentsTotal}"); return; } + NetDebug.Write($"Fragment. Id: {p.FragmentId}, Part: {p.FragmentPart}, Total: {p.FragmentsTotal}"); - //Get needed array from dictionary + ushort packetFragId = p.FragmentId; byte packetChannelId = p.ChannelId; + if (!_holdedFragments.TryGetValue(packetFragId, out var incomingFragments)) { - //Holded fragments limit reached if (_holdedFragments.Count >= NetConstants.MaxFragmentsInWindow * ChannelsCount * NetConstants.FragmentedChannelsCount) { NetManager.PoolRecycle(p); - //NetDebug.WriteError($"Holded fragments limit reached ({_holdedFragments.Count}/{(NetConstants.DefaultWindowSize / 2) * ChannelsCount * NetConstants.FragmentedChannelsCount}). Dropping fragment id: {packetFragId}"); return; } - incomingFragments = new IncomingFragments - { - Fragments = new NetPacket[p.FragmentsTotal], - ChannelId = p.ChannelId - }; + incomingFragments = new IncomingFragments(p.FragmentsTotal, p.ChannelId, _updateTime); _holdedFragments.Add(packetFragId, incomingFragments); } + else if (p.FragmentsTotal != incomingFragments.TotalFragments || p.ChannelId != incomingFragments.ChannelId) + { + NetManager.PoolRecycle(p); + NetDebug.WriteError("Fragment metadata mismatch"); + return; + } - //Cache - var fragments = incomingFragments.Fragments; - - //Error check - if (p.FragmentPart >= fragments.Length || - fragments[p.FragmentPart] != null || - p.ChannelId != incomingFragments.ChannelId) + if (incomingFragments.Contains(p.FragmentPart)) { NetManager.PoolRecycle(p); - NetDebug.WriteError("Invalid fragment packet"); return; } - //Fill array - fragments[p.FragmentPart] = p; - //Increase received fragments count + incomingFragments.Set(p.FragmentPart, p); incomingFragments.ReceivedCount++; - - //Increase total size incomingFragments.TotalSize += p.Size - NetConstants.FragmentedHeaderTotalSize; + incomingFragments.LastReceivedTime = _updateTime; - //Check for finish - if (incomingFragments.ReceivedCount != fragments.Length) + if (incomingFragments.ReceivedCount != incomingFragments.TotalFragments) return; - //just simple packet NetPacket resultingPacket = NetManager.PoolGetPacket(incomingFragments.TotalSize); + void AbortReassembly(string error) + { + _holdedFragments.Remove(packetFragId); + incomingFragments.RecycleAll(NetManager); + NetManager.PoolRecycle(resultingPacket); + NetDebug.WriteError(error); + } + int pos = 0; - for (int i = 0; i < incomingFragments.ReceivedCount; i++) + for (ushort i = 0; i < incomingFragments.TotalFragments; i++) { - var fragment = fragments[i]; + if (!incomingFragments.TryGet(i, out var fragment)) + { + AbortReassembly($"Fragment {i} missing during reassembly"); + return; + } + int writtenSize = fragment.Size - NetConstants.FragmentedHeaderTotalSize; - if (pos+writtenSize > resultingPacket.RawData.Length) + if (pos + writtenSize > resultingPacket.RawData.Length) { - _holdedFragments.Remove(packetFragId); - NetDebug.WriteError($"Fragment error pos: {pos + writtenSize} >= resultPacketSize: {resultingPacket.RawData.Length} , totalSize: {incomingFragments.TotalSize}"); + AbortReassembly($"Fragment error pos: {pos + writtenSize} >= resultPacketSize: {resultingPacket.RawData.Length}"); return; } + if (fragment.Size > fragment.RawData.Length) { - _holdedFragments.Remove(packetFragId); - NetDebug.WriteError($"Fragment error size: {fragment.Size} > fragment.RawData.Length: {fragment.RawData.Length}"); + AbortReassembly($"Fragment error size: {fragment.Size} > fragment.RawData.Length: {fragment.RawData.Length}"); return; } - //Create resulting big packet Buffer.BlockCopy( fragment.RawData, NetConstants.FragmentedHeaderTotalSize, @@ -837,15 +909,11 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) writtenSize); pos += writtenSize; - //Free memory NetManager.PoolRecycle(fragment); - fragments[i] = null; + incomingFragments.Remove(i); } - //Clear memory _holdedFragments.Remove(packetFragId); - - //Send to process NetManager.CreateReceiveEvent(resultingPacket, method, (byte)(packetChannelId / NetConstants.ChannelTypeCount), 0, this); } else //Just simple packet @@ -1154,6 +1222,8 @@ protected virtual void UpdateChannels() internal void Update(float deltaTime) { + _updateTime += deltaTime; + Interlocked.Exchange(ref _timeSinceLastPacket, _timeSinceLastPacket + deltaTime); switch (_connectionState) { @@ -1230,6 +1300,28 @@ internal void Update(float deltaTime) UpdateMtuLogic(deltaTime); + if (_holdedFragments.Count > 0) + { + List expired = null; + foreach (var kv in _holdedFragments) + { + if (_updateTime - kv.Value.LastReceivedTime > NetManager.FragmentTimeout) + { + expired ??= new List(); + expired.Add(kv.Key); + } + } + + if (expired != null) + { + foreach (ushort fragId in expired) + { + if (_holdedFragments.Remove(fragId, out var fragments)) + fragments.RecycleAll(NetManager); + } + } + } + UpdateChannels(); if (_unreliablePendingCount > 0) From 37eeabe960f1aac2b9fe421c3c074ae658e888b8 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 18 Mar 2026 23:55:02 +0300 Subject: [PATCH 173/261] Remove timeout --- LiteNetLib/LiteNetManager.cs | 5 ----- LiteNetLib/LiteNetPeer.cs | 32 ++------------------------------ 2 files changed, 2 insertions(+), 35 deletions(-) diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index 85688933..572fd105 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -205,11 +205,6 @@ private struct OutboundDelayedPacket /// public ushort MaxFragmentsCount = ushort.MaxValue; - /// - /// Fragmented packet timeout - /// - public ushort FragmentTimeout = 3000; - /// /// NatPunchModule for NAT hole punching operations /// diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 8d132121..96997b9e 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -111,13 +111,11 @@ private class IncomingFragments public readonly byte ChannelId; public int ReceivedCount; public int TotalSize; - public float LastReceivedTime; - public IncomingFragments(ushort totalFragments, byte channelId, float now) + public IncomingFragments(ushort totalFragments, byte channelId) { TotalFragments = totalFragments; ChannelId = channelId; - LastReceivedTime = now; if (totalFragments <= ArrayThreshold) _array = new NetPacket[totalFragments]; else @@ -168,7 +166,6 @@ public void RecycleAll(LiteNetManager netManager) } } private int _fragmentId; - private float _updateTime; private readonly Dictionary _holdedFragments; private readonly Dictionary _deliveredFragments; @@ -844,7 +841,7 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) return; } - incomingFragments = new IncomingFragments(p.FragmentsTotal, p.ChannelId, _updateTime); + incomingFragments = new IncomingFragments(p.FragmentsTotal, p.ChannelId); _holdedFragments.Add(packetFragId, incomingFragments); } else if (p.FragmentsTotal != incomingFragments.TotalFragments || p.ChannelId != incomingFragments.ChannelId) @@ -863,7 +860,6 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) incomingFragments.Set(p.FragmentPart, p); incomingFragments.ReceivedCount++; incomingFragments.TotalSize += p.Size - NetConstants.FragmentedHeaderTotalSize; - incomingFragments.LastReceivedTime = _updateTime; if (incomingFragments.ReceivedCount != incomingFragments.TotalFragments) return; @@ -1222,8 +1218,6 @@ protected virtual void UpdateChannels() internal void Update(float deltaTime) { - _updateTime += deltaTime; - Interlocked.Exchange(ref _timeSinceLastPacket, _timeSinceLastPacket + deltaTime); switch (_connectionState) { @@ -1300,28 +1294,6 @@ internal void Update(float deltaTime) UpdateMtuLogic(deltaTime); - if (_holdedFragments.Count > 0) - { - List expired = null; - foreach (var kv in _holdedFragments) - { - if (_updateTime - kv.Value.LastReceivedTime > NetManager.FragmentTimeout) - { - expired ??= new List(); - expired.Add(kv.Key); - } - } - - if (expired != null) - { - foreach (ushort fragId in expired) - { - if (_holdedFragments.Remove(fragId, out var fragments)) - fragments.RecycleAll(NetManager); - } - } - } - UpdateChannels(); if (_unreliablePendingCount > 0) From 3645b3189b37d627e3dcc30361ea8cd848758e0a Mon Sep 17 00:00:00 2001 From: Alexander Fields Date: Wed, 18 Mar 2026 20:34:21 -0400 Subject: [PATCH 174/261] Add automated NuGet publishing workflow --- .github/workflows/nuget-publish.yml | 90 +++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 .github/workflows/nuget-publish.yml diff --git a/.github/workflows/nuget-publish.yml b/.github/workflows/nuget-publish.yml new file mode 100644 index 00000000..afe7e34b --- /dev/null +++ b/.github/workflows/nuget-publish.yml @@ -0,0 +1,90 @@ +name: Publish NuGet Package + +on: + push: + branches: [ master ] + workflow_dispatch: + +jobs: + publish-release: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup .NET + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + + - name: Restore dependencies + run: dotnet restore + + - name: Build LiteNetLib + run: dotnet build LiteNetLib/LiteNetLib.csproj --configuration Release + + - name: Check version and pack if changed + id: check-pack + run: | + echo "Checking for version changes..." + + PROJECT_PATH="LiteNetLib/LiteNetLib.csproj" + PACKAGE_NAME="litenetlib" + + # Extract version from project file + LOCAL_VERSION=$(grep -o '[^<]*' "$PROJECT_PATH" | sed 's/\(.*\)<\/Version>/\1/') + + if [ -z "$LOCAL_VERSION" ]; then + echo "No tag found in $PROJECT_PATH" + echo "has_packages=false" >> $GITHUB_OUTPUT + exit 0 + fi + + # Get the latest version from NuGet.org + echo "Checking NuGet.org for $PACKAGE_NAME..." + NUGET_VERSION=$(curl -s "https://api.nuget.org/v3-flatcontainer/$PACKAGE_NAME/index.json" | grep -o '"[^"]*"' | sed 's/"//g' | sort -V | tail -n 1) + + echo "Local version: $LOCAL_VERSION" + echo "NuGet version: $NUGET_VERSION" + + # Compare versions + if [ "$LOCAL_VERSION" != "$NUGET_VERSION" ]; then + echo "Version changed - will pack and publish" + mkdir -p ./nupkgs + dotnet pack "$PROJECT_PATH" --configuration Release --no-build --output ./nupkgs + echo "has_packages=true" >> $GITHUB_OUTPUT + else + echo "Version unchanged - skipping" + echo "has_packages=false" >> $GITHUB_OUTPUT + fi + + - name: Push to NuGet.org + if: steps.check-pack.outputs.has_packages == 'true' + env: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + run: | + echo "Publishing to NuGet.org..." + for package in ./nupkgs/*.nupkg; do + if [ -f "$package" ]; then + echo "Publishing $package..." + dotnet nuget push "$package" --api-key "$NUGET_API_KEY" --source https://api.nuget.org/v3/index.json --skip-duplicate || { + echo "Failed to publish $package" + exit 1 + } + fi + done + + - name: Upload package as artifact + if: steps.check-pack.outputs.has_packages == 'true' + uses: actions/upload-artifact@v4 + with: + name: nuget-package + path: ./nupkgs/*.nupkg + retention-days: 7 + + - name: No package to publish + if: steps.check-pack.outputs.has_packages == 'false' + run: echo "Version unchanged - nothing to publish" From aa637599103ad04b737a68bb4cdbf02126aed616 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:37:09 +0100 Subject: [PATCH 175/261] Update NetDataReader - Add documentation - Update methods to be faster --- LiteNetLib/Utils/NetDataReader.cs | 549 +++++++++++++++++++++++++----- 1 file changed, 468 insertions(+), 81 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index b8599e43..3271c064 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -1,57 +1,95 @@ using System; using System.Net; +using System.Net.Sockets; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace LiteNetLib.Utils { - public class NetDataReader + public unsafe class NetDataReader { protected byte[] _data; protected int _position; protected int _dataSize; protected int _offset; + /// + /// Gets the internal array containing the raw network data. + /// public byte[] RawData { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _data; } + + /// + /// Gets the total size of the buffer. + /// public int RawDataSize { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _dataSize; } + + /// + /// Gets the starting offset of the user payload within the . + /// public int UserDataOffset { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _offset; } + + /// + /// Gets the size of the user payload excluding the initial . + /// public int UserDataSize { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _dataSize - _offset; } + + /// + /// Gets a value indicating whether the internal data buffer is . + /// public bool IsNull { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _data == null; } + + /// + /// Gets the current read position within the buffer. + /// public int Position { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _position; } + + /// + /// Gets a value indicating whether the has reached the end of the data. + /// public bool EndOfData { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _position == _dataSize; } + + /// + /// Gets the number of s remaining to be read. + /// public int AvailableBytes { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _dataSize - _position; } + /// + /// Verifies that the buffer has at least s available to read. + /// + /// The number of s required. + /// Thrown if exceeds or is negative. [MethodImpl(MethodImplOptions.AggressiveInlining)] private void EnsureAvailable(int count) { @@ -60,10 +98,22 @@ private void EnsureAvailable(int count) $"Not enough data to read {count} byte(s). Position={_position}, DataSize={_dataSize}"); } + /// + /// Advances the by the specified . + /// + /// The number of s to skip. public void SkipBytes(int count) => _position += count; + /// + /// Sets the current read to a specific index. + /// + /// The index to move the to. public void SetPosition(int position) => _position = position; + /// + /// Reinitializes the reader using data from a . + /// + /// The source . public void SetSource(NetDataWriter dataWriter) { _data = dataWriter.Data; @@ -72,6 +122,10 @@ public void SetSource(NetDataWriter dataWriter) _dataSize = dataWriter.Length; } + /// + /// Reinitializes the reader using a array. + /// + /// The source array. public void SetSource(byte[] source) { _data = source; @@ -80,6 +134,12 @@ public void SetSource(byte[] source) _dataSize = source.Length; } + /// + /// Reinitializes the reader using a segment of a array. + /// + /// The source array. + /// The starting index for reading. + /// The total number of s available to read from the . public void SetSource(byte[] source, int offset, int maxSize) { _data = source; @@ -98,20 +158,43 @@ public NetDataReader() { } #region GetMethods + /// + /// Deserializes a that implements . + /// + /// A type implementing . + /// The deserialized output. public void Get(out T result) where T : struct, INetSerializable { - result = default(T); + result = default; result.Deserialize(this); } + /// + /// Deserializes a that implements using a provided constructor. + /// + /// A type implementing . + /// The deserialized instance output. + /// A factory used to instantiate the . public void Get(out T result, Func constructor) where T : class, INetSerializable { result = constructor(); result.Deserialize(this); } + /// + /// Deserializes an and assigns it to the parameter. + /// + /// The deserialized output. public void Get(out IPEndPoint result) => result = GetIPEndPoint(); + /// + /// Reads an from the current . + /// + /// The deserialized . + /// + /// Reads a to determine the (0 for IPv4, 1 for IPv6), + /// followed by the address bytes and a 2-byte port. + /// public IPEndPoint GetIPEndPoint() { IPAddress address; @@ -132,30 +215,82 @@ public IPEndPoint GetIPEndPoint() return new IPEndPoint(address, GetUShort()); } + /// Reads a and assigns it to . public void Get(out byte result) => result = GetByte(); + + /// Reads an and assigns it to . public void Get(out sbyte result) => result = (sbyte)GetByte(); + + /// Reads a and assigns it to . public void Get(out bool result) => result = GetBool(); + + /// Reads a and assigns it to . public void Get(out char result) => result = GetChar(); + + /// Reads a and assigns it to . public void Get(out ushort result) => result = GetUShort(); + + /// Reads a and assigns it to . public void Get(out short result) => result = GetShort(); + + /// Reads a and assigns it to . public void Get(out ulong result) => result = GetULong(); + + /// Reads a and assigns it to . public void Get(out long result) => result = GetLong(); + + /// Reads a and assigns it to . public void Get(out uint result) => result = GetUInt(); + + /// Reads an and assigns it to . public void Get(out int result) => result = GetInt(); + + /// Reads a and assigns it to . public void Get(out double result) => result = GetDouble(); + + /// Reads a and assigns it to . public void Get(out float result) => result = GetFloat(); + + /// Reads a and assigns it to . public void Get(out string result) => result = GetString(); + + /// Reads a with a length limit and assigns it to . public void Get(out string result, int maxLength) => result = GetString(maxLength); + + /// Reads a and assigns it to . public void Get(out Guid result) => result = GetGuid(); + /// Reads the next from the buffer. public byte GetByte() => _data[_position++]; + /// Reads the next from the buffer. public sbyte GetSByte() => (sbyte)GetByte(); + /// + /// Reads an array of unmanaged values prefixed by a length. + /// + /// An unmanaged type. + /// A new array of type . + public T[] GetUnmanagedArray() where T : unmanaged + { + ushort length = GetUShort(); + int byteLength = length * sizeof(T); + ReadOnlySpan slice = _data.AsSpan(_position, byteLength); + T[] result = MemoryMarshal.Cast(slice) + .ToArray(); + _position += byteLength; + return result; + } + + /// + /// Reads an array of values by performing a direct memory copy. + /// + /// The element type. + /// The size of a single element in s. + /// A new array of type . public T[] GetArray(ushort size) { - ushort length = BitConverter.ToUInt16(_data, _position); - _position += 2; + ushort length = GetUShort(); int byteLength = checked(length * size); EnsureAvailable(byteLength); @@ -168,10 +303,14 @@ public T[] GetArray(ushort size) return result; } + /// + /// Reads an array of objects implementing . + /// + /// A type with a parameterless constructor implementing . + /// A new array of type . public T[] GetArray() where T : INetSerializable, new() { - ushort length = BitConverter.ToUInt16(_data, _position); - _position += 2; + ushort length = GetUShort(); T[] result = new T[length]; for (int i = 0; i < length; i++) { @@ -182,26 +321,55 @@ public T[] GetArray(ushort size) return result; } + /// + /// Reads an array of objects implementing using a specific constructor. + /// + /// A type implementing . + /// The factory used to create instances. + /// A new array of type . public T[] GetArray(Func constructor) where T : class, INetSerializable { - ushort length = BitConverter.ToUInt16(_data, _position); - _position += 2; + ushort length = GetUShort(); T[] result = new T[length]; for (int i = 0; i < length; i++) Get(out result[i], constructor); return result; } - public bool[] GetBoolArray() => GetArray(1); - public ushort[] GetUShortArray() => GetArray(2); - public short[] GetShortArray() => GetArray(2); - public int[] GetIntArray() => GetArray(4); - public uint[] GetUIntArray() => GetArray(4); - public float[] GetFloatArray() => GetArray(4); - public double[] GetDoubleArray() => GetArray(8); - public long[] GetLongArray() => GetArray(8); - public ulong[] GetULongArray() => GetArray(8); + /// Reads an array of values. + public bool[] GetBoolArray() => GetUnmanagedArray(); + + /// Reads an array of values. + public ushort[] GetUShortArray() => GetUnmanagedArray(); + + /// Reads an array of values. + public short[] GetShortArray() => GetUnmanagedArray(); + + /// Reads an array of values. + public int[] GetIntArray() => GetUnmanagedArray(); + + /// Reads an array of values. + public uint[] GetUIntArray() => GetUnmanagedArray(); + /// Reads an array of values. + public float[] GetFloatArray() => GetUnmanagedArray(); + + /// Reads an array of values. + public double[] GetDoubleArray() => GetUnmanagedArray(); + + /// Reads an array of values. + public long[] GetLongArray() => GetUnmanagedArray(); + + /// Reads an array of values. + public ulong[] GetULongArray() => GetUnmanagedArray(); + + /// + /// Reads an array of values. + /// + /// A new array. + /// + /// Reads a 2-byte length header followed by each element. + /// public string[] GetStringArray() { ushort length = GetUShort(); @@ -214,9 +382,13 @@ public string[] GetStringArray() } /// - /// Note that "maxStringLength" only limits the number of characters in a string, not its size in bytes. - /// Strings that exceed this parameter are returned as empty + /// Reads an array of values with a maximum character limit per element. /// + /// The maximum number of characters allowed per . + /// A new array. + /// + /// Strings exceeding are returned as . + /// public string[] GetStringArray(int maxStringLength) { ushort length = GetUShort(); @@ -228,69 +400,45 @@ public string[] GetStringArray(int maxStringLength) return arr; } + /// Reads a value from the current position. + /// if the byte is 1; otherwise, . public bool GetBool() => GetByte() == 1; + + /// Reads a value as a 2-byte . public char GetChar() => (char)GetUShort(); - public ushort GetUShort() - { - ushort result = BitConverter.ToUInt16(_data, _position); - _position += 2; - return result; - } + /// Reads a value using unmanaged memory access. + public ushort GetUShort() => GetUnmanaged(); - public short GetShort() - { - short result = BitConverter.ToInt16(_data, _position); - _position += 2; - return result; - } + /// Reads a value using unmanaged memory access. + public short GetShort() => GetUnmanaged(); - public long GetLong() - { - long result = BitConverter.ToInt64(_data, _position); - _position += 8; - return result; - } + /// Reads a value using unmanaged memory access. + public long GetLong() => GetUnmanaged(); - public ulong GetULong() - { - ulong result = BitConverter.ToUInt64(_data, _position); - _position += 8; - return result; - } + /// Reads a value using unmanaged memory access. + public ulong GetULong() => GetUnmanaged(); - public int GetInt() - { - int result = BitConverter.ToInt32(_data, _position); - _position += 4; - return result; - } + /// Reads an value using unmanaged memory access. + public int GetInt() => GetUnmanaged(); - public uint GetUInt() - { - uint result = BitConverter.ToUInt32(_data, _position); - _position += 4; - return result; - } + /// Reads a value using unmanaged memory access. + public uint GetUInt() => GetUnmanaged(); - public float GetFloat() - { - float result = BitConverter.ToSingle(_data, _position); - _position += 4; - return result; - } + /// Reads a value using unmanaged memory access. + public float GetFloat() => GetUnmanaged(); - public double GetDouble() - { - double result = BitConverter.ToDouble(_data, _position); - _position += 8; - return result; - } + /// Reads a value using unmanaged memory access. + public double GetDouble() => GetUnmanaged(); /// - /// Note that "maxLength" only limits the number of characters in a string, not its size in bytes. + /// Reads a with a maximum character limit. /// - /// "string.Empty" if value > "maxLength" + /// The maximum allowed character count. + /// The deserialized , or if the character count exceeds . + /// + /// Note that limits the number of characters, not the total size in s. + /// public string GetString(int maxLength) { ushort size = GetUShort(); @@ -309,6 +457,10 @@ public string GetString(int maxLength) return result; } + /// + /// Reads a from the current position. + /// + /// The deserialized . public string GetString() { ushort size = GetUShort(); @@ -323,6 +475,10 @@ public string GetString() return result; } + /// + /// Reads a prefixed with a 4-byte length header. + /// + /// The deserialized . public string GetLargeString() { int size = GetInt(); @@ -336,6 +492,10 @@ public string GetLargeString() return result; } + /// + /// Reads a 16-byte . + /// + /// The deserialized . public Guid GetGuid() { EnsureAvailable(16); @@ -344,6 +504,11 @@ public Guid GetGuid() return result; } + /// + /// Gets an of s from the current position. + /// + /// The number of s to include in the segment. + /// An wrapping the internal buffer. public ArraySegment GetBytesSegment(int count) { EnsureAvailable(count); @@ -352,6 +517,10 @@ public ArraySegment GetBytesSegment(int count) return segment; } + /// + /// Gets an containing all remaining s. + /// + /// An from the current position to the end of the data. public ArraySegment GetRemainingBytesSegment() { ArraySegment segment = new ArraySegment(_data, _position, AvailableBytes); @@ -359,6 +528,11 @@ public ArraySegment GetRemainingBytesSegment() return segment; } + /// + /// Deserializes a that implements . + /// + /// A type implementing . + /// The deserialized . public T Get() where T : struct, INetSerializable { var obj = default(T); @@ -366,6 +540,12 @@ public T Get() where T : struct, INetSerializable return obj; } + /// + /// Deserializes a that implements using a provided constructor. + /// + /// A type implementing . + /// The factory used to instantiate the . + /// A new instance of . public T Get(Func constructor) where T : class, INetSerializable { var obj = constructor(); @@ -373,14 +553,29 @@ public T Get(Func constructor) where T : class, INetSerializable return obj; } + /// + /// Returns a of s containing all remaining data. + /// + /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan GetRemainingBytesSpan() => new ReadOnlySpan(_data, _position, _dataSize - _position); + /// + /// Returns a of s containing all remaining data. + /// + /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory GetRemainingBytesMemory() => new ReadOnlyMemory(_data, _position, _dataSize - _position); + /// + /// Reads all remaining s and returns them as a new array. + /// + /// A new array containing the remaining data. + /// + /// This method performs a heap allocation and advances the to the end of the data. + /// public byte[] GetRemainingBytes() { byte[] outgoingData = new byte[AvailableBytes]; @@ -389,6 +584,12 @@ public byte[] GetRemainingBytes() return outgoingData; } + /// + /// Copies a specified number of s into a destination array at a specific offset. + /// + /// The array to copy data into. + /// The starting index in the array. + /// The number of s to read. public void GetBytes(byte[] destination, int start, int count) { EnsureAvailable(count); @@ -396,6 +597,11 @@ public void GetBytes(byte[] destination, int start, int count) _position += count; } + /// + /// Copies a specified number of s into a destination array starting at index 0. + /// + /// The array to copy data into. + /// The number of s to read. public void GetBytes(byte[] destination, int count) { EnsureAvailable(count); @@ -403,28 +609,140 @@ public void GetBytes(byte[] destination, int count) _position += count; } - public sbyte[] GetSBytesWithLength() => GetArray(1); - public byte[] GetBytesWithLength() => GetArray(1); + /// + /// Reads an array prefixed with its length. + /// + /// A new array. + public sbyte[] GetSBytesWithLength() => GetUnmanagedArray(); + + /// + /// Reads a array prefixed with its length. + /// + /// A new array. + public byte[] GetBytesWithLength() => GetUnmanagedArray(); + + /// + /// Reads a value of type from the internal byte buffer at the current position, + /// advancing the position by the size of . + /// + /// An unmanaged value type to read from the buffer. + /// The value of type read from the buffer. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T GetUnmanaged() where T : unmanaged + { + var size = sizeof(T); + EnsureAvailable(size); + +#if NET8_0_OR_GREATER + var value = Unsafe.ReadUnaligned(ref _data[_position]); +#else + T value; + fixed (byte* ptr = &_data[_position]) + { + value = *(T*)ptr; + } +#endif + + _position += size; + return value; + } + + /// + /// Reads a nullable value of type from the internal byte buffer at the current position, + /// first reading a indicating whether the value is present, + /// and then reading the value itself if it exists.
+ /// Advances the position by 1 byte for the presence flag plus the size of if the value is present. + ///
+ /// An unmanaged value type to read from the buffer. + /// + /// The nullable value of type read from the buffer. + /// Returns if the presence flag indicates no value. + /// + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T? GetNullableUnmanaged() where T : unmanaged + { + var hasValue = GetBool(); + if (!hasValue) + { + return null; + } + + return GetUnmanaged(); + } + + /// + /// Reads an enum value of type from the internal data buffer at the current position.
+ /// Advances the position by the size of . + ///
+ /// An unmanaged enum type to read. + /// The enum value read from the buffer. + public T GetEnum() where T : unmanaged, Enum + { + var span = GetSpan(sizeof(T)); +#if NET8_0_OR_GREATER + return Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(span)); +#else + fixed (byte* ptr = span) + { + return *(T*)ptr; + } +#endif + } + + public ReadOnlySpan GetSpan(int length) + { + ReadOnlySpan span = new ReadOnlySpan(_data, _position, length); + _position += length; + return span; + } + #endregion #region PeekMethods + /// Reads the at the current position without advancing the . public byte PeekByte() => _data[_position]; + + /// Reads the at the current position without advancing the . public sbyte PeekSByte() => (sbyte)_data[_position]; + + /// Reads the at the current position without advancing the . public bool PeekBool() => _data[_position] == 1; - public char PeekChar() => (char)PeekUShort(); - public ushort PeekUShort() => BitConverter.ToUInt16(_data, _position); - public short PeekShort() => BitConverter.ToInt16(_data, _position); - public long PeekLong() => BitConverter.ToInt64(_data, _position); - public ulong PeekULong() => BitConverter.ToUInt64(_data, _position); - public int PeekInt() => BitConverter.ToInt32(_data, _position); - public uint PeekUInt() => BitConverter.ToUInt32(_data, _position); - public float PeekFloat() => BitConverter.ToSingle(_data, _position); - public double PeekDouble() => BitConverter.ToDouble(_data, _position); + + /// Reads the at the current position without advancing the . + public char PeekChar() => PeekUnmanaged(); + + /// Reads the at the current position without advancing the . + public ushort PeekUShort() => PeekUnmanaged(); + + /// Reads the at the current position without advancing the . + public short PeekShort() => PeekUnmanaged(); + + /// Reads the at the current position without advancing the . + public long PeekLong() => PeekUnmanaged(); + + /// Reads the at the current position without advancing the . + public ulong PeekULong() => PeekUnmanaged(); + + /// Reads the at the current position without advancing the . + public int PeekInt() => PeekUnmanaged(); + + /// Reads the at the current position without advancing the . + public uint PeekUInt() => PeekUnmanaged(); + + /// Reads the at the current position without advancing the . + public float PeekFloat() => PeekUnmanaged(); + + /// Reads the at the current position without advancing the . + public double PeekDouble() => PeekUnmanaged(); /// - /// Note that "maxLength" only limits the number of characters in a string, not its size in bytes. + /// Reads a with a character limit without advancing the . /// + /// Maximum allowed character count. + /// Strings exceeding are returned as . public string PeekString(int maxLength) { ushort size = PeekUShort(); @@ -437,6 +755,9 @@ public string PeekString(int maxLength) : NetDataWriter.uTF8Encoding.GetString(_data, _position + 2, actualSize); } + /// + /// Reads a without advancing the . + /// public string PeekString() { ushort size = PeekUShort(); @@ -446,9 +767,32 @@ public string PeekString() int actualSize = size - 1; return NetDataWriter.uTF8Encoding.GetString(_data, _position + 2, actualSize); } + + /// + /// Reads an unmanaged value of type at the current position without advancing the . + /// + /// An unmanaged value type. + /// The value read from the buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public T PeekUnmanaged() where T : unmanaged + { +#if NET8_0_OR_GREATER + return Unsafe.ReadUnaligned(ref _data[_position]); +#else + T value; + fixed (byte* ptr = &_data[_position]) + { + value = *(T*)ptr; + } + return value; +#endif + } #endregion #region TryGetMethods + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetByte(out byte result) { if (AvailableBytes >= 1) @@ -460,6 +804,9 @@ public bool TryGetByte(out byte result) return false; } + /// Attempts to read an without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetSByte(out sbyte result) { if (AvailableBytes >= 1) @@ -471,6 +818,9 @@ public bool TryGetSByte(out sbyte result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or if failed. + /// if enough data was available; otherwise, . public bool TryGetBool(out bool result) { if (AvailableBytes >= 1) @@ -482,6 +832,9 @@ public bool TryGetBool(out bool result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or '\0' if failed. + /// if enough data was available; otherwise, . public bool TryGetChar(out char result) { if (!TryGetUShort(out ushort uShortValue)) @@ -493,6 +846,9 @@ public bool TryGetChar(out char result) return true; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetShort(out short result) { if (AvailableBytes >= 2) @@ -504,6 +860,9 @@ public bool TryGetShort(out short result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetUShort(out ushort result) { if (AvailableBytes >= 2) @@ -515,6 +874,9 @@ public bool TryGetUShort(out ushort result) return false; } + /// Attempts to read an without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetInt(out int result) { if (AvailableBytes >= 4) @@ -526,6 +888,9 @@ public bool TryGetInt(out int result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetUInt(out uint result) { if (AvailableBytes >= 4) @@ -537,6 +902,9 @@ public bool TryGetUInt(out uint result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetLong(out long result) { if (AvailableBytes >= 8) @@ -548,6 +916,9 @@ public bool TryGetLong(out long result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetULong(out ulong result) { if (AvailableBytes >= 8) @@ -559,6 +930,9 @@ public bool TryGetULong(out ulong result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetFloat(out float result) { if (AvailableBytes >= 4) @@ -570,6 +944,9 @@ public bool TryGetFloat(out float result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. + /// if enough data was available; otherwise, . public bool TryGetDouble(out double result) { if (AvailableBytes >= 8) @@ -581,6 +958,9 @@ public bool TryGetDouble(out double result) return false; } + /// Attempts to read a without throwing an exception. + /// The deserialized , or if failed. + /// if enough data was available; otherwise, . public bool TryGetString(out string result) { if (AvailableBytes >= 2) @@ -598,6 +978,9 @@ public bool TryGetString(out string result) return false; } + /// Attempts to read a array without throwing an exception. + /// The deserialized array, or if failed. + /// if enough data was available; otherwise, . public bool TryGetStringArray(out string[] result) { if (!TryGetUShort(out ushort strArrayLength)) @@ -619,6 +1002,9 @@ public bool TryGetStringArray(out string[] result) return true; } + /// Attempts to read a array with a length header without throwing an exception. + /// The deserialized array, or if failed. + /// if enough data was available; otherwise, . public bool TryGetBytesWithLength(out byte[] result) { if (AvailableBytes >= 2) @@ -635,6 +1021,7 @@ public bool TryGetBytesWithLength(out byte[] result) } #endregion + /// Clears the reader state and releases the reference to the internal buffer. public void Clear() { _position = 0; From bbaf4b43c9fc3f28c1f10e597ec09bd848778c84 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:37:16 +0100 Subject: [PATCH 176/261] Update NetDataWriter - Add documentation - Update methods to be faster --- LiteNetLib/Utils/NetDataWriter.cs | 498 ++++++++++++++++++++++++------ 1 file changed, 403 insertions(+), 95 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index ada5c6e5..0849c0a3 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -2,33 +2,59 @@ using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; using System.Text; namespace LiteNetLib.Utils { - public class NetDataWriter + public unsafe class NetDataWriter { protected byte[] _data; protected int _position; private const int InitialSize = 64; private readonly bool _autoResize; + /// + /// Gets the total capacity of the internal buffer. + /// + /// The length of the underlying array. public int Capacity { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _data.Length; } + + /// + /// Gets the underlying array used by this writer. + /// + /// The internal array. + /// + /// Accessing this directly allows for external manipulation but bypasses bounds checking. + /// public byte[] Data { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _data; } + + /// + /// Gets the current number of s written to the buffer. + /// + /// The current . public int Length { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _position; } + /// + /// Returns a representing the currently used portion of the internal buffer. + /// + /// A from index 0 to . + /// + /// Provides a high-performance, zero-allocation view of the data. + /// The span becomes invalid if the internal buffer is resized or if changes. + /// public ReadOnlySpan AsReadOnlySpan() => new ReadOnlySpan(_data, 0, _position); internal static readonly UTF8Encoding uTF8Encoding = new UTF8Encoding(false, true); @@ -82,6 +108,11 @@ public static NetDataWriter FromBytes(Span bytes) return netDataWriter; } + /// + /// Creates a new and serializes a into it. + /// + /// The to serialize. + /// A new instance containing the serialized . public static NetDataWriter FromString(string value) { var netDataWriter = new NetDataWriter(); @@ -89,6 +120,14 @@ public static NetDataWriter FromString(string value) return netDataWriter; } + /// + /// Ensures the internal buffer is at least . + /// + /// The required minimum size of the buffer. + /// + /// If an allocation is necessary, the buffer grows to either + /// or doubles its current size, whichever is larger. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ResizeIfNeed(int newSize) { @@ -98,6 +137,14 @@ public void ResizeIfNeed(int newSize) } } + /// + /// Ensures the internal buffer can accommodate more s. + /// + /// The number of additional s to fit. + /// + /// This checks against the current . If the capacity is insufficient, + /// the buffer grows to either the required size or doubles its current size. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void EnsureFit(int additionalSize) { @@ -107,14 +154,32 @@ public void EnsureFit(int additionalSize) } } + + /// + /// Resets the to 0 and ensures the internal buffer has at least the specified . + /// + /// The minimum capacity required for the internal buffer. + /// + /// If the current buffer is smaller than , will allocate a larger array. + /// public void Reset(int size) { ResizeIfNeed(size); _position = 0; } + /// + /// Resets the to 0, effectively clearing the buffer for reuse. + /// public void Reset() => _position = 0; + /// + /// Creates a array containing the current data from the internal buffer. + /// + /// A new array of length . + /// + /// This method performs a heap allocation and copies the data using . + /// public byte[] CopyData() { byte[] resultData = new byte[_position]; @@ -134,88 +199,76 @@ public int SetPosition(int position) return prevPosition; } - public void Put(float value) - { - if (_autoResize) - ResizeIfNeed(_position + 4); - FastBitConverter.GetBytes(_data, _position, value); - _position += 4; - } + /// + /// Serializes a value. + /// + /// The value to write. + public void Put(float value) => PutUnmanaged(value); - public void Put(double value) - { - if (_autoResize) - ResizeIfNeed(_position + 8); - FastBitConverter.GetBytes(_data, _position, value); - _position += 8; - } + /// + /// Serializes a value. + /// + /// The value to write. + public void Put(double value) => PutUnmanaged(value); - public void Put(long value) - { - if (_autoResize) - ResizeIfNeed(_position + 8); - FastBitConverter.GetBytes(_data, _position, value); - _position += 8; - } + /// + /// Serializes a value. + /// + /// The value to write. + public void Put(long value) => PutUnmanaged(value); - public void Put(ulong value) - { - if (_autoResize) - ResizeIfNeed(_position + 8); - FastBitConverter.GetBytes(_data, _position, value); - _position += 8; - } + /// + /// Serializes a value. + /// + /// The value to write. + public void Put(ulong value) => PutUnmanaged(value); - public void Put(int value) - { - if (_autoResize) - ResizeIfNeed(_position + 4); - FastBitConverter.GetBytes(_data, _position, value); - _position += 4; - } + /// + /// Serializes an value. + /// + /// The value to write. + public void Put(int value) => PutUnmanaged(value); - public void Put(uint value) - { - if (_autoResize) - ResizeIfNeed(_position + 4); - FastBitConverter.GetBytes(_data, _position, value); - _position += 4; - } + /// + /// Serializes a value. + /// + /// The value to write. + public void Put(uint value) => PutUnmanaged(value); + /// + /// Serializes a value as a . + /// + /// The value to write. public void Put(char value) => Put((ushort)value); - public void Put(ushort value) - { - if (_autoResize) - ResizeIfNeed(_position + 2); - FastBitConverter.GetBytes(_data, _position, value); - _position += 2; - } + /// + /// Serializes a value. + /// + /// The value to write. + public void Put(ushort value) => PutUnmanaged(value); - public void Put(short value) - { - if (_autoResize) - ResizeIfNeed(_position + 2); - FastBitConverter.GetBytes(_data, _position, value); - _position += 2; - } + /// + /// Serializes a value. + /// + /// The value to write. + public void Put(short value) => PutUnmanaged(value); - public void Put(sbyte value) - { - if (_autoResize) - ResizeIfNeed(_position + 1); - _data[_position] = (byte)value; - _position++; - } + /// + /// Serializes an value. + /// + /// The value to write. + public void Put(sbyte value) => PutUnmanaged(value); - public void Put(byte value) - { - if (_autoResize) - ResizeIfNeed(_position + 1); - _data[_position] = value; - _position++; - } + /// + /// Serializes a value. + /// + /// The value to write. + public void Put(byte value) => PutUnmanaged(value); + /// + /// Serializes a value. + /// + /// The value to write. public void Put(Guid value) { if (_autoResize) @@ -224,22 +277,30 @@ public void Put(Guid value) _position += 16; } + /// + /// Serializes a segment of a array. + /// + /// The source array. + /// The starting index in the source array. + /// The number of s to write. public void Put(byte[] data, int offset, int length) { - if (_autoResize) - ResizeIfNeed(_position + length); - Buffer.BlockCopy(data, offset, _data, _position, length); - _position += length; + Put(data.AsSpan(offset, length)); } + /// + /// Serializes an entire array. + /// + /// The source array. public void Put(byte[] data) { - if (_autoResize) - ResizeIfNeed(_position + data.Length); - Buffer.BlockCopy(data, 0, _data, _position, data.Length); - _position += data.Length; + Put(data.AsSpan()); } + /// + /// Serializes a of s to the internal buffer. + /// + /// The span of data to write. public void Put(ReadOnlySpan data) { if (_autoResize) @@ -248,33 +309,99 @@ public void Put(ReadOnlySpan data) _position += data.Length; } + /// + /// Serializes a segment of an array prefixed with its length. + /// + /// The source array. + /// The starting index in the source array. + /// The number of elements to write. public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) { if (_autoResize) + { ResizeIfNeed(_position + 2 + length); - FastBitConverter.GetBytes(_data, _position, length); - Buffer.BlockCopy(data, offset, _data, _position + 2, length); - _position += 2 + length; + } + +#if NET8_0_OR_GREATER + Unsafe.WriteUnaligned(ref _data[_position], length); +#else + fixed (byte* ptr = &_data[_position]) + { + *(ushort*)ptr = length; + } +#endif + _position += 2; + + if (length > 0) + { + ReadOnlySpan source = data.AsSpan(offset, length); + ReadOnlySpan sourceBytes = MemoryMarshal.Cast(source); + + sourceBytes.CopyTo(_data.AsSpan(_position)); + _position += length; + } } + /// + /// Serializes an array prefixed with its length. + /// + /// The source array. public void PutSBytesWithLength(sbyte[] data) => PutArray(data, 1); + /// + /// Serializes a segment of a array prefixed with its length. + /// + /// The source array. + /// The starting index in the source array. + /// The number of s to write. public void PutBytesWithLength(byte[] data, int offset, ushort length) { if (_autoResize) + { ResizeIfNeed(_position + 2 + length); - FastBitConverter.GetBytes(_data, _position, length); - Buffer.BlockCopy(data, offset, _data, _position + 2, length); - _position += 2 + length; + } + +#if NET8_0_OR_GREATER + Unsafe.WriteUnaligned(ref _data[_position], length); +#else + fixed (byte* ptr = &_data[_position]) + { + *(ushort*)ptr = length; + } +#endif + _position += 2; + + if (length > 0) + { + data.AsSpan(offset, length).CopyTo(_data.AsSpan(_position)); + _position += length; + } } + /// + /// Serializes a array prefixed with its length. + /// + /// The source array. public void PutBytesWithLength(byte[] data) => PutArray(data, 1); + /// + /// Serializes a value as a single . + /// + /// The value to write. public void Put(bool value) => Put((byte)(value ? 1 : 0)); + /// + /// Serializes an prefixed with a 2-byte length. + /// + /// The source array to serialize. + /// The size of a single element in s. + /// + /// If the array is , a length of 0 is written.
+ /// The total payload size is calculated as length * sz. + ///
public void PutArray(Array arr, int sz) { - ushort length = arr == null ? (ushort) 0 : (ushort)arr.Length; + ushort length = arr == null ? (ushort)0 : (ushort)arr.Length; sz *= length; if (_autoResize) ResizeIfNeed(_position + sz + 2); @@ -284,16 +411,89 @@ public void PutArray(Array arr, int sz) _position += sz + 2; } - public void PutArray(float[] value) => PutArray(value, 4); - public void PutArray(double[] value) => PutArray(value, 8); - public void PutArray(long[] value) => PutArray(value, 8); - public void PutArray(ulong[] value) => PutArray(value, 8); - public void PutArray(int[] value) => PutArray(value, 4); - public void PutArray(uint[] value) => PutArray(value, 4); - public void PutArray(ushort[] value) => PutArray(value, 2); - public void PutArray(short[] value) => PutArray(value, 2); - public void PutArray(bool[] value) => PutArray(value, 1); + /// + /// Serializes an array of unmanaged values. + /// + /// The unmanaged type of the array elements. + /// The array to serialize. + public void PutUnmanagedArray(T[] arr) where T : unmanaged + { + PutSpan(arr.AsSpan()); + } + + /// + /// Serializes a of unmanaged values to the internal buffer. + /// + /// The unmanaged type of the span elements. + /// The span of data to write. + /// + /// Writes a 2-byte length header followed by the raw binary data.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PutSpan(Span span) where T : unmanaged + { + var length = (ushort)span.Length; + var byteLength = length * sizeof(T); + + if (_autoResize) + { + ResizeIfNeed(_position + byteLength + 2); + } + +#if NET8_0_OR_GREATER + Unsafe.WriteUnaligned(ref _data[_position], length); +#else + fixed (byte* ptr = &_data[_position]) + { + *(ushort*)ptr = length; + } +#endif + _position += 2; + + if (length > 0) + { + var sourceBytes = MemoryMarshal.AsBytes(span); + sourceBytes.CopyTo(_data.AsSpan(_position)); + _position += byteLength; + } + } + + /// + /// Serializes an array of unmanaged values to the internal buffer. + /// + public void PutArray(float[] value) => PutUnmanagedArray(value); + + /// + public void PutArray(double[] value) => PutUnmanagedArray(value); + + /// + public void PutArray(long[] value) => PutUnmanagedArray(value); + + /// + public void PutArray(ulong[] value) => PutUnmanagedArray(value); + + /// + public void PutArray(int[] value) => PutUnmanagedArray(value); + + /// + public void PutArray(uint[] value) => PutUnmanagedArray(value); + + /// + public void PutArray(ushort[] value) => PutUnmanagedArray(value); + + /// + public void PutArray(short[] value) => PutUnmanagedArray(value); + /// + public void PutArray(bool[] value) => PutUnmanagedArray(value); + + /// + /// Serializes an array of values. + /// + /// The array of elements to write. + /// + /// Writes a 2-byte length header followed by each element. + /// public void PutArray(string[] value) { ushort strArrayLength = value == null ? (ushort)0 : (ushort)value.Length; @@ -302,6 +502,11 @@ public void PutArray(string[] value) Put(value[i]); } + /// + /// Serializes an array of values with a maximum length constraint per element. + /// + /// The array of elements to write. + /// The maximum allowed length for each individual . public void PutArray(string[] value, int strMaxLength) { ushort strArrayLength = value == null ? (ushort)0 : (ushort)value.Length; @@ -310,6 +515,11 @@ public void PutArray(string[] value, int strMaxLength) Put(value[i], strMaxLength); } + /// + /// Serializes an array of objects implementing . + /// + /// A type that implements and has a parameterless constructor. + /// The array of objects to serialize. public void PutArray(T[] value) where T : INetSerializable, new() { ushort strArrayLength = (ushort)(value?.Length ?? 0); @@ -318,6 +528,14 @@ public void PutArray(string[] value, int strMaxLength) value[i].Serialize(this); } + /// + /// Serializes an . + /// + /// The network endpoint to write. + /// Thrown when the is not or . + /// + /// Writes a (0 for IPv4, 1 for IPv6), followed by the address bytes and a 2-byte port. + /// public void Put(IPEndPoint endPoint) { if (endPoint.AddressFamily == AddressFamily.InterNetwork) @@ -337,6 +555,14 @@ public void Put(IPEndPoint endPoint) Put((ushort)endPoint.Port); } + /// + /// Serializes a using a 4-byte length header. + /// + /// The to write. + /// + /// Recommended for strings that may exceed the 65535 byte limit of standard length headers.
+ /// Uses . + ///
public void PutLargeString(string value) { if (string.IsNullOrEmpty(value)) @@ -382,6 +608,88 @@ public void Put(string value, int maxLength = 0) _position += size; } + /// + /// Writes a value of type into the internal byte buffer at the current position, + /// advancing the position by the size of . + /// + /// An unmanaged value type to write into the buffer. + /// The value to write into the buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PutUnmanaged(T value) where T : unmanaged + { + int size = sizeof(T); + if (_autoResize) + { + ResizeIfNeed(_position + size); + } + +#if NET8_0_OR_GREATER + Unsafe.WriteUnaligned(ref _data[_position], value); +#else + fixed (byte* ptr = &_data[_position]) + { + *(T*)ptr = value; + } +#endif + + _position += size; + } + + /// + /// Writes a nullable value of type into the internal byte buffer at the current position, + /// first writing a indicating whether the value is present, + /// and then writing the value itself if it exists.
Advances the position by 1 byte for the presence flag plus + /// the size of if the value is present. + ///
+ /// An unmanaged value type to write into the buffer. + /// The nullable value to write into the buffer. If , only a flag is written. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void PutNullableUnmanaged(T? value) where T : unmanaged + { + bool hasValue = value.HasValue; + Put(hasValue); + if (!hasValue) + { + return; + } + + PutUnmanaged(value.Value); + } + + /// + /// Writes an enum value of type to the internal data buffer at the current position.
+ /// Automatically resizes the buffer if is enabled. + /// Advances the position by the size of . + ///
+ /// An unmanaged enum type to write. + /// The enum value to write. + public void PutEnum(T value) where T : unmanaged, Enum + { + var size = sizeof(T); + if (_autoResize) + { + ResizeIfNeed(_position + size); + } + +#if NET8_0_OR_GREATER + Unsafe.WriteUnaligned(ref _data[_position], value); +#else + fixed (byte* ptr = &_data[_position]) + { + *(T*)ptr = value; + } +#endif + _position += size; + } + + /// + /// Serializes an object implementing . + /// + /// A type that implements the interface. + /// The object instance to serialize. + /// + /// This method calls the method on the provided . + /// public void Put(T obj) where T : INetSerializable => obj.Serialize(this); } } From 966da96573bd152bb85181c17f74e7cb6fbc6284 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:37:46 +0100 Subject: [PATCH 177/261] Update NetSerializerTest - Added new Get/PutUnmanaged() methods - Added new GetEnum() method --- LiteNetLib.Tests/NetSerializerTest.cs | 43 +++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/LiteNetLib.Tests/NetSerializerTest.cs b/LiteNetLib.Tests/NetSerializerTest.cs index 301d5d6a..a8bd036a 100644 --- a/LiteNetLib.Tests/NetSerializerTest.cs +++ b/LiteNetLib.Tests/NetSerializerTest.cs @@ -23,15 +23,18 @@ public void Init() SomeGuid = Guid.NewGuid(), SomeVector2 = new SomeVector2(4, 5), SomeVectors = new[] { new SomeVector2(1, 2), new SomeVector2(3, 4) }, + SomeFastVector3 = new SomeFastVector3(0.21f, 100.25f, -400.0f), + SomeFastVectors = new[] { new SomeFastVector3(1.0f, 2.0f, 3.0f), new SomeFastVector3(4.0f, 5.0f, 6.0f) }, SomeEnum = TestEnum.B, SomeByteArray = new byte[] { 255, 1, 0 }, TestObj = new SampleNetSerializable { Value = 5 }, TestArray = new[] { new SampleNetSerializable { Value = 6 }, new SampleNetSerializable { Value = 15 } }, SampleClassArray = new[] - { FillTestArray(new SampleClass { Value = 6 }), FillTestArray(new SampleClass { Value = 15 }) }, + { FillTestArray(new SampleClass { Value = 6, TestEnum = TestEnum.C }), FillTestArray(new SampleClass { Value = 15, TestEnum = TestEnum.B }) }, SampleClassList = new List { FillTestArray(new SampleClass { Value = 1 }), FillTestArray(new SampleClass { Value = 5 }) }, VectorList = new List { new SomeVector2(-1, -2), new SomeVector2(700, 800) }, + FastVectorList = new List { new SomeFastVector3(-100.0f, -200.0f, -300.0f), new SomeFastVector3(100.0f, 200.0f, 300.0f) }, IgnoreMe = 1337 }; @@ -39,6 +42,7 @@ public void Init() _packetProcessor.RegisterNestedType(); _packetProcessor.RegisterNestedType(() => new SampleClass()); _packetProcessor.RegisterNestedType(SomeVector2.Serialize, SomeVector2.Deserialize); + _packetProcessor.RegisterNestedType(SomeFastVector3.Serialize, SomeFastVector3.Deserialize); } private SamplePacket _samplePacket; @@ -70,6 +74,30 @@ public static SomeVector2 Deserialize(NetDataReader reader) } } + private readonly struct SomeFastVector3 + { + public readonly float X; + public readonly float Y; + public readonly float Z; + + public SomeFastVector3(float x, float y, float z) + { + X = x; + Y = y; + Z = z; + } + + public static void Serialize(NetDataWriter writer, SomeFastVector3 vector) + { + writer.PutUnmanaged(vector); + } + + public static SomeFastVector3 Deserialize(NetDataReader reader) + { + return reader.GetUnmanaged(); + } + } + private struct SampleNetSerializable : INetSerializable { public int Value; @@ -89,24 +117,27 @@ private class SampleClass : INetSerializable { public int Value; public ChildClass[] TestArray = Array.Empty(); + public TestEnum TestEnum; public void Serialize(NetDataWriter writer) { writer.Put(Value); writer.PutArray(TestArray); + writer.PutEnum(TestEnum); } public void Deserialize(NetDataReader reader) { Value = reader.GetInt(); TestArray = reader.GetArray(); + TestEnum = reader.GetEnum(); } public override bool Equals(object obj) { var other = (SampleClass)obj; return other.Value == Value && (TestArray is null && other.TestArray is null || TestArray != null && - other.TestArray != null && TestArray.SequenceEqual(other.TestArray)); + other.TestArray != null && TestArray.SequenceEqual(other.TestArray)) && other.TestEnum == TestEnum; } public override int GetHashCode() @@ -157,12 +188,15 @@ private class SamplePacket public Guid SomeGuid { get; set; } public SomeVector2 SomeVector2 { get; set; } public SomeVector2[] SomeVectors { get; set; } + public SomeFastVector3 SomeFastVector3 { get; set; } + public SomeFastVector3[] SomeFastVectors { get; set; } public TestEnum SomeEnum { get; set; } public SampleNetSerializable TestObj { get; set; } public SampleNetSerializable[] TestArray { get; set; } public SampleClass[] SampleClassArray { get; set; } public List SampleClassList { get; set; } public List VectorList { get; set; } + public List FastVectorList { get; set; } [IgnoreDataMember] public int IgnoreMe { get; set; } } @@ -210,6 +244,8 @@ public void CustomPackageTest() Assert.That(readPackage.SomeGuid, Is.EqualTo(_samplePacket.SomeGuid)); Assert.That(readPackage.SomeVector2, Is.EqualTo(_samplePacket.SomeVector2)); Assert.That(readPackage.SomeVectors, Is.EqualTo(_samplePacket.SomeVectors).AsCollection); + Assert.That(readPackage.SomeFastVector3, Is.EqualTo(_samplePacket.SomeFastVector3)); + Assert.That(readPackage.SomeFastVectors, Is.EqualTo(_samplePacket.SomeFastVectors).AsCollection); Assert.That(readPackage.SomeEnum, Is.EqualTo(_samplePacket.SomeEnum)); Assert.That(readPackage.TestObj.Value, Is.EqualTo(_samplePacket.TestObj.Value)); Assert.That(readPackage.TestArray, Is.EqualTo(_samplePacket.TestArray).AsCollection); @@ -218,11 +254,13 @@ public void CustomPackageTest() Assert.That(readPackage.IgnoreMe, Is.EqualTo(0)); // expect 0 because it should be ignored Assert.That(readPackage.SampleClassList, Is.EqualTo(_samplePacket.SampleClassList).AsCollection); Assert.That(readPackage.VectorList, Is.EqualTo(_samplePacket.VectorList).AsCollection); + Assert.That(readPackage.FastVectorList, Is.EqualTo(_samplePacket.FastVectorList).AsCollection); //remove test _samplePacket.SampleClassList.RemoveAt(0); _samplePacket.SampleClassArray = new []{new SampleClass {Value = 1}}; _samplePacket.VectorList.RemoveAt(0); + _samplePacket.FastVectorList.RemoveAt(0); writer.Reset(); _packetProcessor.Write(writer, _samplePacket); @@ -237,6 +275,7 @@ public void CustomPackageTest() _samplePacket.SampleClassList.Add(new SampleClass { Value = 154 }); _samplePacket.SampleClassArray = new[] { new SampleClass { Value = 1 }, new SampleClass { Value = 2 }, new SampleClass { Value = 3 } }; _samplePacket.VectorList.Add(new SomeVector2(500,600)); + _samplePacket.FastVectorList.Add(new SomeFastVector3(500.0f, 600.0f, 700.0f)); writer.Reset(); _packetProcessor.Write(writer, _samplePacket); From d0f2d6efd4715f110844c0cff55d0122e6424c39 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:48:01 +0100 Subject: [PATCH 178/261] Add docs for manualMode --- LiteNetLib/LiteNetManager.Socket.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/LiteNetLib/LiteNetManager.Socket.cs b/LiteNetLib/LiteNetManager.Socket.cs index b7dd5776..f77c015d 100644 --- a/LiteNetLib/LiteNetManager.Socket.cs +++ b/LiteNetLib/LiteNetManager.Socket.cs @@ -325,7 +325,12 @@ private void ReceiveLogic() /// bind to specific ipv4 address /// bind to specific ipv6 address /// port to listen - /// mode of library + /// + /// When , disables internal background threads.
+ /// You must manually call and .

+ /// Recommended for single-threaded environments like Unity or for + /// reducing multi-threading overhead and synchronization issues. + /// public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode) { if (IsRunning && NotConnected == false) From 352576ba8b041f80136627bba5a9c34876831f7a Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:54:21 +0100 Subject: [PATCH 179/261] Add docs for reject --- LiteNetLib/ConnectionRequest.cs | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 099e08ee..527166a8 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -80,6 +80,16 @@ public LiteNetPeer Accept() return _listener.OnConnectionSolved(this, null, 0, 0); } + /// + /// Rejects the connection request. + /// + /// Optional user data to send along with the rejection packet. + /// Offset in the array. + /// Length of the data to be sent from the array. + /// + /// If , performs a "fire-and-forget" rejection without creating an internal peer. + /// If , creates a temporary peer to ensure the rejection is delivered reliably. + /// public void Reject(byte[] rejectData, int start, int length, bool force) { if (!TryActivate()) @@ -88,27 +98,62 @@ public void Reject(byte[] rejectData, int start, int length, bool force) _listener.OnConnectionSolved(this, rejectData, start, length); } + /// + /// Rejects the connection reliably. Creates a temporary peer to handle packet loss. + /// + /// Data to send with the rejection. + /// Offset in the array. + /// Length of the data to be sent. public void Reject(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, false); + /// + /// Rejects the connection immediately without reliability. + /// Minimizes resource usage by not creating an internal peer. + /// + /// Data to send with the rejection. + /// Offset in the array. + /// Length of the data to be sent. public void RejectForce(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, true); + /// + /// Rejects the connection immediately without reliability and without additional data. + /// public void RejectForce() => Reject(null, 0, 0, true); + /// + /// Rejects the connection immediately without reliability. + /// + /// Data to send with the rejection. public void RejectForce(byte[] rejectData) => Reject(rejectData, 0, rejectData.Length, true); + /// + /// Rejects the connection immediately without reliability using data from a . + /// + /// Writer containing the data to send. public void RejectForce(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, true); + /// + /// Rejects the connection reliably without additional data. + /// public void Reject() => Reject(null, 0, 0, false); + /// + /// Rejects the connection reliably. + /// + /// Data to send with the rejection. public void Reject(byte[] rejectData) => Reject(rejectData, 0, rejectData.Length, false); + /// + /// Rejects the connection reliably using data from a . + /// + /// Writer containing the data to send. public void Reject(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, false); } From 3f4cd4aa59a2eac37364bfae0941c74859476784 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:54:21 +0100 Subject: [PATCH 180/261] Add docs for reject --- LiteNetLib/ConnectionRequest.cs | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 099e08ee..527166a8 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -80,6 +80,16 @@ public LiteNetPeer Accept() return _listener.OnConnectionSolved(this, null, 0, 0); } + /// + /// Rejects the connection request. + /// + /// Optional user data to send along with the rejection packet. + /// Offset in the array. + /// Length of the data to be sent from the array. + /// + /// If , performs a "fire-and-forget" rejection without creating an internal peer. + /// If , creates a temporary peer to ensure the rejection is delivered reliably. + /// public void Reject(byte[] rejectData, int start, int length, bool force) { if (!TryActivate()) @@ -88,27 +98,62 @@ public void Reject(byte[] rejectData, int start, int length, bool force) _listener.OnConnectionSolved(this, rejectData, start, length); } + /// + /// Rejects the connection reliably. Creates a temporary peer to handle packet loss. + /// + /// Data to send with the rejection. + /// Offset in the array. + /// Length of the data to be sent. public void Reject(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, false); + /// + /// Rejects the connection immediately without reliability. + /// Minimizes resource usage by not creating an internal peer. + /// + /// Data to send with the rejection. + /// Offset in the array. + /// Length of the data to be sent. public void RejectForce(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, true); + /// + /// Rejects the connection immediately without reliability and without additional data. + /// public void RejectForce() => Reject(null, 0, 0, true); + /// + /// Rejects the connection immediately without reliability. + /// + /// Data to send with the rejection. public void RejectForce(byte[] rejectData) => Reject(rejectData, 0, rejectData.Length, true); + /// + /// Rejects the connection immediately without reliability using data from a . + /// + /// Writer containing the data to send. public void RejectForce(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, true); + /// + /// Rejects the connection reliably without additional data. + /// public void Reject() => Reject(null, 0, 0, false); + /// + /// Rejects the connection reliably. + /// + /// Data to send with the rejection. public void Reject(byte[] rejectData) => Reject(rejectData, 0, rejectData.Length, false); + /// + /// Rejects the connection reliably using data from a . + /// + /// Writer containing the data to send. public void Reject(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, false); } From 62d186d8ea921dedcea0c1255c0a9ec374a3014f Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:48:01 +0100 Subject: [PATCH 181/261] Add docs for manualMode --- LiteNetLib/LiteNetManager.Socket.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/LiteNetLib/LiteNetManager.Socket.cs b/LiteNetLib/LiteNetManager.Socket.cs index b7dd5776..f77c015d 100644 --- a/LiteNetLib/LiteNetManager.Socket.cs +++ b/LiteNetLib/LiteNetManager.Socket.cs @@ -325,7 +325,12 @@ private void ReceiveLogic() /// bind to specific ipv4 address /// bind to specific ipv6 address /// port to listen - /// mode of library + /// + /// When , disables internal background threads.
+ /// You must manually call and .

+ /// Recommended for single-threaded environments like Unity or for + /// reducing multi-threading overhead and synchronization issues. + /// public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode) { if (IsRunning && NotConnected == false) From 64cb08f4ce31f608cffd94e9812f47a9456f9fcd Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:57:22 +0100 Subject: [PATCH 182/261] Revert "Add docs for manualMode" This reverts commit d0f2d6efd4715f110844c0cff55d0122e6424c39. --- LiteNetLib/LiteNetManager.Socket.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/LiteNetLib/LiteNetManager.Socket.cs b/LiteNetLib/LiteNetManager.Socket.cs index f77c015d..b7dd5776 100644 --- a/LiteNetLib/LiteNetManager.Socket.cs +++ b/LiteNetLib/LiteNetManager.Socket.cs @@ -325,12 +325,7 @@ private void ReceiveLogic() /// bind to specific ipv4 address /// bind to specific ipv6 address /// port to listen - /// - /// When , disables internal background threads.
- /// You must manually call and .

- /// Recommended for single-threaded environments like Unity or for - /// reducing multi-threading overhead and synchronization issues. - /// + /// mode of library public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode) { if (IsRunning && NotConnected == false) From 3e758a791d4f9c00ac280f8381ba59d59c9ded74 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:57:28 +0100 Subject: [PATCH 183/261] Revert "Add docs for reject" This reverts commit 352576ba8b041f80136627bba5a9c34876831f7a. --- LiteNetLib/ConnectionRequest.cs | 45 --------------------------------- 1 file changed, 45 deletions(-) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 527166a8..099e08ee 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -80,16 +80,6 @@ public LiteNetPeer Accept() return _listener.OnConnectionSolved(this, null, 0, 0); } - /// - /// Rejects the connection request. - /// - /// Optional user data to send along with the rejection packet. - /// Offset in the array. - /// Length of the data to be sent from the array. - /// - /// If , performs a "fire-and-forget" rejection without creating an internal peer. - /// If , creates a temporary peer to ensure the rejection is delivered reliably. - /// public void Reject(byte[] rejectData, int start, int length, bool force) { if (!TryActivate()) @@ -98,62 +88,27 @@ public void Reject(byte[] rejectData, int start, int length, bool force) _listener.OnConnectionSolved(this, rejectData, start, length); } - /// - /// Rejects the connection reliably. Creates a temporary peer to handle packet loss. - /// - /// Data to send with the rejection. - /// Offset in the array. - /// Length of the data to be sent. public void Reject(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, false); - /// - /// Rejects the connection immediately without reliability. - /// Minimizes resource usage by not creating an internal peer. - /// - /// Data to send with the rejection. - /// Offset in the array. - /// Length of the data to be sent. public void RejectForce(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, true); - /// - /// Rejects the connection immediately without reliability and without additional data. - /// public void RejectForce() => Reject(null, 0, 0, true); - /// - /// Rejects the connection immediately without reliability. - /// - /// Data to send with the rejection. public void RejectForce(byte[] rejectData) => Reject(rejectData, 0, rejectData.Length, true); - /// - /// Rejects the connection immediately without reliability using data from a . - /// - /// Writer containing the data to send. public void RejectForce(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, true); - /// - /// Rejects the connection reliably without additional data. - /// public void Reject() => Reject(null, 0, 0, false); - /// - /// Rejects the connection reliably. - /// - /// Data to send with the rejection. public void Reject(byte[] rejectData) => Reject(rejectData, 0, rejectData.Length, false); - /// - /// Rejects the connection reliably using data from a . - /// - /// Writer containing the data to send. public void Reject(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, false); } From daece50b4f7e92595dcc0c59dbb43e3fb1f45be1 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 23:06:09 +0100 Subject: [PATCH 184/261] Update disconnect docs --- LiteNetLib/LiteNetManager.cs | 15 +++++++++++++++ LiteNetLib/LiteNetPeer.cs | 11 +++++++++++ 2 files changed, 26 insertions(+) diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index 572fd105..dfac720a 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -301,6 +301,21 @@ internal void DisconnectPeerForce(LiteNetPeer peer, NetPacket eventData) => DisconnectPeer(peer, reason, socketErrorCode, true, null, 0, 0, eventData); + /// + /// Disconnects a peer and handles internal state cleanup. + /// + /// The peer to disconnect. + /// The reason for disconnection provided to the event listener. + /// The error code from the underlying socket, if any. + /// + /// If , immediately sets state to Disconnected without sending a notification. + /// If , sends a single unreliable disconnect packet and sets state to ShutdownRequested.
+ /// Queued reliable packets are not guaranteed to be delivered before the state change. + /// + /// Optional custom data to include in the disconnect packet. + /// Offset in the array. + /// Number of bytes to send from the array. + /// Internal packet data associated with the disconnect event. private void DisconnectPeer( LiteNetPeer peer, DisconnectReason reason, diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 7c1d86bb..4109f6bb 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -698,6 +698,17 @@ internal virtual void AddToReliableChannelSendQueue(BaseChannel channel) } + /// + /// Internally handles the shutdown process for this peer. + /// + /// Optional data to include in the disconnect packet. + /// Offset in the array. + /// Length of the data to send. + /// + /// If , immediately sets state to Disconnected without sending a notification. + /// If , sends a single unreliable disconnect packet and sets state to ShutdownRequested. + /// + /// A indicating the state change transition. internal ShutdownResult Shutdown(byte[] data, int start, int length, bool force) { lock (_shutdownLock) From 4ca89a7d21cfe8b98633f1a75958078934e37ed9 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 20 Mar 2026 22:54:21 +0100 Subject: [PATCH 185/261] Update docs --- LiteNetLib/ConnectionRequest.cs | 45 +++++++++++++++++++++++++++++ LiteNetLib/LiteNetManager.Socket.cs | 7 ++++- LiteNetLib/LiteNetManager.cs | 28 +++++++++++++++--- LiteNetLib/LiteNetPeer.cs | 21 ++++++++++++++ 4 files changed, 96 insertions(+), 5 deletions(-) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 099e08ee..32b965eb 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -80,6 +80,16 @@ public LiteNetPeer Accept() return _listener.OnConnectionSolved(this, null, 0, 0); } + /// + /// Rejects the connection request. + /// + /// Optional user data to send along with the rejection packet. + /// Offset in the array. + /// Length of the data to be sent from the array. + /// + /// If , sends a single raw packet and immediately removes the request.
+ /// If , creates a temporary peer that sends a single rejection packet and lingers in memory until a timeout occurs to handle late-arriving packets. + /// public void Reject(byte[] rejectData, int start, int length, bool force) { if (!TryActivate()) @@ -88,27 +98,62 @@ public void Reject(byte[] rejectData, int start, int length, bool force) _listener.OnConnectionSolved(this, rejectData, start, length); } + /// + /// Rejects the connection reliably. Creates a temporary peer to handle packet loss. + /// + /// Data to send with the rejection. + /// Offset in the array. + /// Length of the data to be sent. public void Reject(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, false); + /// + /// Rejects the connection immediately without reliability. + /// Minimizes resource usage by not creating an internal peer. + /// + /// Data to send with the rejection. + /// Offset in the array. + /// Length of the data to be sent. public void RejectForce(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, true); + /// + /// Rejects the connection immediately without reliability and without additional data. + /// public void RejectForce() => Reject(null, 0, 0, true); + /// + /// Rejects the connection immediately without reliability. + /// + /// Data to send with the rejection. public void RejectForce(byte[] rejectData) => Reject(rejectData, 0, rejectData.Length, true); + /// + /// Rejects the connection immediately without reliability using data from a . + /// + /// Writer containing the data to send. public void RejectForce(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, true); + /// + /// Rejects the connection reliably without additional data. + /// public void Reject() => Reject(null, 0, 0, false); + /// + /// Rejects the connection reliably. + /// + /// Data to send with the rejection. public void Reject(byte[] rejectData) => Reject(rejectData, 0, rejectData.Length, false); + /// + /// Rejects the connection reliably using data from a . + /// + /// Writer containing the data to send. public void Reject(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, false); } diff --git a/LiteNetLib/LiteNetManager.Socket.cs b/LiteNetLib/LiteNetManager.Socket.cs index b7dd5776..f77c015d 100644 --- a/LiteNetLib/LiteNetManager.Socket.cs +++ b/LiteNetLib/LiteNetManager.Socket.cs @@ -325,7 +325,12 @@ private void ReceiveLogic() /// bind to specific ipv4 address /// bind to specific ipv6 address /// port to listen - /// mode of library + /// + /// When , disables internal background threads.
+ /// You must manually call and .

+ /// Recommended for single-threaded environments like Unity or for + /// reducing multi-threading overhead and synchronization issues. + /// public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode) { if (IsRunning && NotConnected == false) diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index 572fd105..e7b0102f 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -301,6 +301,21 @@ internal void DisconnectPeerForce(LiteNetPeer peer, NetPacket eventData) => DisconnectPeer(peer, reason, socketErrorCode, true, null, 0, 0, eventData); + /// + /// Disconnects a peer and handles internal state cleanup. + /// + /// The peer to disconnect. + /// The reason for disconnection provided to the event listener. + /// The error code from the underlying socket, if any. + /// + /// If , immediately sets state to without sending a notification.
+ /// If , sends a single unreliable disconnect packet and sets state to . + /// Peer will linger until to ignore late-arriving packets from the old session. + /// + /// Optional custom data to include in the disconnect packet. + /// Offset in the array. + /// Number of bytes to send from the array. + /// Internal packet data associated with the disconnect event. private void DisconnectPeer( LiteNetPeer peer, DisconnectReason reason, @@ -562,9 +577,12 @@ private void ProcessDelayedPackets() /// - /// Update and send logic. Use this only when NetManager started in manual mode + /// Updates internal peer states, handles timeouts, and processes NTP requests. /// - /// elapsed milliseconds since last update call + /// Time passed since the last update frame. + /// + /// Must be called continuously from the main loop if was set to . + /// public void ManualUpdate(float elapsedMilliseconds) { if (!_manualMode) @@ -1278,9 +1296,11 @@ public void TriggerUpdate() => _updateTriggerEvent.Set(); /// - /// Receive" pending events. Call this in game update code - /// In Manual mode it will call also socket Receive (which can be slow) + /// Reads data from the UDP sockets and processes pending events immediately. /// + /// + /// Must be called continuously from the main loop if was set to . + /// public void PollEvents() { if (_manualMode) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 7c1d86bb..dacce2c6 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -698,6 +698,18 @@ internal virtual void AddToReliableChannelSendQueue(BaseChannel channel) } + /// + /// Internally handles the shutdown process for this peer. + /// + /// Optional data to include in the unreliable disconnect packet. + /// Offset in the array. + /// Length of the data to send. + /// + /// If , immediately sets state to without sending a notification.
+ /// If , sends a single unreliable disconnect packet and sets state to + /// Queued reliable packets are bypassed and dropped immediately. + /// + /// A indicating the state change transition. internal ShutdownResult Shutdown(byte[] data, int start, int length, bool force) { lock (_shutdownLock) @@ -929,6 +941,15 @@ private void UpdateMtuLogic(float deltaTime) } } + /// + /// Evaluates incoming connection requests against the current peer state to supply Reconnect Protection. + /// + /// The incoming connection request packet. + /// A directing how the manager should handle the request. + /// + /// If the state is , the peer lingers to ignore older connection requests + /// (where the packet timestamp is smaller than internal ), ensuring delayed or stale packets are dropped. + /// internal ConnectRequestResult ProcessConnectRequest(NetConnectRequestPacket connRequest) { //current or new request From 9d5d42f11ea8361a0212891cca23c14a24718252 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Sat, 21 Mar 2026 00:04:04 +0100 Subject: [PATCH 186/261] Refine docs --- LiteNetLib/Utils/NetDataReader.cs | 242 +++++++++++++++--------------- LiteNetLib/Utils/NetDataWriter.cs | 81 +++++----- 2 files changed, 166 insertions(+), 157 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 3271c064..30597f01 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -14,7 +14,7 @@ public unsafe class NetDataReader protected int _offset; /// - /// Gets the internal array containing the raw network data. + /// Gets the internal array containing the raw network data. /// public byte[] RawData { @@ -77,7 +77,7 @@ public bool EndOfData } /// - /// Gets the number of s remaining to be read. + /// Gets the number of s remaining to be read. /// public int AvailableBytes { @@ -86,9 +86,9 @@ public int AvailableBytes } /// - /// Verifies that the buffer has at least s available to read. + /// Verifies that the buffer has at least s available to read. /// - /// The number of s required. + /// The number of s required. /// Thrown if exceeds or is negative. [MethodImpl(MethodImplOptions.AggressiveInlining)] private void EnsureAvailable(int count) @@ -101,7 +101,7 @@ private void EnsureAvailable(int count) /// /// Advances the by the specified . /// - /// The number of s to skip. + /// The number of s to skip. public void SkipBytes(int count) => _position += count; /// @@ -123,9 +123,9 @@ public void SetSource(NetDataWriter dataWriter) } /// - /// Reinitializes the reader using a array. + /// Reinitializes the reader using a array. /// - /// The source array. + /// The source array. public void SetSource(byte[] source) { _data = source; @@ -135,11 +135,11 @@ public void SetSource(byte[] source) } /// - /// Reinitializes the reader using a segment of a array. + /// Reinitializes the reader using a segment of a array. /// - /// The source array. + /// The source array. /// The starting index for reading. - /// The total number of s available to read from the . + /// The total number of s available to read from the . public void SetSource(byte[] source, int offset, int maxSize) { _data = source; @@ -192,8 +192,8 @@ public void Get(out T result, Func constructor) where T : class, INetSeria /// /// The deserialized . /// - /// Reads a to determine the (0 for IPv4, 1 for IPv6), - /// followed by the address bytes and a 2-byte port. + /// Reads a to determine the (0 for IPv4, 1 for IPv6), + /// followed by the address bytes and a 2-byte port. /// public IPEndPoint GetIPEndPoint() { @@ -215,59 +215,59 @@ public IPEndPoint GetIPEndPoint() return new IPEndPoint(address, GetUShort()); } - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out byte result) => result = GetByte(); - /// Reads an and assigns it to . + /// Reads an and assigns it to . public void Get(out sbyte result) => result = (sbyte)GetByte(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out bool result) => result = GetBool(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out char result) => result = GetChar(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out ushort result) => result = GetUShort(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out short result) => result = GetShort(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out ulong result) => result = GetULong(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out long result) => result = GetLong(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out uint result) => result = GetUInt(); - /// Reads an and assigns it to . + /// Reads an and assigns it to . public void Get(out int result) => result = GetInt(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out double result) => result = GetDouble(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out float result) => result = GetFloat(); - /// Reads a and assigns it to . + /// Reads a and assigns it to . public void Get(out string result) => result = GetString(); - /// Reads a with a length limit and assigns it to . + /// Reads a with a length limit and assigns it to . public void Get(out string result, int maxLength) => result = GetString(maxLength); /// Reads a and assigns it to . public void Get(out Guid result) => result = GetGuid(); - /// Reads the next from the buffer. + /// Reads the next from the buffer. public byte GetByte() => _data[_position++]; - /// Reads the next from the buffer. + /// Reads the next from the buffer. public sbyte GetSByte() => (sbyte)GetByte(); /// - /// Reads an array of unmanaged values prefixed by a length. + /// Reads an array of unmanaged values prefixed by a length. /// /// An unmanaged type. /// A new array of type . @@ -286,7 +286,7 @@ public T[] GetUnmanagedArray() where T : unmanaged /// Reads an array of values by performing a direct memory copy. /// /// The element type. - /// The size of a single element in s. + /// The size of a single element in s. /// A new array of type . public T[] GetArray(ushort size) { @@ -336,39 +336,39 @@ public T[] GetArray(Func constructor) where T : class, INetSerializable return result; } - /// Reads an array of values. + /// Reads an array of values. public bool[] GetBoolArray() => GetUnmanagedArray(); - /// Reads an array of values. + /// Reads an array of values. public ushort[] GetUShortArray() => GetUnmanagedArray(); - /// Reads an array of values. + /// Reads an array of values. public short[] GetShortArray() => GetUnmanagedArray(); - /// Reads an array of values. + /// Reads an array of values. public int[] GetIntArray() => GetUnmanagedArray(); - /// Reads an array of values. + /// Reads an array of values. public uint[] GetUIntArray() => GetUnmanagedArray(); - /// Reads an array of values. + /// Reads an array of values. public float[] GetFloatArray() => GetUnmanagedArray(); - /// Reads an array of values. + /// Reads an array of values. public double[] GetDoubleArray() => GetUnmanagedArray(); - /// Reads an array of values. + /// Reads an array of values. public long[] GetLongArray() => GetUnmanagedArray(); - /// Reads an array of values. + /// Reads an array of values. public ulong[] GetULongArray() => GetUnmanagedArray(); /// - /// Reads an array of values. + /// Reads an array of values. /// - /// A new array. + /// A new array. /// - /// Reads a 2-byte length header followed by each element. + /// Reads a 2-byte length header followed by each element. /// public string[] GetStringArray() { @@ -382,10 +382,10 @@ public string[] GetStringArray() } /// - /// Reads an array of values with a maximum character limit per element. + /// Reads an array of values with a maximum character limit per element. /// - /// The maximum number of characters allowed per . - /// A new array. + /// The maximum number of characters allowed per . + /// A new array. /// /// Strings exceeding are returned as . /// @@ -400,44 +400,44 @@ public string[] GetStringArray(int maxStringLength) return arr; } - /// Reads a value from the current position. + /// Reads a value from the current position. /// if the byte is 1; otherwise, . public bool GetBool() => GetByte() == 1; - /// Reads a value as a 2-byte . + /// Reads a value as a 2-byte . public char GetChar() => (char)GetUShort(); - /// Reads a value using unmanaged memory access. + /// Reads a value using unmanaged memory access. public ushort GetUShort() => GetUnmanaged(); - /// Reads a value using unmanaged memory access. + /// Reads a value using unmanaged memory access. public short GetShort() => GetUnmanaged(); - /// Reads a value using unmanaged memory access. + /// Reads a value using unmanaged memory access. public long GetLong() => GetUnmanaged(); - /// Reads a value using unmanaged memory access. + /// Reads a value using unmanaged memory access. public ulong GetULong() => GetUnmanaged(); - /// Reads an value using unmanaged memory access. + /// Reads an value using unmanaged memory access. public int GetInt() => GetUnmanaged(); - /// Reads a value using unmanaged memory access. + /// Reads a value using unmanaged memory access. public uint GetUInt() => GetUnmanaged(); - /// Reads a value using unmanaged memory access. + /// Reads a value using unmanaged memory access. public float GetFloat() => GetUnmanaged(); - /// Reads a value using unmanaged memory access. + /// Reads a value using unmanaged memory access. public double GetDouble() => GetUnmanaged(); /// - /// Reads a with a maximum character limit. + /// Reads a with a maximum character limit. /// /// The maximum allowed character count. - /// The deserialized , or if the character count exceeds . + /// The deserialized , or if the character count exceeds . /// - /// Note that limits the number of characters, not the total size in s. + /// Note that limits the number of characters, not the total size in s. /// public string GetString(int maxLength) { @@ -458,9 +458,9 @@ public string GetString(int maxLength) } /// - /// Reads a from the current position. + /// Reads a from the current position. /// - /// The deserialized . + /// The deserialized . public string GetString() { ushort size = GetUShort(); @@ -476,9 +476,9 @@ public string GetString() } /// - /// Reads a prefixed with a 4-byte length header. + /// Reads a prefixed with a 4-byte length header. /// - /// The deserialized . + /// The deserialized . public string GetLargeString() { int size = GetInt(); @@ -505,9 +505,9 @@ public Guid GetGuid() } /// - /// Gets an of s from the current position. + /// Gets an of s from the current position. /// - /// The number of s to include in the segment. + /// The number of s to include in the segment. /// An wrapping the internal buffer. public ArraySegment GetBytesSegment(int count) { @@ -518,7 +518,7 @@ public ArraySegment GetBytesSegment(int count) } /// - /// Gets an containing all remaining s. + /// Gets an containing all remaining s. /// /// An from the current position to the end of the data. public ArraySegment GetRemainingBytesSegment() @@ -554,7 +554,7 @@ public T Get(Func constructor) where T : class, INetSerializable } /// - /// Returns a of s containing all remaining data. + /// Returns a of s containing all remaining data. /// /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -562,7 +562,7 @@ public ReadOnlySpan GetRemainingBytesSpan() => new ReadOnlySpan(_data, _position, _dataSize - _position); /// - /// Returns a of s containing all remaining data. + /// Returns a of s containing all remaining data. /// /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -570,9 +570,9 @@ public ReadOnlyMemory GetRemainingBytesMemory() => new ReadOnlyMemory(_data, _position, _dataSize - _position); /// - /// Reads all remaining s and returns them as a new array. + /// Reads all remaining s and returns them as a new array. /// - /// A new array containing the remaining data. + /// A new array containing the remaining data. /// /// This method performs a heap allocation and advances the to the end of the data. /// @@ -585,11 +585,11 @@ public byte[] GetRemainingBytes() } /// - /// Copies a specified number of s into a destination array at a specific offset. + /// Copies a specified number of s into a destination array at a specific offset. /// /// The array to copy data into. /// The starting index in the array. - /// The number of s to read. + /// The number of s to read. public void GetBytes(byte[] destination, int start, int count) { EnsureAvailable(count); @@ -598,10 +598,10 @@ public void GetBytes(byte[] destination, int start, int count) } /// - /// Copies a specified number of s into a destination array starting at index 0. + /// Copies a specified number of s into a destination array starting at index 0. /// /// The array to copy data into. - /// The number of s to read. + /// The number of s to read. public void GetBytes(byte[] destination, int count) { EnsureAvailable(count); @@ -610,15 +610,15 @@ public void GetBytes(byte[] destination, int count) } /// - /// Reads an array prefixed with its length. + /// Reads an array prefixed with its length. /// - /// A new array. + /// A new array. public sbyte[] GetSBytesWithLength() => GetUnmanagedArray(); /// - /// Reads a array prefixed with its length. + /// Reads a array prefixed with its length. /// - /// A new array. + /// A new array. public byte[] GetBytesWithLength() => GetUnmanagedArray(); /// @@ -702,44 +702,44 @@ public ReadOnlySpan GetSpan(int length) #region PeekMethods - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public byte PeekByte() => _data[_position]; - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public sbyte PeekSByte() => (sbyte)_data[_position]; - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public bool PeekBool() => _data[_position] == 1; - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public char PeekChar() => PeekUnmanaged(); - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public ushort PeekUShort() => PeekUnmanaged(); - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public short PeekShort() => PeekUnmanaged(); - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public long PeekLong() => PeekUnmanaged(); - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public ulong PeekULong() => PeekUnmanaged(); - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public int PeekInt() => PeekUnmanaged(); - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public uint PeekUInt() => PeekUnmanaged(); - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public float PeekFloat() => PeekUnmanaged(); - /// Reads the at the current position without advancing the . + /// Reads the at the current position without advancing the . public double PeekDouble() => PeekUnmanaged(); /// - /// Reads a with a character limit without advancing the . + /// Reads a with a character limit without advancing the . /// /// Maximum allowed character count. /// Strings exceeding are returned as . @@ -756,7 +756,7 @@ public string PeekString(int maxLength) } /// - /// Reads a without advancing the . + /// Reads a without advancing the . /// public string PeekString() { @@ -790,8 +790,8 @@ public T PeekUnmanaged() where T : unmanaged #endregion #region TryGetMethods - /// Attempts to read a without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetByte(out byte result) { @@ -804,8 +804,8 @@ public bool TryGetByte(out byte result) return false; } - /// Attempts to read an without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read an without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetSByte(out sbyte result) { @@ -818,8 +818,8 @@ public bool TryGetSByte(out sbyte result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or if failed. /// if enough data was available; otherwise, . public bool TryGetBool(out bool result) { @@ -832,8 +832,8 @@ public bool TryGetBool(out bool result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or '\0' if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or '\0' if failed. /// if enough data was available; otherwise, . public bool TryGetChar(out char result) { @@ -846,8 +846,8 @@ public bool TryGetChar(out char result) return true; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetShort(out short result) { @@ -860,8 +860,8 @@ public bool TryGetShort(out short result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetUShort(out ushort result) { @@ -874,8 +874,8 @@ public bool TryGetUShort(out ushort result) return false; } - /// Attempts to read an without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read an without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetInt(out int result) { @@ -888,8 +888,8 @@ public bool TryGetInt(out int result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetUInt(out uint result) { @@ -902,8 +902,8 @@ public bool TryGetUInt(out uint result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetLong(out long result) { @@ -916,8 +916,8 @@ public bool TryGetLong(out long result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetULong(out ulong result) { @@ -930,8 +930,8 @@ public bool TryGetULong(out ulong result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetFloat(out float result) { @@ -944,8 +944,8 @@ public bool TryGetFloat(out float result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or 0 if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . public bool TryGetDouble(out double result) { @@ -958,8 +958,8 @@ public bool TryGetDouble(out double result) return false; } - /// Attempts to read a without throwing an exception. - /// The deserialized , or if failed. + /// Attempts to read a without throwing an exception. + /// The deserialized , or if failed. /// if enough data was available; otherwise, . public bool TryGetString(out string result) { @@ -978,8 +978,8 @@ public bool TryGetString(out string result) return false; } - /// Attempts to read a array without throwing an exception. - /// The deserialized array, or if failed. + /// Attempts to read a array without throwing an exception. + /// The deserialized array, or if failed. /// if enough data was available; otherwise, . public bool TryGetStringArray(out string[] result) { @@ -1002,8 +1002,8 @@ public bool TryGetStringArray(out string[] result) return true; } - /// Attempts to read a array with a length header without throwing an exception. - /// The deserialized array, or if failed. + /// Attempts to read a array with a length header without throwing an exception. + /// The deserialized array, or if failed. /// if enough data was available; otherwise, . public bool TryGetBytesWithLength(out byte[] result) { diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 0849c0a3..9420c969 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -15,7 +15,7 @@ public unsafe class NetDataWriter private readonly bool _autoResize; /// - /// Gets the total capacity of the internal buffer. + /// Gets the total capacity of the internal buffer. /// /// The length of the underlying array. public int Capacity @@ -25,7 +25,7 @@ public int Capacity } /// - /// Gets the underlying array used by this writer. + /// Gets the underlying array used by this writer. /// /// The internal array. /// @@ -38,7 +38,7 @@ public byte[] Data } /// - /// Gets the current number of s written to the buffer. + /// Gets the current number of s written to the buffer. /// /// The current . public int Length @@ -109,10 +109,10 @@ public static NetDataWriter FromBytes(Span bytes) } /// - /// Creates a new and serializes a into it. + /// Creates a new and serializes a into it. /// - /// The to serialize. - /// A new instance containing the serialized . + /// The to serialize. + /// A new instance containing the serialized . public static NetDataWriter FromString(string value) { var netDataWriter = new NetDataWriter(); @@ -138,9 +138,9 @@ public void ResizeIfNeed(int newSize) } /// - /// Ensures the internal buffer can accommodate more s. + /// Ensures the internal buffer can accommodate more s. /// - /// The number of additional s to fit. + /// The number of additional s to fit. /// /// This checks against the current . If the capacity is insufficient, /// the buffer grows to either the required size or doubles its current size. @@ -160,7 +160,7 @@ public void EnsureFit(int additionalSize) /// /// The minimum capacity required for the internal buffer. /// - /// If the current buffer is smaller than , will allocate a larger array. + /// If the current buffer is smaller than , will allocate a larger array. /// public void Reset(int size) { @@ -174,9 +174,9 @@ public void Reset(int size) public void Reset() => _position = 0; /// - /// Creates a array containing the current data from the internal buffer. + /// Creates a array containing the current data from the internal buffer. /// - /// A new array of length . + /// A new array of length . /// /// This method performs a heap allocation and copies the data using . /// @@ -278,18 +278,18 @@ public void Put(Guid value) } /// - /// Serializes a segment of a array. + /// Serializes a segment of a array. /// /// The source array. /// The starting index in the source array. - /// The number of s to write. + /// The number of s to write. public void Put(byte[] data, int offset, int length) { Put(data.AsSpan(offset, length)); } /// - /// Serializes an entire array. + /// Serializes an entire array. /// /// The source array. public void Put(byte[] data) @@ -310,9 +310,9 @@ public void Put(ReadOnlySpan data) } /// - /// Serializes a segment of an array prefixed with its length. + /// Serializes a segment of an array prefixed with its length. /// - /// The source array. + /// The source array. /// The starting index in the source array. /// The number of elements to write. public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) @@ -343,17 +343,17 @@ public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) } /// - /// Serializes an array prefixed with its length. + /// Serializes an array prefixed with its length. /// /// The source array. public void PutSBytesWithLength(sbyte[] data) => PutArray(data, 1); /// - /// Serializes a segment of a array prefixed with its length. + /// Serializes a segment of a array prefixed with its length. /// - /// The source array. + /// The source array. /// The starting index in the source array. - /// The number of s to write. + /// The number of s to write. public void PutBytesWithLength(byte[] data, int offset, ushort length) { if (_autoResize) @@ -379,22 +379,22 @@ public void PutBytesWithLength(byte[] data, int offset, ushort length) } /// - /// Serializes a array prefixed with its length. + /// Serializes a array prefixed with its length. /// /// The source array. public void PutBytesWithLength(byte[] data) => PutArray(data, 1); /// - /// Serializes a value as a single . + /// Serializes a value as a single . /// - /// The value to write. + /// The value to write. public void Put(bool value) => Put((byte)(value ? 1 : 0)); /// - /// Serializes an prefixed with a 2-byte length. + /// Serializes an prefixed with a 2-byte length. /// /// The source array to serialize. - /// The size of a single element in s. + /// The size of a single element in s. /// /// If the array is , a length of 0 is written.
/// The total payload size is calculated as length * sz. @@ -488,11 +488,11 @@ public void PutSpan(Span span) where T : unmanaged public void PutArray(bool[] value) => PutUnmanagedArray(value); /// - /// Serializes an array of values. + /// Serializes an array of values. /// - /// The array of elements to write. + /// The array of elements to write. /// - /// Writes a 2-byte length header followed by each element. + /// Writes a 2-byte length header followed by each element. /// public void PutArray(string[] value) { @@ -503,10 +503,10 @@ public void PutArray(string[] value) } /// - /// Serializes an array of values with a maximum length constraint per element. + /// Serializes an array of values with a maximum length constraint per element. /// - /// The array of elements to write. - /// The maximum allowed length for each individual . + /// The array of elements to write. + /// The maximum allowed length for each individual . public void PutArray(string[] value, int strMaxLength) { ushort strArrayLength = value == null ? (ushort)0 : (ushort)value.Length; @@ -534,7 +534,7 @@ public void PutArray(string[] value, int strMaxLength) /// The network endpoint to write. /// Thrown when the is not or . /// - /// Writes a (0 for IPv4, 1 for IPv6), followed by the address bytes and a 2-byte port. + /// Writes a (0 for IPv4, 1 for IPv6), followed by the address bytes and a 2-byte port. /// public void Put(IPEndPoint endPoint) { @@ -556,11 +556,11 @@ public void Put(IPEndPoint endPoint) } /// - /// Serializes a using a 4-byte length header. + /// Serializes a using a 4-byte length header. /// - /// The to write. + /// The to write. /// - /// Recommended for strings that may exceed the 65535 byte limit of standard length headers.
+ /// Recommended for strings that may exceed the 65535 byte limit of standard length headers.
/// Uses . ///
public void PutLargeString(string value) @@ -584,8 +584,17 @@ public void PutLargeString(string value) } /// - /// Note that "maxLength" only limits the number of characters in a string, not its size in bytes. + /// Serializes a string using a 2-byte length header. /// + /// The string to write to the buffer. + /// + /// The maximum number of characters to write. If the string is longer, it will be truncated.
+ /// A value of 0 indicates no limit. + /// + /// + /// Note that limits the number of characters, not the total size in s.
+ /// Uses . + ///
public void Put(string value, int maxLength = 0) { if (string.IsNullOrEmpty(value)) From ad6b8f613b6bb6872756ab7f3e1d38ed5e0e85da Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Sat, 21 Mar 2026 00:31:22 +0100 Subject: [PATCH 187/261] Use FastBitConverter --- LiteNetLib/Utils/NetDataWriter.cs | 47 ++++--------------------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 9420c969..197fc717 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -322,14 +322,7 @@ public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) ResizeIfNeed(_position + 2 + length); } -#if NET8_0_OR_GREATER - Unsafe.WriteUnaligned(ref _data[_position], length); -#else - fixed (byte* ptr = &_data[_position]) - { - *(ushort*)ptr = length; - } -#endif + FastBitConverter.GetBytes(_data, _position, length); _position += 2; if (length > 0) @@ -361,14 +354,7 @@ public void PutBytesWithLength(byte[] data, int offset, ushort length) ResizeIfNeed(_position + 2 + length); } -#if NET8_0_OR_GREATER - Unsafe.WriteUnaligned(ref _data[_position], length); -#else - fixed (byte* ptr = &_data[_position]) - { - *(ushort*)ptr = length; - } -#endif + FastBitConverter.GetBytes(_data, _position, length); _position += 2; if (length > 0) @@ -440,14 +426,7 @@ public void PutSpan(Span span) where T : unmanaged ResizeIfNeed(_position + byteLength + 2); } -#if NET8_0_OR_GREATER - Unsafe.WriteUnaligned(ref _data[_position], length); -#else - fixed (byte* ptr = &_data[_position]) - { - *(ushort*)ptr = length; - } -#endif + FastBitConverter.GetBytes(_data, _position, length); _position += 2; if (length > 0) @@ -631,16 +610,7 @@ public void PutUnmanaged(T value) where T : unmanaged { ResizeIfNeed(_position + size); } - -#if NET8_0_OR_GREATER - Unsafe.WriteUnaligned(ref _data[_position], value); -#else - fixed (byte* ptr = &_data[_position]) - { - *(T*)ptr = value; - } -#endif - + FastBitConverter.GetBytes(_data, _position, value); _position += size; } @@ -680,14 +650,7 @@ public void PutEnum(T value) where T : unmanaged, Enum ResizeIfNeed(_position + size); } -#if NET8_0_OR_GREATER - Unsafe.WriteUnaligned(ref _data[_position], value); -#else - fixed (byte* ptr = &_data[_position]) - { - *(T*)ptr = value; - } -#endif + FastBitConverter.GetBytes(_data, _position, value); _position += size; } From fc24c7ca51829bf4ec792cc6a6937ced7f1aa03d Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Sat, 21 Mar 2026 00:33:53 +0100 Subject: [PATCH 188/261] Formatting --- LiteNetLib/Utils/NetDataWriter.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 197fc717..08320a28 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -318,9 +318,7 @@ public void Put(ReadOnlySpan data) public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) { if (_autoResize) - { ResizeIfNeed(_position + 2 + length); - } FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -350,9 +348,7 @@ public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) public void PutBytesWithLength(byte[] data, int offset, ushort length) { if (_autoResize) - { ResizeIfNeed(_position + 2 + length); - } FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -422,9 +418,7 @@ public void PutSpan(Span span) where T : unmanaged var byteLength = length * sizeof(T); if (_autoResize) - { ResizeIfNeed(_position + byteLength + 2); - } FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -607,9 +601,7 @@ public void PutUnmanaged(T value) where T : unmanaged { int size = sizeof(T); if (_autoResize) - { ResizeIfNeed(_position + size); - } FastBitConverter.GetBytes(_data, _position, value); _position += size; } From 99a909f28a35f9eaa93ae18fdf9c787db8082c31 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Sat, 21 Mar 2026 00:48:57 +0100 Subject: [PATCH 189/261] Use WriteUnaligned --- LiteNetLib/Utils/FastBitConverter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/FastBitConverter.cs b/LiteNetLib/Utils/FastBitConverter.cs index 82bedf4e..b067a3db 100644 --- a/LiteNetLib/Utils/FastBitConverter.cs +++ b/LiteNetLib/Utils/FastBitConverter.cs @@ -14,7 +14,9 @@ public static unsafe void GetBytes(byte[] bytes, int startIndex, T value) whe int size = sizeof(T); if (bytes.Length < startIndex + size) ThrowIndexOutOfRangeException(); -#if NETCOREAPP3_1 || NET5_0 || NETCOREAPP3_0_OR_GREATER +#if NET8_0_OR_GREATER + Unsafe.WriteUnaligned(ref bytes[startIndex], value); +#elif NETCOREAPP3_1 || NET5_0 || NETCOREAPP3_0_OR_GREATER Unsafe.As(ref bytes[startIndex]) = value; #else fixed (byte* ptr = &bytes[startIndex]) From 8d2854e4b5c187c6acf4c57224315debc0af0260 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Sat, 21 Mar 2026 01:03:53 +0100 Subject: [PATCH 190/261] Update GetEnum --- LiteNetLib/Utils/NetDataReader.cs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 30597f01..7d109031 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -680,7 +680,9 @@ public T GetUnmanaged() where T : unmanaged /// The enum value read from the buffer. public T GetEnum() where T : unmanaged, Enum { - var span = GetSpan(sizeof(T)); + int size = sizeof(T); + ReadOnlySpan span = new ReadOnlySpan(_data, _position, size); + _position += size; #if NET8_0_OR_GREATER return Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(span)); #else @@ -691,13 +693,6 @@ public T GetEnum() where T : unmanaged, Enum #endif } - public ReadOnlySpan GetSpan(int length) - { - ReadOnlySpan span = new ReadOnlySpan(_data, _position, length); - _position += length; - return span; - } - #endregion #region PeekMethods From 0032ef126dfef345942c856a09922537ccbef1c2 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Sun, 22 Mar 2026 12:54:33 +0200 Subject: [PATCH 191/261] little tunes --- LiteNetLib/Utils/NetDataReader.cs | 8 ++++---- LiteNetLib/Utils/NetDataWriter.cs | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 7d109031..fcf3ee04 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -6,7 +6,7 @@ namespace LiteNetLib.Utils { - public unsafe class NetDataReader + public class NetDataReader { protected byte[] _data; protected int _position; @@ -271,7 +271,7 @@ public IPEndPoint GetIPEndPoint() /// /// An unmanaged type. /// A new array of type . - public T[] GetUnmanagedArray() where T : unmanaged + public unsafe T[] GetUnmanagedArray() where T : unmanaged { ushort length = GetUShort(); int byteLength = length * sizeof(T); @@ -629,7 +629,7 @@ public void GetBytes(byte[] destination, int count) /// The value of type read from the buffer. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T GetUnmanaged() where T : unmanaged + public unsafe T GetUnmanaged() where T : unmanaged { var size = sizeof(T); EnsureAvailable(size); @@ -678,7 +678,7 @@ public T GetUnmanaged() where T : unmanaged /// /// An unmanaged enum type to read. /// The enum value read from the buffer. - public T GetEnum() where T : unmanaged, Enum + public unsafe T GetEnum() where T : unmanaged, Enum { int size = sizeof(T); ReadOnlySpan span = new ReadOnlySpan(_data, _position, size); diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 08320a28..5c00a6e4 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -7,7 +7,7 @@ namespace LiteNetLib.Utils { - public unsafe class NetDataWriter + public class NetDataWriter { protected byte[] _data; protected int _position; @@ -412,7 +412,7 @@ public void PutUnmanagedArray(T[] arr) where T : unmanaged /// Writes a 2-byte length header followed by the raw binary data.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PutSpan(Span span) where T : unmanaged + public unsafe void PutSpan(Span span) where T : unmanaged { var length = (ushort)span.Length; var byteLength = length * sizeof(T); @@ -597,7 +597,7 @@ public void Put(string value, int maxLength = 0) /// An unmanaged value type to write into the buffer. /// The value to write into the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PutUnmanaged(T value) where T : unmanaged + public unsafe void PutUnmanaged(T value) where T : unmanaged { int size = sizeof(T); if (_autoResize) @@ -608,7 +608,7 @@ public void PutUnmanaged(T value) where T : unmanaged /// /// Writes a nullable value of type into the internal byte buffer at the current position, - /// first writing a indicating whether the value is present, + /// first writing a indicating whether the value is present, /// and then writing the value itself if it exists.
Advances the position by 1 byte for the presence flag plus /// the size of if the value is present. ///
@@ -634,7 +634,7 @@ public void PutNullableUnmanaged(T? value) where T : unmanaged /// /// An unmanaged enum type to write. /// The enum value to write. - public void PutEnum(T value) where T : unmanaged, Enum + public unsafe void PutEnum(T value) where T : unmanaged, Enum { var size = sizeof(T); if (_autoResize) From d38944864c23c18ebe35c0e542f60046e177c16e Mon Sep 17 00:00:00 2001 From: RevenantX Date: Sun, 22 Mar 2026 12:55:25 +0200 Subject: [PATCH 192/261] update docs --- docs/api/LiteNetLib.ConnectionRequest.html | 352 +------- .../api/LiteNetLib.ILiteNetEventListener.html | 6 +- .../api/LiteNetLib.LiteConnectionRequest.html | 493 +++++++++++ docs/api/LiteNetLib.LiteNetManager.html | 53 +- .../LiteNetLib.NetConnectRequestPacket.html | 270 ++++++ docs/api/LiteNetLib.NetEvent.html | 4 +- docs/api/LiteNetLib.NetManager.html | 57 +- docs/api/LiteNetLib.NetPacketReader.html | 15 + docs/api/LiteNetLib.Utils.NetDataReader.html | 816 ++++++++++++++---- docs/api/LiteNetLib.Utils.NetDataWriter.html | 580 ++++++++++--- docs/api/LiteNetLib.html | 4 + docs/api/toc.html | 6 + docs/api/toc.json | 2 +- docs/manifest.json | 28 + docs/xrefmap.yml | 515 ++++++++--- 15 files changed, 2475 insertions(+), 726 deletions(-) create mode 100644 docs/api/LiteNetLib.LiteConnectionRequest.html create mode 100644 docs/api/LiteNetLib.NetConnectRequestPacket.html diff --git a/docs/api/LiteNetLib.ConnectionRequest.html b/docs/api/LiteNetLib.ConnectionRequest.html index a0db2405..9b89b5ca 100644 --- a/docs/api/LiteNetLib.ConnectionRequest.html +++ b/docs/api/LiteNetLib.ConnectionRequest.html @@ -76,79 +76,62 @@

Inheritance
object
-
ConnectionRequest
+ +
ConnectionRequest
+ +
Namespace: LiteNetLib
Assembly: LiteNetLib.dll
Syntax
-
public class ConnectionRequest
-
-

Fields -

- - -

RemoteEndPoint

-
-
-
Declaration
-
-
public readonly IPEndPoint RemoteEndPoint
-
-
Field Value
- - - - - - - - - - - - - -
TypeDescription
IPEndPoint
-

Properties -

- - - -

Data

-
-
-
Declaration
-
-
public NetDataReader Data { get; }
+
public class ConnectionRequest : LiteConnectionRequest
-
Property Value
- - - - - - - - - - - - - -
TypeDescription
NetDataReader

Methods

Accept()

-

Accept connection and get new NetPeer as result

-
+
Declaration
-
public LiteNetPeer Accept()
+
public NetPeer Accept()
Returns
@@ -160,9 +143,8 @@
Returns
- - + +
LiteNetPeer

Connected NetPeer

-
NetPeer
@@ -174,7 +156,7 @@

Declaration
-
public LiteNetPeer AcceptIfKey(string key)
+
public NetPeer AcceptIfKey(string key)
Parameters
@@ -203,251 +185,7 @@
Returns
- - - - -
LiteNetPeer
- - - -

Reject()

-
-
-
Declaration
-
-
public void Reject()
-
- - - -

Reject(NetDataWriter)

-
-
-
Declaration
-
-
public void Reject(NetDataWriter rejectData)
-
-
Parameters
- - - - - - - - - - - - - - - -
TypeNameDescription
NetDataWriterrejectData
- - - -

Reject(byte[])

-
-
-
Declaration
-
-
public void Reject(byte[] rejectData)
-
-
Parameters
- - - - - - - - - - - - - - - -
TypeNameDescription
byte[]rejectData
- - - -

Reject(byte[], int, int)

-
-
-
Declaration
-
-
public void Reject(byte[] rejectData, int start, int length)
-
-
Parameters
- - - - - - - - - - - - - - - - - - - - - - - - - -
TypeNameDescription
byte[]rejectData
intstart
intlength
- - - -

Reject(byte[], int, int, bool)

-
-
-
Declaration
-
-
public void Reject(byte[] rejectData, int start, int length, bool force)
-
-
Parameters
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeNameDescription
byte[]rejectData
intstart
intlength
boolforce
- - - -

RejectForce()

-
-
-
Declaration
-
-
public void RejectForce()
-
- - - -

RejectForce(NetDataWriter)

-
-
-
Declaration
-
-
public void RejectForce(NetDataWriter rejectData)
-
-
Parameters
- - - - - - - - - - - - - - - -
TypeNameDescription
NetDataWriterrejectData
- - - -

RejectForce(byte[])

-
-
-
Declaration
-
-
public void RejectForce(byte[] rejectData)
-
-
Parameters
- - - - - - - - - - - - - - - -
TypeNameDescription
byte[]rejectData
- - - -

RejectForce(byte[], int, int)

-
-
-
Declaration
-
-
public void RejectForce(byte[] rejectData, int start, int length)
-
-
Parameters
- - - - - - - - - - - - - - - - - - - - - - + diff --git a/docs/api/LiteNetLib.ILiteNetEventListener.html b/docs/api/LiteNetLib.ILiteNetEventListener.html index b67706f5..09fbcb96 100644 --- a/docs/api/LiteNetLib.ILiteNetEventListener.html +++ b/docs/api/LiteNetLib.ILiteNetEventListener.html @@ -85,13 +85,13 @@

Methods -

OnConnectionRequest(ConnectionRequest)

+

OnConnectionRequest(LiteConnectionRequest)

On peer connection requested

Declaration
-
void OnConnectionRequest(ConnectionRequest request)
+
void OnConnectionRequest(LiteConnectionRequest request)
Parameters
TypeNameDescription
byte[]rejectData
intstart
intlengthNetPeer
@@ -104,7 +104,7 @@
Parameters
- + diff --git a/docs/api/LiteNetLib.LiteConnectionRequest.html b/docs/api/LiteNetLib.LiteConnectionRequest.html new file mode 100644 index 00000000..6eb76992 --- /dev/null +++ b/docs/api/LiteNetLib.LiteConnectionRequest.html @@ -0,0 +1,493 @@ + + + + + + + + Class LiteConnectionRequest + + + + + + + + + + + + + + + +
+
+ + + + +
+
ConnectionRequestLiteConnectionRequest request

Request information (EndPoint, internal id, additional data)

+ + + + + + + + + + + + +
TypeDescription
IPEndPoint
+

Properties +

+ + + +

Data

+
+
+
Declaration
+
+
public NetDataReader Data { get; }
+
+
Property Value
+ + + + + + + + + + + + + +
TypeDescription
NetDataReader
+

Methods +

+ + + +

Accept()

+

Accept connection and get new NetPeer as result

+
+
+
Declaration
+
+
public LiteNetPeer Accept()
+
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
LiteNetPeer

Connected NetPeer

+
+ + + +

AcceptIfKey(string)

+
+
+
Declaration
+
+
public LiteNetPeer AcceptIfKey(string key)
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
stringkey
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
LiteNetPeer
+ + + +

Reject()

+
+
+
Declaration
+
+
public void Reject()
+
+ + + +

Reject(NetDataWriter)

+
+
+
Declaration
+
+
public void Reject(NetDataWriter rejectData)
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
NetDataWriterrejectData
+ + + +

Reject(byte[])

+
+
+
Declaration
+
+
public void Reject(byte[] rejectData)
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
byte[]rejectData
+ + + +

Reject(byte[], int, int)

+
+
+
Declaration
+
+
public void Reject(byte[] rejectData, int start, int length)
+
+
Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescription
byte[]rejectData
intstart
intlength
+ + + +

Reject(byte[], int, int, bool)

+
+
+
Declaration
+
+
public void Reject(byte[] rejectData, int start, int length, bool force)
+
+
Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescription
byte[]rejectData
intstart
intlength
boolforce
+ + + +

RejectForce()

+
+
+
Declaration
+
+
public void RejectForce()
+
+ + + +

RejectForce(NetDataWriter)

+
+
+
Declaration
+
+
public void RejectForce(NetDataWriter rejectData)
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
NetDataWriterrejectData
+ + + +

RejectForce(byte[])

+
+
+
Declaration
+
+
public void RejectForce(byte[] rejectData)
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
byte[]rejectData
+ + + +

RejectForce(byte[], int, int)

+
+
+
Declaration
+
+
public void RejectForce(byte[] rejectData, int start, int length)
+
+
Parameters
+ + + + + + + + + + + + + + + + + + + + + + + + + +
TypeNameDescription
byte[]rejectData
intstart
intlength
+ + + + + + + + + + + + + + + + diff --git a/docs/api/LiteNetLib.LiteNetManager.html b/docs/api/LiteNetLib.LiteNetManager.html index 97b3162b..cc9bd602 100644 --- a/docs/api/LiteNetLib.LiteNetManager.html +++ b/docs/api/LiteNetLib.LiteNetManager.html @@ -1625,13 +1625,60 @@
Returns
+ +

CreateConnectionRequest(IPEndPoint, NetConnectRequestPacket)

+
+
+
Declaration
+
+
protected virtual LiteConnectionRequest CreateConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket requestPacket)
+
+
Parameters
+ + + + + + + + + + + + + + + + + + + + +
TypeNameDescription
IPEndPointremoteEndPoint
NetConnectRequestPacketrequestPacket
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
LiteConnectionRequest
+ + -

CreateIncomingPeer(ConnectionRequest, int)

+

CreateIncomingPeer(LiteConnectionRequest, int)

Declaration
-
protected virtual LiteNetPeer CreateIncomingPeer(ConnectionRequest request, int id)
+
protected virtual LiteNetPeer CreateIncomingPeer(LiteConnectionRequest request, int id)
Parameters
@@ -1644,7 +1691,7 @@
Parameters
- + diff --git a/docs/api/LiteNetLib.NetConnectRequestPacket.html b/docs/api/LiteNetLib.NetConnectRequestPacket.html new file mode 100644 index 00000000..c39a3bde --- /dev/null +++ b/docs/api/LiteNetLib.NetConnectRequestPacket.html @@ -0,0 +1,270 @@ + + + + + + + + Class NetConnectRequestPacket + + + + + + + + + + + + + + + +
+
+ + + + +
+
ConnectionRequestLiteConnectionRequest request
+ + + + + + + + + + + + +
TypeDescription
byte
+ + +

ConnectionTime

+
+
+
Declaration
+
+
public readonly long ConnectionTime
+
+
Field Value
+ + + + + + + + + + + + + +
TypeDescription
long
+ + +

Data

+
+
+
Declaration
+
+
public readonly NetDataReader Data
+
+
Field Value
+ + + + + + + + + + + + + +
TypeDescription
NetDataReader
+ + +

HeaderSize

+
+
+
Declaration
+
+
public const int HeaderSize = 18
+
+
Field Value
+ + + + + + + + + + + + + +
TypeDescription
int
+ + +

PeerId

+
+
+
Declaration
+
+
public readonly int PeerId
+
+
Field Value
+ + + + + + + + + + + + + +
TypeDescription
int
+ + +

TargetAddress

+
+
+
Declaration
+
+
public readonly byte[] TargetAddress
+
+
Field Value
+ + + + + + + + + + + + + +
TypeDescription
byte[]
+ + + + + + + + + + + + + + + + diff --git a/docs/api/LiteNetLib.NetEvent.html b/docs/api/LiteNetLib.NetEvent.html index 98a9e57e..bea06f3b 100644 --- a/docs/api/LiteNetLib.NetEvent.html +++ b/docs/api/LiteNetLib.NetEvent.html @@ -147,7 +147,7 @@

Declaration
-
public ConnectionRequest ConnectionRequest
+
public LiteConnectionRequest ConnectionRequest
Field Value
@@ -159,7 +159,7 @@
Field Value
- + diff --git a/docs/api/LiteNetLib.NetManager.html b/docs/api/LiteNetLib.NetManager.html index 79ec6f88..86c94fa8 100644 --- a/docs/api/LiteNetLib.NetManager.html +++ b/docs/api/LiteNetLib.NetManager.html @@ -789,13 +789,62 @@
Exceptions
ConnectionRequestLiteConnectionRequest
+ +

CreateConnectionRequest(IPEndPoint, NetConnectRequestPacket)

+
+
+
Declaration
+
+
protected override LiteConnectionRequest CreateConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket requestPacket)
+
+
Parameters
+ + + + + + + + + + + + + + + + + + + + +
TypeNameDescription
IPEndPointremoteEndPoint
NetConnectRequestPacketrequestPacket
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
LiteConnectionRequest
+
Overrides
+ + + -

CreateIncomingPeer(ConnectionRequest, int)

+

CreateIncomingPeer(LiteConnectionRequest, int)

Declaration
-
protected override LiteNetPeer CreateIncomingPeer(ConnectionRequest request, int id)
+
protected override LiteNetPeer CreateIncomingPeer(LiteConnectionRequest request, int id)
Parameters
@@ -808,7 +857,7 @@
Parameters
- + @@ -835,7 +884,7 @@
Returns
ConnectionRequestLiteConnectionRequest request
Overrides
- + diff --git a/docs/api/LiteNetLib.NetPacketReader.html b/docs/api/LiteNetLib.NetPacketReader.html index 59159508..a2634d2c 100644 --- a/docs/api/LiteNetLib.NetPacketReader.html +++ b/docs/api/LiteNetLib.NetPacketReader.html @@ -183,6 +183,9 @@
Inherited Members
+ @@ -300,6 +303,15 @@
Inherited Members
+ + + @@ -342,6 +354,9 @@
Inherited Members
+ diff --git a/docs/api/LiteNetLib.Utils.NetDataReader.html b/docs/api/LiteNetLib.Utils.NetDataReader.html index 477f7dc5..4b8e7acb 100644 --- a/docs/api/LiteNetLib.Utils.NetDataReader.html +++ b/docs/api/LiteNetLib.Utils.NetDataReader.html @@ -292,7 +292,8 @@

Properties

AvailableBytes

-
+

Gets the number of bytes remaining to be read.

+
Declaration
@@ -317,7 +318,8 @@
Property Value

EndOfData

-
+

Gets a value indicating whether the Position has reached the end of the data.

+
Declaration
@@ -342,7 +344,8 @@
Property Value

IsNull

-
+

Gets a value indicating whether the internal data buffer is null.

+
Declaration
@@ -367,7 +370,8 @@
Property Value

Position

-
+

Gets the current read position within the buffer.

+
Declaration
@@ -392,7 +396,8 @@
Property Value

RawData

-
+

Gets the internal byte array containing the raw network data.

+
Declaration
@@ -417,7 +422,8 @@
Property Value

RawDataSize

-
+

Gets the total size of the RawData buffer.

+
Declaration
@@ -442,7 +448,8 @@
Property Value

UserDataOffset

-
+

Gets the starting offset of the user payload within the RawData.

+
Declaration
@@ -467,7 +474,8 @@
Property Value

UserDataSize

-
+

Gets the size of the user payload excluding the initial UserDataOffset.

+
Declaration
@@ -494,7 +502,8 @@

Methods

Clear()

-
+

Clears the reader state and releases the reference to the internal buffer.

+
Declaration
@@ -504,7 +513,8 @@
Declaration

Get(out bool)

-
+

Reads a bool and assigns it to result.

+
Declaration
@@ -531,7 +541,8 @@
Parameters

Get(out byte)

-
+

Reads a byte and assigns it to result.

+
Declaration
@@ -558,7 +569,8 @@
Parameters

Get(out char)

-
+

Reads a char and assigns it to result.

+
Declaration
@@ -585,7 +597,8 @@
Parameters

Get(out double)

-
+

Reads a double and assigns it to result.

+
Declaration
@@ -612,7 +625,8 @@
Parameters

Get(out Guid)

-
+

Reads a Guid and assigns it to result.

+
Declaration
@@ -639,7 +653,8 @@
Parameters

Get(out short)

-
+

Reads a short and assigns it to result.

+
Declaration
@@ -666,7 +681,8 @@
Parameters

Get(out int)

-
+

Reads an int and assigns it to result.

+
Declaration
@@ -693,7 +709,8 @@
Parameters

Get(out long)

-
+

Reads a long and assigns it to result.

+
Declaration
@@ -720,7 +737,8 @@
Parameters

Get(out IPEndPoint)

-
+

Deserializes an IPEndPoint and assigns it to the result parameter.

+
Declaration
@@ -739,7 +757,8 @@
Parameters
IPEndPoint result - +

The deserialized IPEndPoint output.

+ @@ -747,7 +766,8 @@
Parameters

Get(out sbyte)

-
+

Reads an sbyte and assigns it to result.

+
Declaration
@@ -774,7 +794,8 @@
Parameters

Get(out float)

-
+

Reads a float and assigns it to result.

+
Declaration
@@ -801,7 +822,8 @@
Parameters

Get(out string)

-
+

Reads a string and assigns it to result.

+
Declaration
@@ -828,7 +850,8 @@
Parameters

Get(out string, int)

-
+

Reads a string with a length limit and assigns it to result.

+
Declaration
@@ -860,7 +883,8 @@
Parameters

Get(out ushort)

-
+

Reads a ushort and assigns it to result.

+
Declaration
@@ -887,7 +911,8 @@
Parameters

Get(out uint)

-
+

Reads a uint and assigns it to result.

+
Declaration
@@ -914,7 +939,8 @@
Parameters

Get(out ulong)

-
+

Reads a ulong and assigns it to result.

+
Declaration
@@ -941,7 +967,8 @@
Parameters

GetArray<T>()

-
+

Reads an array of objects implementing INetSerializable.

+
Declaration
@@ -958,7 +985,8 @@
Returns
T[] - +

A new array of type T.

+ @@ -973,7 +1001,8 @@
Type Parameters
T - +

A type with a parameterless constructor implementing INetSerializable.

+ @@ -981,7 +1010,8 @@
Type Parameters

GetArray<T>(Func<T>)

-
+

Reads an array of objects implementing INetSerializable using a specific constructor.

+
Declaration
@@ -1000,7 +1030,8 @@
Parameters
Func<T> constructor - +

The factory delegate used to create instances.

+ @@ -1015,7 +1046,8 @@
Returns
T[] - +

A new array of type T.

+ @@ -1030,7 +1062,8 @@
Type Parameters
T - +

A class type implementing INetSerializable.

+ @@ -1038,7 +1071,8 @@
Type Parameters

GetArray<T>(ushort)

-
+

Reads an array of values by performing a direct memory copy.

+
Declaration
@@ -1057,7 +1091,8 @@
Parameters
ushort size - +

The size of a single element in bytes.

+ @@ -1072,7 +1107,8 @@
Returns
T[] - +

A new array of type T.

+ @@ -1087,7 +1123,8 @@
Type Parameters
T - +

The element type.

+ @@ -1095,7 +1132,8 @@
Type Parameters

GetBool()

-
+

Reads a bool value from the current position.

+
Declaration
@@ -1112,7 +1150,8 @@
Returns
bool - +

true if the byte is 1; otherwise, false.

+ @@ -1120,7 +1159,8 @@
Returns

GetBoolArray()

-
+

Reads an array of bool values.

+
Declaration
@@ -1145,7 +1185,8 @@
Returns

GetByte()

-
+

Reads the next byte from the buffer.

+
Declaration
@@ -1170,7 +1211,8 @@
Returns

GetBytes(byte[], int)

-
+

Copies a specified number of bytes into a destination array starting at index 0.

+
Declaration
@@ -1189,12 +1231,14 @@
Parameters
byte[] destination - +

The array to copy data into.

+ int count - +

The number of bytes to read.

+ @@ -1202,7 +1246,8 @@
Parameters

GetBytes(byte[], int, int)

-
+

Copies a specified number of bytes into a destination array at a specific offset.

+
Declaration
@@ -1221,17 +1266,20 @@
Parameters
byte[] destination - +

The array to copy data into.

+ int start - +

The starting index in the destination array.

+ int count - +

The number of bytes to read.

+ @@ -1239,7 +1287,8 @@
Parameters

GetBytesSegment(int)

-
+

Gets an ArraySegment<T> of bytes from the current position.

+
Declaration
@@ -1258,7 +1307,8 @@
Parameters
int count - +

The number of bytes to include in the segment.

+ @@ -1273,7 +1323,8 @@
Returns
ArraySegment<byte> - +

An ArraySegment<T> wrapping the internal buffer.

+ @@ -1281,7 +1332,8 @@
Returns

GetBytesWithLength()

-
+

Reads a byte array prefixed with its ushort length.

+
Declaration
@@ -1298,7 +1350,8 @@
Returns
byte[] - +

A new byte array.

+ @@ -1306,7 +1359,8 @@
Returns

GetChar()

-
+

Reads a char value as a 2-byte ushort.

+
Declaration
@@ -1331,7 +1385,8 @@
Returns

GetDouble()

-
+

Reads a double value using unmanaged memory access.

+
Declaration
@@ -1356,7 +1411,8 @@
Returns

GetDoubleArray()

-
+

Reads an array of double values.

+
Declaration
@@ -1379,9 +1435,54 @@
Returns
+ +

GetEnum<T>()

+

Reads an enum value of type T from the internal data buffer at the current position.
+Advances the position by the size of T.

+
+
+
Declaration
+
+
public T GetEnum<T>() where T : unmanaged, Enum
+
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
T

The enum value read from the buffer.

+
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T

An unmanaged enum type to read.

+
+ +

GetFloat()

-
+

Reads a float value using unmanaged memory access.

+
Declaration
@@ -1406,7 +1507,8 @@
Returns

GetFloatArray()

-
+

Reads an array of float values.

+
Declaration
@@ -1431,7 +1533,8 @@
Returns

GetGuid()

-
+

Reads a 16-byte Guid.

+
Declaration
@@ -1448,7 +1551,8 @@
Returns
Guid - +

The deserialized Guid.

+ @@ -1456,7 +1560,8 @@
Returns

GetIPEndPoint()

-
+

Reads an IPEndPoint from the current Position.

+
Declaration
@@ -1473,15 +1578,21 @@
Returns
IPEndPoint - +

The deserialized IPEndPoint.

+ +
Remarks
+

Reads a byte to determine the AddressFamily (0 for IPv4, 1 for IPv6), +followed by the address bytes and a 2-byte ushort port.

+

GetInt()

-
+

Reads an int value using unmanaged memory access.

+
Declaration
@@ -1506,7 +1617,8 @@
Returns

GetIntArray()

-
+

Reads an array of int values.

+
Declaration
@@ -1531,7 +1643,8 @@
Returns

GetLargeString()

-
+

Reads a string prefixed with a 4-byte int length header.

+
Declaration
@@ -1548,7 +1661,8 @@
Returns
string - +

The deserialized string.

+ @@ -1556,7 +1670,8 @@
Returns

GetLong()

-
+

Reads a long value using unmanaged memory access.

+
Declaration
@@ -1581,7 +1696,8 @@
Returns

GetLongArray()

-
+

Reads an array of long values.

+
Declaration
@@ -1604,9 +1720,72 @@
Returns
+ +

GetNullableUnmanaged<T>()

+

Reads a nullable value of type T from the internal byte buffer at the current position, +first reading a bool indicating whether the value is present, +and then reading the value itself if it exists.
+Advances the position by 1 byte for the presence flag plus the size of T if the value is present.

+
+
+
Declaration
+
+
public T? GetNullableUnmanaged<T>() where T : unmanaged
+
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
T?

The nullable value of type T read from the buffer. +Returns null if the presence flag indicates no value.

+
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T

An unmanaged value type to read from the buffer.

+
+
Exceptions
+ + + + + + + + + + + + + +
TypeCondition
IndexOutOfRangeException
+ +

GetRemainingBytes()

-
+

Reads all remaining bytes and returns them as a new array.

+
Declaration
@@ -1623,15 +1802,20 @@
Returns
byte[] - +

A new byte array containing the remaining data.

+ +
Remarks
+

This method performs a heap allocation and advances the Position to the end of the data.

+

GetRemainingBytesMemory()

-
+

Returns a ReadOnlyMemory<T> of bytes containing all remaining data.

+
Declaration
@@ -1648,7 +1832,8 @@
Returns
ReadOnlyMemory<byte> - +

A ReadOnlyMemory<T> from the current Position to the end of the buffer.

+ @@ -1656,7 +1841,8 @@
Returns

GetRemainingBytesSegment()

-
+

Gets an ArraySegment<T> containing all remaining bytes.

+
Declaration
@@ -1673,7 +1859,8 @@
Returns
ArraySegment<byte> - +

An ArraySegment<T> from the current position to the end of the data.

+ @@ -1681,7 +1868,8 @@
Returns

GetRemainingBytesSpan()

-
+

Returns a ReadOnlySpan<T> of bytes containing all remaining data.

+
Declaration
@@ -1698,7 +1886,8 @@
Returns
ReadOnlySpan<byte> - +

A ReadOnlySpan<T> from the current Position to the end of the buffer.

+ @@ -1706,7 +1895,8 @@
Returns

GetSByte()

-
+

Reads the next sbyte from the buffer.

+
Declaration
@@ -1731,7 +1921,8 @@
Returns

GetSBytesWithLength()

-
+

Reads an sbyte array prefixed with its ushort length.

+
Declaration
@@ -1748,7 +1939,8 @@
Returns
sbyte[] - +

A new sbyte array.

+ @@ -1756,7 +1948,8 @@
Returns

GetShort()

-
+

Reads a short value using unmanaged memory access.

+
Declaration
@@ -1781,7 +1974,8 @@
Returns

GetShortArray()

-
+

Reads an array of short values.

+
Declaration
@@ -1806,7 +2000,8 @@
Returns

GetString()

-
+

Reads a string from the current position.

+
Declaration
@@ -1823,7 +2018,8 @@
Returns
string - +

The deserialized string.

+ @@ -1831,7 +2027,7 @@
Returns

GetString(int)

-

Note that "maxLength" only limits the number of characters in a string, not its size in bytes.

+

Reads a string with a maximum character limit.

Declaration
@@ -1851,7 +2047,8 @@
Parameters
int maxLength - +

The maximum allowed character count.

+ @@ -1866,16 +2063,20 @@
Returns
string -

"string.Empty" if value > "maxLength"

+

The deserialized string, or Empty if the character count exceeds maxLength.

+
Remarks
+

Note that maxLength limits the number of characters, not the total size in bytes.

+

GetStringArray()

-
+

Reads an array of string values.

+
Declaration
@@ -1892,16 +2093,19 @@
Returns
string[] - +

A new string array.

+ +
Remarks
+

Reads a 2-byte ushort length header followed by each string element.

+

GetStringArray(int)

-

Note that "maxStringLength" only limits the number of characters in a string, not its size in bytes. -Strings that exceed this parameter are returned as empty

+

Reads an array of string values with a maximum character limit per element.

Declaration
@@ -1921,7 +2125,8 @@
Parameters
int maxStringLength - +

The maximum number of characters allowed per string.

+ @@ -1936,15 +2141,20 @@
Returns
string[] - +

A new string array.

+ +
Remarks
+

Strings exceeding maxStringLength are returned as Empty.

+

GetUInt()

-
+

Reads a uint value using unmanaged memory access.

+
Declaration
@@ -1969,7 +2179,8 @@
Returns

GetUIntArray()

-
+

Reads an array of uint values.

+
Declaration
@@ -1994,7 +2205,8 @@
Returns

GetULong()

-
+

Reads a ulong value using unmanaged memory access.

+
Declaration
@@ -2019,7 +2231,8 @@
Returns

GetULongArray()

-
+

Reads an array of ulong values.

+
Declaration
@@ -2044,7 +2257,8 @@
Returns

GetUShort()

-
+

Reads a ushort value using unmanaged memory access.

+
Declaration
@@ -2069,7 +2283,8 @@
Returns

GetUShortArray()

-
+

Reads an array of ushort values.

+
Declaration
@@ -2092,9 +2307,112 @@
Returns
+ +

GetUnmanagedArray<T>()

+

Reads an array of unmanaged values prefixed by a ushort length.

+
+
+
Declaration
+
+
public T[] GetUnmanagedArray<T>() where T : unmanaged
+
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
T[]

A new array of type T.

+
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T

An unmanaged type.

+
+ + + +

GetUnmanaged<T>()

+

Reads a value of type T from the internal byte buffer at the current position, +advancing the position by the size of T.

+
+
+
Declaration
+
+
public T GetUnmanaged<T>() where T : unmanaged
+
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
T

The value of type T read from the buffer.

+
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T

An unmanaged value type to read from the buffer.

+
+
Exceptions
+ + + + + + + + + + + + + +
TypeCondition
IndexOutOfRangeException
+ +

Get<T>()

-
+

Deserializes a struct that implements INetSerializable.

+
Declaration
@@ -2111,7 +2429,8 @@
Returns
T - +

The deserialized struct.

+ @@ -2126,7 +2445,8 @@
Type Parameters
T - +

A struct type implementing INetSerializable.

+ @@ -2134,7 +2454,8 @@
Type Parameters

Get<T>(Func<T>)

-
+

Deserializes a class that implements INetSerializable using a provided constructor.

+
Declaration
@@ -2153,7 +2474,8 @@
Parameters
Func<T> constructor - +

The factory delegate used to instantiate the class.

+ @@ -2168,7 +2490,8 @@
Returns
T - +

A new instance of T.

+ @@ -2183,7 +2506,8 @@
Type Parameters
T - +

A class type implementing INetSerializable.

+ @@ -2191,7 +2515,8 @@
Type Parameters

Get<T>(out T)

-
+

Deserializes a struct that implements INetSerializable.

+
Declaration
@@ -2210,7 +2535,8 @@
Parameters
T result - +

The deserialized struct output.

+ @@ -2225,7 +2551,8 @@
Type Parameters
T - +

A struct type implementing INetSerializable.

+ @@ -2233,7 +2560,8 @@
Type Parameters

Get<T>(out T, Func<T>)

-
+

Deserializes a that implements INetSerializable using a provided constructor.

+
Declaration
@@ -2252,12 +2580,14 @@
Parameters
T result - +

The deserialized class instance output.

+ Func<T> constructor - +

A factory delegate used to instantiate the class.

+ @@ -2272,7 +2602,8 @@
Type Parameters
T - +

A class type implementing INetSerializable.

+ @@ -2280,7 +2611,8 @@
Type Parameters

PeekBool()

-
+

Reads the bool at the current position without advancing the Position.

+
Declaration
@@ -2305,7 +2637,8 @@
Returns

PeekByte()

-
+

Reads the byte at the current position without advancing the Position.

+
Declaration
@@ -2330,7 +2663,8 @@
Returns

PeekChar()

-
+

Reads the char at the current position without advancing the Position.

+
Declaration
@@ -2355,7 +2689,8 @@
Returns

PeekDouble()

-
+

Reads the double at the current position without advancing the Position.

+
Declaration
@@ -2380,7 +2715,8 @@
Returns

PeekFloat()

-
+

Reads the float at the current position without advancing the Position.

+
Declaration
@@ -2405,7 +2741,8 @@
Returns

PeekInt()

-
+

Reads the int at the current position without advancing the Position.

+
Declaration
@@ -2430,7 +2767,8 @@
Returns

PeekLong()

-
+

Reads the long at the current position without advancing the Position.

+
Declaration
@@ -2455,7 +2793,8 @@
Returns

PeekSByte()

-
+

Reads the sbyte at the current position without advancing the Position.

+
Declaration
@@ -2480,7 +2819,8 @@
Returns

PeekShort()

-
+

Reads the short at the current position without advancing the Position.

+
Declaration
@@ -2505,7 +2845,8 @@
Returns

PeekString()

-
+

Reads a string without advancing the Position.

+
Declaration
@@ -2530,7 +2871,7 @@
Returns

PeekString(int)

-

Note that "maxLength" only limits the number of characters in a string, not its size in bytes.

+

Reads a string with a character limit without advancing the Position.

Declaration
@@ -2550,7 +2891,8 @@
Parameters
int maxLength - +

Maximum allowed character count.

+ @@ -2569,11 +2911,15 @@
Returns
+
Remarks
+

Strings exceeding maxLength are returned as Empty.

+

PeekUInt()

-
+

Reads the uint at the current position without advancing the Position.

+
Declaration
@@ -2598,7 +2944,8 @@
Returns

PeekULong()

-
+

Reads the ulong at the current position without advancing the Position.

+
Declaration
@@ -2623,7 +2970,8 @@
Returns

PeekUShort()

-
+

Reads the ushort at the current position without advancing the Position.

+
Declaration
@@ -2646,9 +2994,53 @@
Returns
+ +

PeekUnmanaged<T>()

+

Reads an unmanaged value of type T at the current position without advancing the Position.

+
+
+
Declaration
+
+
public T PeekUnmanaged<T>() where T : unmanaged
+
+
Returns
+ + + + + + + + + + + + + +
TypeDescription
T

The value read from the buffer.

+
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T

An unmanaged value type.

+
+ +

SetPosition(int)

-
+

Sets the current read Position to a specific index.

+
Declaration
@@ -2667,7 +3059,8 @@
Parameters
int position - +

The index to move the Position to.

+ @@ -2675,7 +3068,8 @@
Parameters

SetSource(NetDataWriter)

-
+

Reinitializes the reader using data from a NetDataWriter.

+
Declaration
@@ -2694,7 +3088,8 @@
Parameters
NetDataWriter dataWriter - +

The source NetDataWriter.

+ @@ -2702,7 +3097,8 @@
Parameters

SetSource(byte[])

-
+

Reinitializes the reader using a byte array.

+
Declaration
@@ -2721,7 +3117,8 @@
Parameters
byte[] source - +

The source byte array.

+ @@ -2729,7 +3126,8 @@
Parameters

SetSource(byte[], int, int)

-
+

Reinitializes the reader using a segment of a byte array.

+
Declaration
@@ -2748,17 +3146,20 @@
Parameters
byte[] source - +

The source byte array.

+ int offset - +

The starting index for reading.

+ int maxSize - +

The total number of bytes available to read from the source.

+ @@ -2766,7 +3167,8 @@
Parameters

SkipBytes(int)

-
+

Advances the Position by the specified count.

+
Declaration
@@ -2785,7 +3187,8 @@
Parameters
int count - +

The number of bytes to skip.

+ @@ -2793,7 +3196,8 @@
Parameters

TryGetBool(out bool)

-
+

Attempts to read a bool without throwing an exception.

+
Declaration
@@ -2812,7 +3216,8 @@
Parameters
bool result - +

The deserialized bool, or false if failed.

+ @@ -2827,7 +3232,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -2835,7 +3241,8 @@
Returns

TryGetByte(out byte)

-
+

Attempts to read a byte without throwing an exception.

+
Declaration
@@ -2854,7 +3261,8 @@
Parameters
byte result - +

The deserialized byte, or 0 if failed.

+ @@ -2869,7 +3277,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -2877,7 +3286,8 @@
Returns

TryGetBytesWithLength(out byte[])

-
+

Attempts to read a byte array with a length header without throwing an exception.

+
Declaration
@@ -2896,7 +3306,8 @@
Parameters
byte[] result - +

The deserialized byte array, or null if failed.

+ @@ -2911,7 +3322,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -2919,7 +3331,8 @@
Returns

TryGetChar(out char)

-
+

Attempts to read a char without throwing an exception.

+
Declaration
@@ -2938,7 +3351,8 @@
Parameters
char result - +

The deserialized char, or '\0' if failed.

+ @@ -2953,7 +3367,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -2961,7 +3376,8 @@
Returns

TryGetDouble(out double)

-
+

Attempts to read a double without throwing an exception.

+
Declaration
@@ -2980,7 +3396,8 @@
Parameters
double result - +

The deserialized double, or 0 if failed.

+ @@ -2995,7 +3412,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3003,7 +3421,8 @@
Returns

TryGetFloat(out float)

-
+

Attempts to read a float without throwing an exception.

+
Declaration
@@ -3022,7 +3441,8 @@
Parameters
float result - +

The deserialized float, or 0 if failed.

+ @@ -3037,7 +3457,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3045,7 +3466,8 @@
Returns

TryGetInt(out int)

-
+

Attempts to read an int without throwing an exception.

+
Declaration
@@ -3064,7 +3486,8 @@
Parameters
int result - +

The deserialized int, or 0 if failed.

+ @@ -3079,7 +3502,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3087,7 +3511,8 @@
Returns

TryGetLong(out long)

-
+

Attempts to read a long without throwing an exception.

+
Declaration
@@ -3106,7 +3531,8 @@
Parameters
long result - +

The deserialized long, or 0 if failed.

+ @@ -3121,7 +3547,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3129,7 +3556,8 @@
Returns

TryGetSByte(out sbyte)

-
+

Attempts to read an sbyte without throwing an exception.

+
Declaration
@@ -3148,7 +3576,8 @@
Parameters
sbyte result - +

The deserialized sbyte, or 0 if failed.

+ @@ -3163,7 +3592,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3171,7 +3601,8 @@
Returns

TryGetShort(out short)

-
+

Attempts to read a short without throwing an exception.

+
Declaration
@@ -3190,7 +3621,8 @@
Parameters
short result - +

The deserialized short, or 0 if failed.

+ @@ -3205,7 +3637,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3213,7 +3646,8 @@
Returns

TryGetString(out string)

-
+

Attempts to read a string without throwing an exception.

+
Declaration
@@ -3232,7 +3666,8 @@
Parameters
string result - +

The deserialized string, or null if failed.

+ @@ -3247,7 +3682,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3255,7 +3691,8 @@
Returns

TryGetStringArray(out string[])

-
+

Attempts to read a string array without throwing an exception.

+
Declaration
@@ -3274,7 +3711,8 @@
Parameters
string[] result - +

The deserialized string array, or null if failed.

+ @@ -3289,7 +3727,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3297,7 +3736,8 @@
Returns

TryGetUInt(out uint)

-
+

Attempts to read a uint without throwing an exception.

+
Declaration
@@ -3316,7 +3756,8 @@
Parameters
uint result - +

The deserialized uint, or 0 if failed.

+ @@ -3331,7 +3772,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3339,7 +3781,8 @@
Returns

TryGetULong(out ulong)

-
+

Attempts to read a ulong without throwing an exception.

+
Declaration
@@ -3358,7 +3801,8 @@
Parameters
ulong result - +

The deserialized ulong, or 0 if failed.

+ @@ -3373,7 +3817,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ @@ -3381,7 +3826,8 @@
Returns

TryGetUShort(out ushort)

-
+

Attempts to read a ushort without throwing an exception.

+
Declaration
@@ -3400,7 +3846,8 @@
Parameters
ushort result - +

The deserialized ushort, or 0 if failed.

+ @@ -3415,7 +3862,8 @@
Returns
bool - +

true if enough data was available; otherwise, false.

+ diff --git a/docs/api/LiteNetLib.Utils.NetDataWriter.html b/docs/api/LiteNetLib.Utils.NetDataWriter.html index c06d2e85..d24d1d4a 100644 --- a/docs/api/LiteNetLib.Utils.NetDataWriter.html +++ b/docs/api/LiteNetLib.Utils.NetDataWriter.html @@ -211,7 +211,8 @@

Properties

Capacity

-
+

Gets the total capacity of the internal byte buffer.

+
Declaration
@@ -228,7 +229,8 @@
Property Value
int - +

The length of the underlying _data array.

+ @@ -236,7 +238,8 @@
Property Value

Data

-
+

Gets the underlying byte array used by this writer.

+
Declaration
@@ -253,15 +256,20 @@
Property Value
byte[] - +

The internal _data array.

+ +
Remarks
+

Accessing this directly allows for external manipulation but bypasses bounds checking.

+

Length

-
+

Gets the current number of bytes written to the buffer.

+
Declaration
@@ -278,7 +286,8 @@
Property Value
int - +

The current _position.

+ @@ -288,7 +297,8 @@

Methods

AsReadOnlySpan()

-
+

Returns a ReadOnlySpan<T> representing the currently used portion of the internal buffer.

+
Declaration
@@ -305,15 +315,21 @@
Returns
ReadOnlySpan<byte> - +

A ReadOnlySpan<T> from index 0 to _position.

+ +
Remarks
+

Provides a high-performance, zero-allocation view of the data. +The span becomes invalid if the internal buffer is resized or if _position changes.

+

CopyData()

-
+

Creates a byte array containing the current data from the internal buffer.

+
Declaration
@@ -330,15 +346,20 @@
Returns
byte[] - +

A new byte array of length _position.

+ +
Remarks
+

This method performs a heap allocation and copies the data using BlockCopy(Array, int, Array, int, int).

+

EnsureFit(int)

-
+

Ensures the internal buffer can accommodate additionalSize more bytes.

+
Declaration
@@ -357,10 +378,15 @@
Parameters
int additionalSize - +

The number of additional bytes to fit.

+ +
Remarks
+

This checks against the current _position. If the capacity is insufficient, +the buffer grows to either the required size or doubles its current size.

+
@@ -514,7 +540,8 @@
Returns

FromString(string)

-
+

Creates a new NetDataWriter and serializes a string into it.

+
Declaration
@@ -533,7 +560,8 @@
Parameters
string value - +

The string to serialize.

+ @@ -548,7 +576,8 @@
Returns
NetDataWriter - +

A new NetDataWriter instance containing the serialized string.

+ @@ -556,7 +585,8 @@
Returns

Put(bool)

-
+

Serializes a bool value as a single byte.

+
Declaration
@@ -575,7 +605,8 @@
Parameters
bool value - +

The bool value to write.

+ @@ -583,7 +614,8 @@
Parameters

Put(byte)

-
+

Serializes a byte value.

+
Declaration
@@ -602,7 +634,8 @@
Parameters
byte value - +

The byte value to write.

+ @@ -610,7 +643,8 @@
Parameters

Put(byte[])

-
+

Serializes an entire byte array.

+
Declaration
@@ -629,7 +663,8 @@
Parameters
byte[] data - +

The source array.

+ @@ -637,7 +672,8 @@
Parameters

Put(byte[], int, int)

-
+

Serializes a segment of a byte array.

+
Declaration
@@ -656,17 +692,20 @@
Parameters
byte[] data - +

The source array.

+ int offset - +

The starting index in the source array.

+ int length - +

The number of bytes to write.

+ @@ -674,7 +713,8 @@
Parameters

Put(char)

-
+

Serializes a char value as a ushort.

+
Declaration
@@ -693,7 +733,8 @@
Parameters
char value - +

The char value to write.

+ @@ -701,7 +742,8 @@
Parameters

Put(double)

-
+

Serializes a double value.

+
Declaration
@@ -720,7 +762,8 @@
Parameters
double value - +

The double value to write.

+ @@ -728,7 +771,8 @@
Parameters

Put(Guid)

-
+

Serializes a Guid value.

+
Declaration
@@ -747,7 +791,8 @@
Parameters
Guid value - +

The Guid value to write.

+ @@ -755,7 +800,8 @@
Parameters

Put(short)

-
+

Serializes a short value.

+
Declaration
@@ -774,7 +820,8 @@
Parameters
short value - +

The short value to write.

+ @@ -782,7 +829,8 @@
Parameters

Put(int)

-
+

Serializes an int value.

+
Declaration
@@ -801,7 +849,8 @@
Parameters
int value - +

The int value to write.

+ @@ -809,7 +858,8 @@
Parameters

Put(long)

-
+

Serializes a long value.

+
Declaration
@@ -828,7 +878,8 @@
Parameters
long value - +

The long value to write.

+ @@ -836,7 +887,8 @@
Parameters

Put(IPEndPoint)

-
+

Serializes an IPEndPoint.

+
Declaration
@@ -855,7 +907,27 @@
Parameters
IPEndPoint endPoint - +

The network endpoint to write.

+ + + + +
Remarks
+

Writes a byte (0 for IPv4, 1 for IPv6), followed by the address bytes and a 2-byte ushort port.

+
+
Exceptions
+ + + + + + + + + + +
TypeCondition
ArgumentException

Thrown when the AddressFamily is not InterNetwork or InterNetworkV6.

+
@@ -863,7 +935,8 @@
Parameters

Put(ReadOnlySpan<byte>)

-
+

Serializes a ReadOnlySpan<T> of bytes to the internal buffer.

+
Declaration
@@ -882,7 +955,8 @@
Parameters
ReadOnlySpan<byte> data - +

The span of data to write.

+ @@ -890,7 +964,8 @@
Parameters

Put(sbyte)

-
+

Serializes an sbyte value.

+
Declaration
@@ -909,7 +984,8 @@
Parameters
sbyte value - +

The sbyte value to write.

+ @@ -917,7 +993,8 @@
Parameters

Put(float)

-
+

Serializes a float value.

+
Declaration
@@ -936,7 +1013,8 @@
Parameters
float value - +

The float value to write.

+ @@ -944,7 +1022,7 @@
Parameters

Put(string, int)

-

Note that "maxLength" only limits the number of characters in a string, not its size in bytes.

+

Serializes a string using a 2-byte float length header.

Declaration
@@ -964,20 +1042,28 @@
Parameters
string value - +

The string to write to the buffer.

+ int maxLength - +

The maximum number of characters to write. If the string is longer, it will be truncated.
+A value of 0 indicates no limit.

+ +
Remarks
+

Note that maxLength limits the number of characters, not the total size in bytes.
+Uses UTF8.

+

Put(ushort)

-
+

Serializes a ushort value.

+
Declaration
@@ -996,7 +1082,8 @@
Parameters
ushort value - +

The ushort value to write.

+ @@ -1004,7 +1091,8 @@
Parameters

Put(uint)

-
+

Serializes a uint value.

+
Declaration
@@ -1023,7 +1111,8 @@
Parameters
uint value - +

The uint value to write.

+ @@ -1031,7 +1120,8 @@
Parameters

Put(ulong)

-
+

Serializes a ulong value.

+
Declaration
@@ -1050,7 +1140,8 @@
Parameters
ulong value - +

The ulong value to write.

+ @@ -1058,7 +1149,8 @@
Parameters

PutArray(Array, int)

-
+

Serializes an Array prefixed with a 2-byte ushort length.

+
Declaration
@@ -1077,20 +1169,27 @@
Parameters
Array arr - +

The source array to serialize.

+ int sz - +

The size of a single element in bytes.

+ +
Remarks
+

If the array is null, a length of 0 is written.
+The total payload size is calculated as length * sz.

+

PutArray(bool[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1117,7 +1216,8 @@
Parameters

PutArray(double[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1144,7 +1244,8 @@
Parameters

PutArray(short[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1171,7 +1272,8 @@
Parameters

PutArray(int[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1198,7 +1300,8 @@
Parameters

PutArray(long[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1225,7 +1328,8 @@
Parameters

PutArray(float[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1252,7 +1356,8 @@
Parameters

PutArray(string[])

-
+

Serializes an array of string values.

+
Declaration
@@ -1271,15 +1376,20 @@
Parameters
string[] value - +

The array of string elements to write.

+ +
Remarks
+

Writes a 2-byte ushort length header followed by each string element.

+

PutArray(string[], int)

-
+

Serializes an array of string values with a maximum length constraint per element.

+
Declaration
@@ -1298,12 +1408,14 @@
Parameters
string[] value - +

The array of string elements to write.

+ int strMaxLength - +

The maximum allowed length for each individual string.

+ @@ -1311,7 +1423,8 @@
Parameters

PutArray(ushort[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1338,7 +1451,8 @@
Parameters

PutArray(uint[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1365,7 +1479,8 @@
Parameters

PutArray(ulong[])

-
+

Serializes an array of unmanaged values to the internal buffer.

+
Declaration
@@ -1392,7 +1507,8 @@
Parameters

PutArray<T>(T[])

-
+

Serializes an array of objects implementing INetSerializable.

+
Declaration
@@ -1411,7 +1527,8 @@
Parameters
T[] value - +

The array of objects to serialize.

+ @@ -1426,7 +1543,8 @@
Type Parameters
T - +

A type that implements INetSerializable and has a parameterless constructor.

+ @@ -1434,7 +1552,8 @@
Type Parameters

PutBytesWithLength(byte[])

-
+

Serializes a byte array prefixed with its ushort length.

+
Declaration
@@ -1453,7 +1572,8 @@
Parameters
byte[] data - +

The source array.

+ @@ -1461,7 +1581,8 @@
Parameters

PutBytesWithLength(byte[], int, ushort)

-
+

Serializes a segment of a byte array prefixed with its ushort length.

+
Declaration
@@ -1480,17 +1601,67 @@
Parameters
byte[] data - +

The source byte array.

+ int offset - +

The starting index in the source array.

+ ushort length - +

The number of bytes to write.

+ + + + + + + +

PutEnum<T>(T)

+

Writes an enum value of type T to the internal data buffer at the current position.
+Automatically resizes the buffer if LiteNetLib.Utils.NetDataWriter._autoResize is enabled. +Advances the position by the size of T.

+
+
+
Declaration
+
+
public void PutEnum<T>(T value) where T : unmanaged, Enum
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
Tvalue

The enum value to write.

+
+
Type Parameters
+ + + + + + + + + + +
NameDescription
T

An unmanaged enum type to write.

+
@@ -1498,7 +1669,8 @@
Parameters

PutLargeString(string)

-
+

Serializes a string using a 4-byte int length header.

+
Declaration
@@ -1517,7 +1689,60 @@
Parameters
string value - +

The string to write.

+ + + + +
Remarks
+

Recommended for strings that may exceed the 65535 byte limit of standard ushort length headers.
+Uses UTF8.

+
+ + + +

PutNullableUnmanaged<T>(T?)

+

Writes a nullable value of type T into the internal byte buffer at the current position, +first writing a bool indicating whether the value is present, +and then writing the value itself if it exists.
Advances the position by 1 byte for the presence flag plus +the size of T if the value is present.

+
+
+
Declaration
+
+
public void PutNullableUnmanaged<T>(T? value) where T : unmanaged
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
T?value

The nullable value to write into the buffer. If null, only a false flag is written.

+
+
Type Parameters
+ + + + + + + + + + +
NameDescription
T

An unmanaged value type to write into the buffer.

+
@@ -1525,7 +1750,8 @@
Parameters

PutSBytesWithLength(sbyte[])

-
+

Serializes an sbyte array prefixed with its ushort length.

+
Declaration
@@ -1544,7 +1770,8 @@
Parameters
sbyte[] data - +

The source array.

+ @@ -1552,7 +1779,8 @@
Parameters

PutSBytesWithLength(sbyte[], int, ushort)

-
+

Serializes a segment of an sbyte array prefixed with its ushort length.

+
Declaration
@@ -1571,17 +1799,159 @@
Parameters
sbyte[] data - +

The source sbyte array.

+ int offset - +

The starting index in the source array.

+ ushort length - +

The number of elements to write.

+ + + + + + + +

PutSpan<T>(Span<T>)

+

Serializes a Span<T> of unmanaged values to the internal buffer.

+
+
+
Declaration
+
+
public void PutSpan<T>(Span<T> span) where T : unmanaged
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
Span<T>span

The span of data to write.

+
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T

The unmanaged type of the span elements.

+
+
Remarks
+

Writes a 2-byte ushort length header followed by the raw binary data.

+
+ + + +

PutUnmanagedArray<T>(T[])

+

Serializes an array of unmanaged values.

+
+
+
Declaration
+
+
public void PutUnmanagedArray<T>(T[] arr) where T : unmanaged
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
T[]arr

The array to serialize.

+
+
Type Parameters
+ + + + + + + + + + + + + +
NameDescription
T

The unmanaged type of the array elements.

+
+ + + +

PutUnmanaged<T>(T)

+

Writes a value of type T into the internal byte buffer at the current position, +advancing the position by the size of T.

+
+
+
Declaration
+
+
public void PutUnmanaged<T>(T value) where T : unmanaged
+
+
Parameters
+ + + + + + + + + + + + + + + +
TypeNameDescription
Tvalue

The value to write into the buffer.

+
+
Type Parameters
+ + + + + + + + + + +
NameDescription
T

An unmanaged value type to write into the buffer.

+
@@ -1589,7 +1959,8 @@
Parameters

Put<T>(T)

-
+

Serializes an object implementing INetSerializable.

+
Declaration
@@ -1608,7 +1979,8 @@
Parameters
T obj - +

The object instance to serialize.

+ @@ -1623,15 +1995,20 @@
Type Parameters
T - +

A type that implements the INetSerializable interface.

+ +
Remarks
+

This method calls the Serialize(NetDataWriter) method on the provided obj.

+

Reset()

-
+

Resets the _position to 0, effectively clearing the buffer for reuse.

+
Declaration
@@ -1641,7 +2018,8 @@
Declaration

Reset(int)

-
+

Resets the _position to 0 and ensures the internal buffer has at least the specified size.

+
Declaration
@@ -1660,15 +2038,20 @@
Parameters
int size - +

The minimum capacity required for the internal buffer.

+ +
Remarks
+

If the current buffer is smaller than size, ResizeIfNeed(int) will allocate a larger byte array.

+

ResizeIfNeed(int)

-
+

Ensures the internal buffer is at least newSize.

+
Declaration
@@ -1687,10 +2070,15 @@
Parameters
int newSize - +

The required minimum size of the buffer.

+ +
Remarks
+

If an allocation is necessary, the buffer grows to either newSize +or doubles its current size, whichever is larger.

+
diff --git a/docs/api/LiteNetLib.html b/docs/api/LiteNetLib.html index 72a2a32b..842b779e 100644 --- a/docs/api/LiteNetLib.html +++ b/docs/api/LiteNetLib.html @@ -87,6 +87,8 @@

EventBasedNetLi

InvalidPacketException

+

LiteConnectionRequest

+

LiteNetManager

Main class for all network operations. Can be used as client and/or server.

@@ -96,6 +98,8 @@

LiteNetPeer

NatPunchModule

Module for UDP NAT Hole punching operations. Can be accessed from NetManager

+

NetConnectRequestPacket

+

NetConstants

Network constants. Can be tuned from sources for your purposes.

diff --git a/docs/api/toc.html b/docs/api/toc.html index ebd278b0..290589f2 100644 --- a/docs/api/toc.html +++ b/docs/api/toc.html @@ -56,6 +56,9 @@
  • InvalidPacketException
  • +
  • + LiteConnectionRequest +
  • LiteNetManager
  • @@ -74,6 +77,9 @@
  • NatPunchModule
  • +
  • + NetConnectRequestPacket +
  • NetConstants
  • diff --git a/docs/api/toc.json b/docs/api/toc.json index 82dcfb4e..17d2e194 100644 --- a/docs/api/toc.json +++ b/docs/api/toc.json @@ -1,2 +1,2 @@ -{"items":[{"name":"LiteNetLib","href":"LiteNetLib.html","topicHref":"LiteNetLib.html","topicUid":"LiteNetLib","type":"Namespace","items":[{"name":"ConnectionRequest","href":"LiteNetLib.ConnectionRequest.html","topicHref":"LiteNetLib.ConnectionRequest.html","topicUid":"LiteNetLib.ConnectionRequest","type":"Class"},{"name":"ConnectionState","href":"LiteNetLib.ConnectionState.html","topicHref":"LiteNetLib.ConnectionState.html","topicUid":"LiteNetLib.ConnectionState","type":"Enum"},{"name":"DeliveryMethod","href":"LiteNetLib.DeliveryMethod.html","topicHref":"LiteNetLib.DeliveryMethod.html","topicUid":"LiteNetLib.DeliveryMethod","type":"Enum"},{"name":"DisconnectInfo","href":"LiteNetLib.DisconnectInfo.html","topicHref":"LiteNetLib.DisconnectInfo.html","topicUid":"LiteNetLib.DisconnectInfo","type":"Struct"},{"name":"DisconnectReason","href":"LiteNetLib.DisconnectReason.html","topicHref":"LiteNetLib.DisconnectReason.html","topicUid":"LiteNetLib.DisconnectReason","type":"Enum"},{"name":"EventBasedLiteNetListener","href":"LiteNetLib.EventBasedLiteNetListener.html","topicHref":"LiteNetLib.EventBasedLiteNetListener.html","topicUid":"LiteNetLib.EventBasedLiteNetListener","type":"Class"},{"name":"EventBasedNatPunchListener","href":"LiteNetLib.EventBasedNatPunchListener.html","topicHref":"LiteNetLib.EventBasedNatPunchListener.html","topicUid":"LiteNetLib.EventBasedNatPunchListener","type":"Class"},{"name":"EventBasedNetListener","href":"LiteNetLib.EventBasedNetListener.html","topicHref":"LiteNetLib.EventBasedNetListener.html","topicUid":"LiteNetLib.EventBasedNetListener","type":"Class"},{"name":"ILiteNetEventListener","href":"LiteNetLib.ILiteNetEventListener.html","topicHref":"LiteNetLib.ILiteNetEventListener.html","topicUid":"LiteNetLib.ILiteNetEventListener","type":"Interface"},{"name":"INatPunchListener","href":"LiteNetLib.INatPunchListener.html","topicHref":"LiteNetLib.INatPunchListener.html","topicUid":"LiteNetLib.INatPunchListener","type":"Interface"},{"name":"INetEventListener","href":"LiteNetLib.INetEventListener.html","topicHref":"LiteNetLib.INetEventListener.html","topicUid":"LiteNetLib.INetEventListener","type":"Interface"},{"name":"INetLogger","href":"LiteNetLib.INetLogger.html","topicHref":"LiteNetLib.INetLogger.html","topicUid":"LiteNetLib.INetLogger","type":"Interface"},{"name":"InvalidPacketException","href":"LiteNetLib.InvalidPacketException.html","topicHref":"LiteNetLib.InvalidPacketException.html","topicUid":"LiteNetLib.InvalidPacketException","type":"Class"},{"name":"LiteNetManager","href":"LiteNetLib.LiteNetManager.html","topicHref":"LiteNetLib.LiteNetManager.html","topicUid":"LiteNetLib.LiteNetManager","type":"Class"},{"name":"LiteNetManager.NetPeerEnumerator","href":"LiteNetLib.LiteNetManager.NetPeerEnumerator-1.html","topicHref":"LiteNetLib.LiteNetManager.NetPeerEnumerator-1.html","topicUid":"LiteNetLib.LiteNetManager.NetPeerEnumerator`1","type":"Struct"},{"name":"LiteNetPeer","href":"LiteNetLib.LiteNetPeer.html","topicHref":"LiteNetLib.LiteNetPeer.html","topicUid":"LiteNetLib.LiteNetPeer","type":"Class"},{"name":"LocalAddrType","href":"LiteNetLib.LocalAddrType.html","topicHref":"LiteNetLib.LocalAddrType.html","topicUid":"LiteNetLib.LocalAddrType","type":"Enum"},{"name":"NatAddressType","href":"LiteNetLib.NatAddressType.html","topicHref":"LiteNetLib.NatAddressType.html","topicUid":"LiteNetLib.NatAddressType","type":"Enum"},{"name":"NatPunchModule","href":"LiteNetLib.NatPunchModule.html","topicHref":"LiteNetLib.NatPunchModule.html","topicUid":"LiteNetLib.NatPunchModule","type":"Class"},{"name":"NetConstants","href":"LiteNetLib.NetConstants.html","topicHref":"LiteNetLib.NetConstants.html","topicUid":"LiteNetLib.NetConstants","type":"Class"},{"name":"NetDebug","href":"LiteNetLib.NetDebug.html","topicHref":"LiteNetLib.NetDebug.html","topicUid":"LiteNetLib.NetDebug","type":"Class"},{"name":"NetEvent","href":"LiteNetLib.NetEvent.html","topicHref":"LiteNetLib.NetEvent.html","topicUid":"LiteNetLib.NetEvent","type":"Class"},{"name":"NetEvent.EType","href":"LiteNetLib.NetEvent.EType.html","topicHref":"LiteNetLib.NetEvent.EType.html","topicUid":"LiteNetLib.NetEvent.EType","type":"Enum"},{"name":"NetLogLevel","href":"LiteNetLib.NetLogLevel.html","topicHref":"LiteNetLib.NetLogLevel.html","topicUid":"LiteNetLib.NetLogLevel","type":"Enum"},{"name":"NetManager","href":"LiteNetLib.NetManager.html","topicHref":"LiteNetLib.NetManager.html","topicUid":"LiteNetLib.NetManager","type":"Class"},{"name":"NetPacketReader","href":"LiteNetLib.NetPacketReader.html","topicHref":"LiteNetLib.NetPacketReader.html","topicUid":"LiteNetLib.NetPacketReader","type":"Class"},{"name":"NetPeer","href":"LiteNetLib.NetPeer.html","topicHref":"LiteNetLib.NetPeer.html","topicUid":"LiteNetLib.NetPeer","type":"Class"},{"name":"NetStatistics","href":"LiteNetLib.NetStatistics.html","topicHref":"LiteNetLib.NetStatistics.html","topicUid":"LiteNetLib.NetStatistics","type":"Class"},{"name":"NetUtils","href":"LiteNetLib.NetUtils.html","topicHref":"LiteNetLib.NetUtils.html","topicUid":"LiteNetLib.NetUtils","type":"Class"},{"name":"PooledPacket","href":"LiteNetLib.PooledPacket.html","topicHref":"LiteNetLib.PooledPacket.html","topicUid":"LiteNetLib.PooledPacket","type":"Struct"},{"name":"TooBigPacketException","href":"LiteNetLib.TooBigPacketException.html","topicHref":"LiteNetLib.TooBigPacketException.html","topicUid":"LiteNetLib.TooBigPacketException","type":"Class"},{"name":"UnconnectedMessageType","href":"LiteNetLib.UnconnectedMessageType.html","topicHref":"LiteNetLib.UnconnectedMessageType.html","topicUid":"LiteNetLib.UnconnectedMessageType","type":"Enum"}]},{"name":"LiteNetLib.Layers","href":"LiteNetLib.Layers.html","topicHref":"LiteNetLib.Layers.html","topicUid":"LiteNetLib.Layers","type":"Namespace","items":[{"name":"Crc32cLayer","href":"LiteNetLib.Layers.Crc32cLayer.html","topicHref":"LiteNetLib.Layers.Crc32cLayer.html","topicUid":"LiteNetLib.Layers.Crc32cLayer","type":"Class"},{"name":"PacketLayerBase","href":"LiteNetLib.Layers.PacketLayerBase.html","topicHref":"LiteNetLib.Layers.PacketLayerBase.html","topicUid":"LiteNetLib.Layers.PacketLayerBase","type":"Class"},{"name":"XorEncryptLayer","href":"LiteNetLib.Layers.XorEncryptLayer.html","topicHref":"LiteNetLib.Layers.XorEncryptLayer.html","topicUid":"LiteNetLib.Layers.XorEncryptLayer","type":"Class"}]},{"name":"LiteNetLib.Utils","href":"LiteNetLib.Utils.html","topicHref":"LiteNetLib.Utils.html","topicUid":"LiteNetLib.Utils","type":"Namespace","items":[{"name":"CRC32C","href":"LiteNetLib.Utils.CRC32C.html","topicHref":"LiteNetLib.Utils.CRC32C.html","topicUid":"LiteNetLib.Utils.CRC32C","type":"Class"},{"name":"FastBitConverter","href":"LiteNetLib.Utils.FastBitConverter.html","topicHref":"LiteNetLib.Utils.FastBitConverter.html","topicUid":"LiteNetLib.Utils.FastBitConverter","type":"Class"},{"name":"INetSerializable","href":"LiteNetLib.Utils.INetSerializable.html","topicHref":"LiteNetLib.Utils.INetSerializable.html","topicUid":"LiteNetLib.Utils.INetSerializable","type":"Interface"},{"name":"InvalidTypeException","href":"LiteNetLib.Utils.InvalidTypeException.html","topicHref":"LiteNetLib.Utils.InvalidTypeException.html","topicUid":"LiteNetLib.Utils.InvalidTypeException","type":"Class"},{"name":"NetDataReader","href":"LiteNetLib.Utils.NetDataReader.html","topicHref":"LiteNetLib.Utils.NetDataReader.html","topicUid":"LiteNetLib.Utils.NetDataReader","type":"Class"},{"name":"NetDataWriter","href":"LiteNetLib.Utils.NetDataWriter.html","topicHref":"LiteNetLib.Utils.NetDataWriter.html","topicUid":"LiteNetLib.Utils.NetDataWriter","type":"Class"},{"name":"NetPacketProcessor","href":"LiteNetLib.Utils.NetPacketProcessor.html","topicHref":"LiteNetLib.Utils.NetPacketProcessor.html","topicUid":"LiteNetLib.Utils.NetPacketProcessor","type":"Class"},{"name":"NetSerializer","href":"LiteNetLib.Utils.NetSerializer.html","topicHref":"LiteNetLib.Utils.NetSerializer.html","topicUid":"LiteNetLib.Utils.NetSerializer","type":"Class"},{"name":"NtpLeapIndicator","href":"LiteNetLib.Utils.NtpLeapIndicator.html","topicHref":"LiteNetLib.Utils.NtpLeapIndicator.html","topicUid":"LiteNetLib.Utils.NtpLeapIndicator","type":"Enum"},{"name":"NtpMode","href":"LiteNetLib.Utils.NtpMode.html","topicHref":"LiteNetLib.Utils.NtpMode.html","topicUid":"LiteNetLib.Utils.NtpMode","type":"Enum"},{"name":"NtpPacket","href":"LiteNetLib.Utils.NtpPacket.html","topicHref":"LiteNetLib.Utils.NtpPacket.html","topicUid":"LiteNetLib.Utils.NtpPacket","type":"Class"},{"name":"ParseException","href":"LiteNetLib.Utils.ParseException.html","topicHref":"LiteNetLib.Utils.ParseException.html","topicUid":"LiteNetLib.Utils.ParseException","type":"Class"},{"name":"PreserveAttribute","href":"LiteNetLib.Utils.PreserveAttribute.html","topicHref":"LiteNetLib.Utils.PreserveAttribute.html","topicUid":"LiteNetLib.Utils.PreserveAttribute","type":"Class"}]}],"memberLayout":"SamePage"} +{"items":[{"name":"LiteNetLib","href":"LiteNetLib.html","topicHref":"LiteNetLib.html","topicUid":"LiteNetLib","type":"Namespace","items":[{"name":"ConnectionRequest","href":"LiteNetLib.ConnectionRequest.html","topicHref":"LiteNetLib.ConnectionRequest.html","topicUid":"LiteNetLib.ConnectionRequest","type":"Class"},{"name":"ConnectionState","href":"LiteNetLib.ConnectionState.html","topicHref":"LiteNetLib.ConnectionState.html","topicUid":"LiteNetLib.ConnectionState","type":"Enum"},{"name":"DeliveryMethod","href":"LiteNetLib.DeliveryMethod.html","topicHref":"LiteNetLib.DeliveryMethod.html","topicUid":"LiteNetLib.DeliveryMethod","type":"Enum"},{"name":"DisconnectInfo","href":"LiteNetLib.DisconnectInfo.html","topicHref":"LiteNetLib.DisconnectInfo.html","topicUid":"LiteNetLib.DisconnectInfo","type":"Struct"},{"name":"DisconnectReason","href":"LiteNetLib.DisconnectReason.html","topicHref":"LiteNetLib.DisconnectReason.html","topicUid":"LiteNetLib.DisconnectReason","type":"Enum"},{"name":"EventBasedLiteNetListener","href":"LiteNetLib.EventBasedLiteNetListener.html","topicHref":"LiteNetLib.EventBasedLiteNetListener.html","topicUid":"LiteNetLib.EventBasedLiteNetListener","type":"Class"},{"name":"EventBasedNatPunchListener","href":"LiteNetLib.EventBasedNatPunchListener.html","topicHref":"LiteNetLib.EventBasedNatPunchListener.html","topicUid":"LiteNetLib.EventBasedNatPunchListener","type":"Class"},{"name":"EventBasedNetListener","href":"LiteNetLib.EventBasedNetListener.html","topicHref":"LiteNetLib.EventBasedNetListener.html","topicUid":"LiteNetLib.EventBasedNetListener","type":"Class"},{"name":"ILiteNetEventListener","href":"LiteNetLib.ILiteNetEventListener.html","topicHref":"LiteNetLib.ILiteNetEventListener.html","topicUid":"LiteNetLib.ILiteNetEventListener","type":"Interface"},{"name":"INatPunchListener","href":"LiteNetLib.INatPunchListener.html","topicHref":"LiteNetLib.INatPunchListener.html","topicUid":"LiteNetLib.INatPunchListener","type":"Interface"},{"name":"INetEventListener","href":"LiteNetLib.INetEventListener.html","topicHref":"LiteNetLib.INetEventListener.html","topicUid":"LiteNetLib.INetEventListener","type":"Interface"},{"name":"INetLogger","href":"LiteNetLib.INetLogger.html","topicHref":"LiteNetLib.INetLogger.html","topicUid":"LiteNetLib.INetLogger","type":"Interface"},{"name":"InvalidPacketException","href":"LiteNetLib.InvalidPacketException.html","topicHref":"LiteNetLib.InvalidPacketException.html","topicUid":"LiteNetLib.InvalidPacketException","type":"Class"},{"name":"LiteConnectionRequest","href":"LiteNetLib.LiteConnectionRequest.html","topicHref":"LiteNetLib.LiteConnectionRequest.html","topicUid":"LiteNetLib.LiteConnectionRequest","type":"Class"},{"name":"LiteNetManager","href":"LiteNetLib.LiteNetManager.html","topicHref":"LiteNetLib.LiteNetManager.html","topicUid":"LiteNetLib.LiteNetManager","type":"Class"},{"name":"LiteNetManager.NetPeerEnumerator","href":"LiteNetLib.LiteNetManager.NetPeerEnumerator-1.html","topicHref":"LiteNetLib.LiteNetManager.NetPeerEnumerator-1.html","topicUid":"LiteNetLib.LiteNetManager.NetPeerEnumerator`1","type":"Struct"},{"name":"LiteNetPeer","href":"LiteNetLib.LiteNetPeer.html","topicHref":"LiteNetLib.LiteNetPeer.html","topicUid":"LiteNetLib.LiteNetPeer","type":"Class"},{"name":"LocalAddrType","href":"LiteNetLib.LocalAddrType.html","topicHref":"LiteNetLib.LocalAddrType.html","topicUid":"LiteNetLib.LocalAddrType","type":"Enum"},{"name":"NatAddressType","href":"LiteNetLib.NatAddressType.html","topicHref":"LiteNetLib.NatAddressType.html","topicUid":"LiteNetLib.NatAddressType","type":"Enum"},{"name":"NatPunchModule","href":"LiteNetLib.NatPunchModule.html","topicHref":"LiteNetLib.NatPunchModule.html","topicUid":"LiteNetLib.NatPunchModule","type":"Class"},{"name":"NetConnectRequestPacket","href":"LiteNetLib.NetConnectRequestPacket.html","topicHref":"LiteNetLib.NetConnectRequestPacket.html","topicUid":"LiteNetLib.NetConnectRequestPacket","type":"Class"},{"name":"NetConstants","href":"LiteNetLib.NetConstants.html","topicHref":"LiteNetLib.NetConstants.html","topicUid":"LiteNetLib.NetConstants","type":"Class"},{"name":"NetDebug","href":"LiteNetLib.NetDebug.html","topicHref":"LiteNetLib.NetDebug.html","topicUid":"LiteNetLib.NetDebug","type":"Class"},{"name":"NetEvent","href":"LiteNetLib.NetEvent.html","topicHref":"LiteNetLib.NetEvent.html","topicUid":"LiteNetLib.NetEvent","type":"Class"},{"name":"NetEvent.EType","href":"LiteNetLib.NetEvent.EType.html","topicHref":"LiteNetLib.NetEvent.EType.html","topicUid":"LiteNetLib.NetEvent.EType","type":"Enum"},{"name":"NetLogLevel","href":"LiteNetLib.NetLogLevel.html","topicHref":"LiteNetLib.NetLogLevel.html","topicUid":"LiteNetLib.NetLogLevel","type":"Enum"},{"name":"NetManager","href":"LiteNetLib.NetManager.html","topicHref":"LiteNetLib.NetManager.html","topicUid":"LiteNetLib.NetManager","type":"Class"},{"name":"NetPacketReader","href":"LiteNetLib.NetPacketReader.html","topicHref":"LiteNetLib.NetPacketReader.html","topicUid":"LiteNetLib.NetPacketReader","type":"Class"},{"name":"NetPeer","href":"LiteNetLib.NetPeer.html","topicHref":"LiteNetLib.NetPeer.html","topicUid":"LiteNetLib.NetPeer","type":"Class"},{"name":"NetStatistics","href":"LiteNetLib.NetStatistics.html","topicHref":"LiteNetLib.NetStatistics.html","topicUid":"LiteNetLib.NetStatistics","type":"Class"},{"name":"NetUtils","href":"LiteNetLib.NetUtils.html","topicHref":"LiteNetLib.NetUtils.html","topicUid":"LiteNetLib.NetUtils","type":"Class"},{"name":"PooledPacket","href":"LiteNetLib.PooledPacket.html","topicHref":"LiteNetLib.PooledPacket.html","topicUid":"LiteNetLib.PooledPacket","type":"Struct"},{"name":"TooBigPacketException","href":"LiteNetLib.TooBigPacketException.html","topicHref":"LiteNetLib.TooBigPacketException.html","topicUid":"LiteNetLib.TooBigPacketException","type":"Class"},{"name":"UnconnectedMessageType","href":"LiteNetLib.UnconnectedMessageType.html","topicHref":"LiteNetLib.UnconnectedMessageType.html","topicUid":"LiteNetLib.UnconnectedMessageType","type":"Enum"}]},{"name":"LiteNetLib.Layers","href":"LiteNetLib.Layers.html","topicHref":"LiteNetLib.Layers.html","topicUid":"LiteNetLib.Layers","type":"Namespace","items":[{"name":"Crc32cLayer","href":"LiteNetLib.Layers.Crc32cLayer.html","topicHref":"LiteNetLib.Layers.Crc32cLayer.html","topicUid":"LiteNetLib.Layers.Crc32cLayer","type":"Class"},{"name":"PacketLayerBase","href":"LiteNetLib.Layers.PacketLayerBase.html","topicHref":"LiteNetLib.Layers.PacketLayerBase.html","topicUid":"LiteNetLib.Layers.PacketLayerBase","type":"Class"},{"name":"XorEncryptLayer","href":"LiteNetLib.Layers.XorEncryptLayer.html","topicHref":"LiteNetLib.Layers.XorEncryptLayer.html","topicUid":"LiteNetLib.Layers.XorEncryptLayer","type":"Class"}]},{"name":"LiteNetLib.Utils","href":"LiteNetLib.Utils.html","topicHref":"LiteNetLib.Utils.html","topicUid":"LiteNetLib.Utils","type":"Namespace","items":[{"name":"CRC32C","href":"LiteNetLib.Utils.CRC32C.html","topicHref":"LiteNetLib.Utils.CRC32C.html","topicUid":"LiteNetLib.Utils.CRC32C","type":"Class"},{"name":"FastBitConverter","href":"LiteNetLib.Utils.FastBitConverter.html","topicHref":"LiteNetLib.Utils.FastBitConverter.html","topicUid":"LiteNetLib.Utils.FastBitConverter","type":"Class"},{"name":"INetSerializable","href":"LiteNetLib.Utils.INetSerializable.html","topicHref":"LiteNetLib.Utils.INetSerializable.html","topicUid":"LiteNetLib.Utils.INetSerializable","type":"Interface"},{"name":"InvalidTypeException","href":"LiteNetLib.Utils.InvalidTypeException.html","topicHref":"LiteNetLib.Utils.InvalidTypeException.html","topicUid":"LiteNetLib.Utils.InvalidTypeException","type":"Class"},{"name":"NetDataReader","href":"LiteNetLib.Utils.NetDataReader.html","topicHref":"LiteNetLib.Utils.NetDataReader.html","topicUid":"LiteNetLib.Utils.NetDataReader","type":"Class"},{"name":"NetDataWriter","href":"LiteNetLib.Utils.NetDataWriter.html","topicHref":"LiteNetLib.Utils.NetDataWriter.html","topicUid":"LiteNetLib.Utils.NetDataWriter","type":"Class"},{"name":"NetPacketProcessor","href":"LiteNetLib.Utils.NetPacketProcessor.html","topicHref":"LiteNetLib.Utils.NetPacketProcessor.html","topicUid":"LiteNetLib.Utils.NetPacketProcessor","type":"Class"},{"name":"NetSerializer","href":"LiteNetLib.Utils.NetSerializer.html","topicHref":"LiteNetLib.Utils.NetSerializer.html","topicUid":"LiteNetLib.Utils.NetSerializer","type":"Class"},{"name":"NtpLeapIndicator","href":"LiteNetLib.Utils.NtpLeapIndicator.html","topicHref":"LiteNetLib.Utils.NtpLeapIndicator.html","topicUid":"LiteNetLib.Utils.NtpLeapIndicator","type":"Enum"},{"name":"NtpMode","href":"LiteNetLib.Utils.NtpMode.html","topicHref":"LiteNetLib.Utils.NtpMode.html","topicUid":"LiteNetLib.Utils.NtpMode","type":"Enum"},{"name":"NtpPacket","href":"LiteNetLib.Utils.NtpPacket.html","topicHref":"LiteNetLib.Utils.NtpPacket.html","topicUid":"LiteNetLib.Utils.NtpPacket","type":"Class"},{"name":"ParseException","href":"LiteNetLib.Utils.ParseException.html","topicHref":"LiteNetLib.Utils.ParseException.html","topicUid":"LiteNetLib.Utils.ParseException","type":"Class"},{"name":"PreserveAttribute","href":"LiteNetLib.Utils.PreserveAttribute.html","topicHref":"LiteNetLib.Utils.PreserveAttribute.html","topicUid":"LiteNetLib.Utils.PreserveAttribute","type":"Class"}]}],"memberLayout":"SamePage"} diff --git a/docs/manifest.json b/docs/manifest.json index a4b3519d..09864182 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -240,6 +240,20 @@ "Title": "LiteNetLib.Layers", "Summary": null }, + { + "type": "ManagedReference", + "source_relative_path": "api/LiteNetLib.LiteConnectionRequest.yml", + "output": { + ".html": { + "relative_path": "api/LiteNetLib.LiteConnectionRequest.html" + } + }, + "version": "", + "Uid": null, + "IsMRef": true, + "Title": "LiteNetLib.LiteConnectionRequest", + "Summary": null + }, { "type": "ManagedReference", "source_relative_path": "api/LiteNetLib.LiteNetManager.NetPeerEnumerator-1.yml", @@ -338,6 +352,20 @@ "Title": "LiteNetLib.NatPunchModule", "Summary": "

    Module for UDP NAT Hole punching operations. Can be accessed from NetManager

    \n" }, + { + "type": "ManagedReference", + "source_relative_path": "api/LiteNetLib.NetConnectRequestPacket.yml", + "output": { + ".html": { + "relative_path": "api/LiteNetLib.NetConnectRequestPacket.html" + } + }, + "version": "", + "Uid": null, + "IsMRef": true, + "Title": "LiteNetLib.NetConnectRequestPacket", + "Summary": null + }, { "type": "ManagedReference", "source_relative_path": "api/LiteNetLib.NetConstants.yml", diff --git a/docs/xrefmap.yml b/docs/xrefmap.yml index 5968b31b..c0c86392 100644 --- a/docs/xrefmap.yml +++ b/docs/xrefmap.yml @@ -42,108 +42,6 @@ references: isSpec: "True" fullName: LiteNetLib.ConnectionRequest.AcceptIfKey nameWithType: ConnectionRequest.AcceptIfKey -- uid: LiteNetLib.ConnectionRequest.Data - name: Data - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_Data - commentId: P:LiteNetLib.ConnectionRequest.Data - fullName: LiteNetLib.ConnectionRequest.Data - nameWithType: ConnectionRequest.Data -- uid: LiteNetLib.ConnectionRequest.Data* - name: Data - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_Data_ - commentId: Overload:LiteNetLib.ConnectionRequest.Data - isSpec: "True" - fullName: LiteNetLib.ConnectionRequest.Data - nameWithType: ConnectionRequest.Data -- uid: LiteNetLib.ConnectionRequest.Reject - name: Reject() - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_Reject - commentId: M:LiteNetLib.ConnectionRequest.Reject - fullName: LiteNetLib.ConnectionRequest.Reject() - nameWithType: ConnectionRequest.Reject() -- uid: LiteNetLib.ConnectionRequest.Reject(LiteNetLib.Utils.NetDataWriter) - name: Reject(NetDataWriter) - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_Reject_LiteNetLib_Utils_NetDataWriter_ - commentId: M:LiteNetLib.ConnectionRequest.Reject(LiteNetLib.Utils.NetDataWriter) - fullName: LiteNetLib.ConnectionRequest.Reject(LiteNetLib.Utils.NetDataWriter) - nameWithType: ConnectionRequest.Reject(NetDataWriter) -- uid: LiteNetLib.ConnectionRequest.Reject(System.Byte[]) - name: Reject(byte[]) - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_Reject_System_Byte___ - commentId: M:LiteNetLib.ConnectionRequest.Reject(System.Byte[]) - name.vb: Reject(Byte()) - fullName: LiteNetLib.ConnectionRequest.Reject(byte[]) - fullName.vb: LiteNetLib.ConnectionRequest.Reject(Byte()) - nameWithType: ConnectionRequest.Reject(byte[]) - nameWithType.vb: ConnectionRequest.Reject(Byte()) -- uid: LiteNetLib.ConnectionRequest.Reject(System.Byte[],System.Int32,System.Int32) - name: Reject(byte[], int, int) - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_Reject_System_Byte___System_Int32_System_Int32_ - commentId: M:LiteNetLib.ConnectionRequest.Reject(System.Byte[],System.Int32,System.Int32) - name.vb: Reject(Byte(), Integer, Integer) - fullName: LiteNetLib.ConnectionRequest.Reject(byte[], int, int) - fullName.vb: LiteNetLib.ConnectionRequest.Reject(Byte(), Integer, Integer) - nameWithType: ConnectionRequest.Reject(byte[], int, int) - nameWithType.vb: ConnectionRequest.Reject(Byte(), Integer, Integer) -- uid: LiteNetLib.ConnectionRequest.Reject(System.Byte[],System.Int32,System.Int32,System.Boolean) - name: Reject(byte[], int, int, bool) - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_Reject_System_Byte___System_Int32_System_Int32_System_Boolean_ - commentId: M:LiteNetLib.ConnectionRequest.Reject(System.Byte[],System.Int32,System.Int32,System.Boolean) - name.vb: Reject(Byte(), Integer, Integer, Boolean) - fullName: LiteNetLib.ConnectionRequest.Reject(byte[], int, int, bool) - fullName.vb: LiteNetLib.ConnectionRequest.Reject(Byte(), Integer, Integer, Boolean) - nameWithType: ConnectionRequest.Reject(byte[], int, int, bool) - nameWithType.vb: ConnectionRequest.Reject(Byte(), Integer, Integer, Boolean) -- uid: LiteNetLib.ConnectionRequest.Reject* - name: Reject - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_Reject_ - commentId: Overload:LiteNetLib.ConnectionRequest.Reject - isSpec: "True" - fullName: LiteNetLib.ConnectionRequest.Reject - nameWithType: ConnectionRequest.Reject -- uid: LiteNetLib.ConnectionRequest.RejectForce - name: RejectForce() - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_RejectForce - commentId: M:LiteNetLib.ConnectionRequest.RejectForce - fullName: LiteNetLib.ConnectionRequest.RejectForce() - nameWithType: ConnectionRequest.RejectForce() -- uid: LiteNetLib.ConnectionRequest.RejectForce(LiteNetLib.Utils.NetDataWriter) - name: RejectForce(NetDataWriter) - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_RejectForce_LiteNetLib_Utils_NetDataWriter_ - commentId: M:LiteNetLib.ConnectionRequest.RejectForce(LiteNetLib.Utils.NetDataWriter) - fullName: LiteNetLib.ConnectionRequest.RejectForce(LiteNetLib.Utils.NetDataWriter) - nameWithType: ConnectionRequest.RejectForce(NetDataWriter) -- uid: LiteNetLib.ConnectionRequest.RejectForce(System.Byte[]) - name: RejectForce(byte[]) - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_RejectForce_System_Byte___ - commentId: M:LiteNetLib.ConnectionRequest.RejectForce(System.Byte[]) - name.vb: RejectForce(Byte()) - fullName: LiteNetLib.ConnectionRequest.RejectForce(byte[]) - fullName.vb: LiteNetLib.ConnectionRequest.RejectForce(Byte()) - nameWithType: ConnectionRequest.RejectForce(byte[]) - nameWithType.vb: ConnectionRequest.RejectForce(Byte()) -- uid: LiteNetLib.ConnectionRequest.RejectForce(System.Byte[],System.Int32,System.Int32) - name: RejectForce(byte[], int, int) - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_RejectForce_System_Byte___System_Int32_System_Int32_ - commentId: M:LiteNetLib.ConnectionRequest.RejectForce(System.Byte[],System.Int32,System.Int32) - name.vb: RejectForce(Byte(), Integer, Integer) - fullName: LiteNetLib.ConnectionRequest.RejectForce(byte[], int, int) - fullName.vb: LiteNetLib.ConnectionRequest.RejectForce(Byte(), Integer, Integer) - nameWithType: ConnectionRequest.RejectForce(byte[], int, int) - nameWithType.vb: ConnectionRequest.RejectForce(Byte(), Integer, Integer) -- uid: LiteNetLib.ConnectionRequest.RejectForce* - name: RejectForce - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_RejectForce_ - commentId: Overload:LiteNetLib.ConnectionRequest.RejectForce - isSpec: "True" - fullName: LiteNetLib.ConnectionRequest.RejectForce - nameWithType: ConnectionRequest.RejectForce -- uid: LiteNetLib.ConnectionRequest.RemoteEndPoint - name: RemoteEndPoint - href: api/LiteNetLib.ConnectionRequest.html#LiteNetLib_ConnectionRequest_RemoteEndPoint - commentId: F:LiteNetLib.ConnectionRequest.RemoteEndPoint - fullName: LiteNetLib.ConnectionRequest.RemoteEndPoint - nameWithType: ConnectionRequest.RemoteEndPoint - uid: LiteNetLib.ConnectionState name: ConnectionState href: api/LiteNetLib.ConnectionState.html @@ -721,12 +619,12 @@ references: commentId: T:LiteNetLib.ILiteNetEventListener fullName: LiteNetLib.ILiteNetEventListener nameWithType: ILiteNetEventListener -- uid: LiteNetLib.ILiteNetEventListener.OnConnectionRequest(LiteNetLib.ConnectionRequest) - name: OnConnectionRequest(ConnectionRequest) - href: api/LiteNetLib.ILiteNetEventListener.html#LiteNetLib_ILiteNetEventListener_OnConnectionRequest_LiteNetLib_ConnectionRequest_ - commentId: M:LiteNetLib.ILiteNetEventListener.OnConnectionRequest(LiteNetLib.ConnectionRequest) - fullName: LiteNetLib.ILiteNetEventListener.OnConnectionRequest(LiteNetLib.ConnectionRequest) - nameWithType: ILiteNetEventListener.OnConnectionRequest(ConnectionRequest) +- uid: LiteNetLib.ILiteNetEventListener.OnConnectionRequest(LiteNetLib.LiteConnectionRequest) + name: OnConnectionRequest(LiteConnectionRequest) + href: api/LiteNetLib.ILiteNetEventListener.html#LiteNetLib_ILiteNetEventListener_OnConnectionRequest_LiteNetLib_LiteConnectionRequest_ + commentId: M:LiteNetLib.ILiteNetEventListener.OnConnectionRequest(LiteNetLib.LiteConnectionRequest) + fullName: LiteNetLib.ILiteNetEventListener.OnConnectionRequest(LiteNetLib.LiteConnectionRequest) + nameWithType: ILiteNetEventListener.OnConnectionRequest(LiteConnectionRequest) - uid: LiteNetLib.ILiteNetEventListener.OnConnectionRequest* name: OnConnectionRequest href: api/LiteNetLib.ILiteNetEventListener.html#LiteNetLib_ILiteNetEventListener_OnConnectionRequest_ @@ -1300,6 +1198,143 @@ references: isSpec: "True" fullName: LiteNetLib.Layers.XorEncryptLayer.SetKey nameWithType: XorEncryptLayer.SetKey +- uid: LiteNetLib.LiteConnectionRequest + name: LiteConnectionRequest + href: api/LiteNetLib.LiteConnectionRequest.html + commentId: T:LiteNetLib.LiteConnectionRequest + fullName: LiteNetLib.LiteConnectionRequest + nameWithType: LiteConnectionRequest +- uid: LiteNetLib.LiteConnectionRequest.Accept + name: Accept() + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Accept + commentId: M:LiteNetLib.LiteConnectionRequest.Accept + fullName: LiteNetLib.LiteConnectionRequest.Accept() + nameWithType: LiteConnectionRequest.Accept() +- uid: LiteNetLib.LiteConnectionRequest.Accept* + name: Accept + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Accept_ + commentId: Overload:LiteNetLib.LiteConnectionRequest.Accept + isSpec: "True" + fullName: LiteNetLib.LiteConnectionRequest.Accept + nameWithType: LiteConnectionRequest.Accept +- uid: LiteNetLib.LiteConnectionRequest.AcceptIfKey(System.String) + name: AcceptIfKey(string) + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_AcceptIfKey_System_String_ + commentId: M:LiteNetLib.LiteConnectionRequest.AcceptIfKey(System.String) + name.vb: AcceptIfKey(String) + fullName: LiteNetLib.LiteConnectionRequest.AcceptIfKey(string) + fullName.vb: LiteNetLib.LiteConnectionRequest.AcceptIfKey(String) + nameWithType: LiteConnectionRequest.AcceptIfKey(string) + nameWithType.vb: LiteConnectionRequest.AcceptIfKey(String) +- uid: LiteNetLib.LiteConnectionRequest.AcceptIfKey* + name: AcceptIfKey + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_AcceptIfKey_ + commentId: Overload:LiteNetLib.LiteConnectionRequest.AcceptIfKey + isSpec: "True" + fullName: LiteNetLib.LiteConnectionRequest.AcceptIfKey + nameWithType: LiteConnectionRequest.AcceptIfKey +- uid: LiteNetLib.LiteConnectionRequest.Data + name: Data + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Data + commentId: P:LiteNetLib.LiteConnectionRequest.Data + fullName: LiteNetLib.LiteConnectionRequest.Data + nameWithType: LiteConnectionRequest.Data +- uid: LiteNetLib.LiteConnectionRequest.Data* + name: Data + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Data_ + commentId: Overload:LiteNetLib.LiteConnectionRequest.Data + isSpec: "True" + fullName: LiteNetLib.LiteConnectionRequest.Data + nameWithType: LiteConnectionRequest.Data +- uid: LiteNetLib.LiteConnectionRequest.Reject + name: Reject() + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Reject + commentId: M:LiteNetLib.LiteConnectionRequest.Reject + fullName: LiteNetLib.LiteConnectionRequest.Reject() + nameWithType: LiteConnectionRequest.Reject() +- uid: LiteNetLib.LiteConnectionRequest.Reject(LiteNetLib.Utils.NetDataWriter) + name: Reject(NetDataWriter) + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Reject_LiteNetLib_Utils_NetDataWriter_ + commentId: M:LiteNetLib.LiteConnectionRequest.Reject(LiteNetLib.Utils.NetDataWriter) + fullName: LiteNetLib.LiteConnectionRequest.Reject(LiteNetLib.Utils.NetDataWriter) + nameWithType: LiteConnectionRequest.Reject(NetDataWriter) +- uid: LiteNetLib.LiteConnectionRequest.Reject(System.Byte[]) + name: Reject(byte[]) + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Reject_System_Byte___ + commentId: M:LiteNetLib.LiteConnectionRequest.Reject(System.Byte[]) + name.vb: Reject(Byte()) + fullName: LiteNetLib.LiteConnectionRequest.Reject(byte[]) + fullName.vb: LiteNetLib.LiteConnectionRequest.Reject(Byte()) + nameWithType: LiteConnectionRequest.Reject(byte[]) + nameWithType.vb: LiteConnectionRequest.Reject(Byte()) +- uid: LiteNetLib.LiteConnectionRequest.Reject(System.Byte[],System.Int32,System.Int32) + name: Reject(byte[], int, int) + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Reject_System_Byte___System_Int32_System_Int32_ + commentId: M:LiteNetLib.LiteConnectionRequest.Reject(System.Byte[],System.Int32,System.Int32) + name.vb: Reject(Byte(), Integer, Integer) + fullName: LiteNetLib.LiteConnectionRequest.Reject(byte[], int, int) + fullName.vb: LiteNetLib.LiteConnectionRequest.Reject(Byte(), Integer, Integer) + nameWithType: LiteConnectionRequest.Reject(byte[], int, int) + nameWithType.vb: LiteConnectionRequest.Reject(Byte(), Integer, Integer) +- uid: LiteNetLib.LiteConnectionRequest.Reject(System.Byte[],System.Int32,System.Int32,System.Boolean) + name: Reject(byte[], int, int, bool) + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Reject_System_Byte___System_Int32_System_Int32_System_Boolean_ + commentId: M:LiteNetLib.LiteConnectionRequest.Reject(System.Byte[],System.Int32,System.Int32,System.Boolean) + name.vb: Reject(Byte(), Integer, Integer, Boolean) + fullName: LiteNetLib.LiteConnectionRequest.Reject(byte[], int, int, bool) + fullName.vb: LiteNetLib.LiteConnectionRequest.Reject(Byte(), Integer, Integer, Boolean) + nameWithType: LiteConnectionRequest.Reject(byte[], int, int, bool) + nameWithType.vb: LiteConnectionRequest.Reject(Byte(), Integer, Integer, Boolean) +- uid: LiteNetLib.LiteConnectionRequest.Reject* + name: Reject + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_Reject_ + commentId: Overload:LiteNetLib.LiteConnectionRequest.Reject + isSpec: "True" + fullName: LiteNetLib.LiteConnectionRequest.Reject + nameWithType: LiteConnectionRequest.Reject +- uid: LiteNetLib.LiteConnectionRequest.RejectForce + name: RejectForce() + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_RejectForce + commentId: M:LiteNetLib.LiteConnectionRequest.RejectForce + fullName: LiteNetLib.LiteConnectionRequest.RejectForce() + nameWithType: LiteConnectionRequest.RejectForce() +- uid: LiteNetLib.LiteConnectionRequest.RejectForce(LiteNetLib.Utils.NetDataWriter) + name: RejectForce(NetDataWriter) + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_RejectForce_LiteNetLib_Utils_NetDataWriter_ + commentId: M:LiteNetLib.LiteConnectionRequest.RejectForce(LiteNetLib.Utils.NetDataWriter) + fullName: LiteNetLib.LiteConnectionRequest.RejectForce(LiteNetLib.Utils.NetDataWriter) + nameWithType: LiteConnectionRequest.RejectForce(NetDataWriter) +- uid: LiteNetLib.LiteConnectionRequest.RejectForce(System.Byte[]) + name: RejectForce(byte[]) + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_RejectForce_System_Byte___ + commentId: M:LiteNetLib.LiteConnectionRequest.RejectForce(System.Byte[]) + name.vb: RejectForce(Byte()) + fullName: LiteNetLib.LiteConnectionRequest.RejectForce(byte[]) + fullName.vb: LiteNetLib.LiteConnectionRequest.RejectForce(Byte()) + nameWithType: LiteConnectionRequest.RejectForce(byte[]) + nameWithType.vb: LiteConnectionRequest.RejectForce(Byte()) +- uid: LiteNetLib.LiteConnectionRequest.RejectForce(System.Byte[],System.Int32,System.Int32) + name: RejectForce(byte[], int, int) + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_RejectForce_System_Byte___System_Int32_System_Int32_ + commentId: M:LiteNetLib.LiteConnectionRequest.RejectForce(System.Byte[],System.Int32,System.Int32) + name.vb: RejectForce(Byte(), Integer, Integer) + fullName: LiteNetLib.LiteConnectionRequest.RejectForce(byte[], int, int) + fullName.vb: LiteNetLib.LiteConnectionRequest.RejectForce(Byte(), Integer, Integer) + nameWithType: LiteConnectionRequest.RejectForce(byte[], int, int) + nameWithType.vb: LiteConnectionRequest.RejectForce(Byte(), Integer, Integer) +- uid: LiteNetLib.LiteConnectionRequest.RejectForce* + name: RejectForce + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_RejectForce_ + commentId: Overload:LiteNetLib.LiteConnectionRequest.RejectForce + isSpec: "True" + fullName: LiteNetLib.LiteConnectionRequest.RejectForce + nameWithType: LiteConnectionRequest.RejectForce +- uid: LiteNetLib.LiteConnectionRequest.RemoteEndPoint + name: RemoteEndPoint + href: api/LiteNetLib.LiteConnectionRequest.html#LiteNetLib_LiteConnectionRequest_RemoteEndPoint + commentId: F:LiteNetLib.LiteConnectionRequest.RemoteEndPoint + fullName: LiteNetLib.LiteConnectionRequest.RemoteEndPoint + nameWithType: LiteConnectionRequest.RemoteEndPoint - uid: LiteNetLib.LiteNetManager name: LiteNetManager href: api/LiteNetLib.LiteNetManager.html @@ -1431,15 +1466,28 @@ references: isSpec: "True" fullName: LiteNetLib.LiteNetManager.ContainsPeer nameWithType: LiteNetManager.ContainsPeer -- uid: LiteNetLib.LiteNetManager.CreateIncomingPeer(LiteNetLib.ConnectionRequest,System.Int32) - name: CreateIncomingPeer(ConnectionRequest, int) - href: api/LiteNetLib.LiteNetManager.html#LiteNetLib_LiteNetManager_CreateIncomingPeer_LiteNetLib_ConnectionRequest_System_Int32_ - commentId: M:LiteNetLib.LiteNetManager.CreateIncomingPeer(LiteNetLib.ConnectionRequest,System.Int32) - name.vb: CreateIncomingPeer(ConnectionRequest, Integer) - fullName: LiteNetLib.LiteNetManager.CreateIncomingPeer(LiteNetLib.ConnectionRequest, int) - fullName.vb: LiteNetLib.LiteNetManager.CreateIncomingPeer(LiteNetLib.ConnectionRequest, Integer) - nameWithType: LiteNetManager.CreateIncomingPeer(ConnectionRequest, int) - nameWithType.vb: LiteNetManager.CreateIncomingPeer(ConnectionRequest, Integer) +- uid: LiteNetLib.LiteNetManager.CreateConnectionRequest(System.Net.IPEndPoint,LiteNetLib.NetConnectRequestPacket) + name: CreateConnectionRequest(IPEndPoint, NetConnectRequestPacket) + href: api/LiteNetLib.LiteNetManager.html#LiteNetLib_LiteNetManager_CreateConnectionRequest_System_Net_IPEndPoint_LiteNetLib_NetConnectRequestPacket_ + commentId: M:LiteNetLib.LiteNetManager.CreateConnectionRequest(System.Net.IPEndPoint,LiteNetLib.NetConnectRequestPacket) + fullName: LiteNetLib.LiteNetManager.CreateConnectionRequest(System.Net.IPEndPoint, LiteNetLib.NetConnectRequestPacket) + nameWithType: LiteNetManager.CreateConnectionRequest(IPEndPoint, NetConnectRequestPacket) +- uid: LiteNetLib.LiteNetManager.CreateConnectionRequest* + name: CreateConnectionRequest + href: api/LiteNetLib.LiteNetManager.html#LiteNetLib_LiteNetManager_CreateConnectionRequest_ + commentId: Overload:LiteNetLib.LiteNetManager.CreateConnectionRequest + isSpec: "True" + fullName: LiteNetLib.LiteNetManager.CreateConnectionRequest + nameWithType: LiteNetManager.CreateConnectionRequest +- uid: LiteNetLib.LiteNetManager.CreateIncomingPeer(LiteNetLib.LiteConnectionRequest,System.Int32) + name: CreateIncomingPeer(LiteConnectionRequest, int) + href: api/LiteNetLib.LiteNetManager.html#LiteNetLib_LiteNetManager_CreateIncomingPeer_LiteNetLib_LiteConnectionRequest_System_Int32_ + commentId: M:LiteNetLib.LiteNetManager.CreateIncomingPeer(LiteNetLib.LiteConnectionRequest,System.Int32) + name.vb: CreateIncomingPeer(LiteConnectionRequest, Integer) + fullName: LiteNetLib.LiteNetManager.CreateIncomingPeer(LiteNetLib.LiteConnectionRequest, int) + fullName.vb: LiteNetLib.LiteNetManager.CreateIncomingPeer(LiteNetLib.LiteConnectionRequest, Integer) + nameWithType: LiteNetManager.CreateIncomingPeer(LiteConnectionRequest, int) + nameWithType.vb: LiteNetManager.CreateIncomingPeer(LiteConnectionRequest, Integer) - uid: LiteNetLib.LiteNetManager.CreateIncomingPeer* name: CreateIncomingPeer href: api/LiteNetLib.LiteNetManager.html#LiteNetLib_LiteNetManager_CreateIncomingPeer_ @@ -2955,6 +3003,48 @@ references: commentId: F:LiteNetLib.NatPunchModule.UnsyncedEvents fullName: LiteNetLib.NatPunchModule.UnsyncedEvents nameWithType: NatPunchModule.UnsyncedEvents +- uid: LiteNetLib.NetConnectRequestPacket + name: NetConnectRequestPacket + href: api/LiteNetLib.NetConnectRequestPacket.html + commentId: T:LiteNetLib.NetConnectRequestPacket + fullName: LiteNetLib.NetConnectRequestPacket + nameWithType: NetConnectRequestPacket +- uid: LiteNetLib.NetConnectRequestPacket.ConnectionNumber + name: ConnectionNumber + href: api/LiteNetLib.NetConnectRequestPacket.html#LiteNetLib_NetConnectRequestPacket_ConnectionNumber + commentId: F:LiteNetLib.NetConnectRequestPacket.ConnectionNumber + fullName: LiteNetLib.NetConnectRequestPacket.ConnectionNumber + nameWithType: NetConnectRequestPacket.ConnectionNumber +- uid: LiteNetLib.NetConnectRequestPacket.ConnectionTime + name: ConnectionTime + href: api/LiteNetLib.NetConnectRequestPacket.html#LiteNetLib_NetConnectRequestPacket_ConnectionTime + commentId: F:LiteNetLib.NetConnectRequestPacket.ConnectionTime + fullName: LiteNetLib.NetConnectRequestPacket.ConnectionTime + nameWithType: NetConnectRequestPacket.ConnectionTime +- uid: LiteNetLib.NetConnectRequestPacket.Data + name: Data + href: api/LiteNetLib.NetConnectRequestPacket.html#LiteNetLib_NetConnectRequestPacket_Data + commentId: F:LiteNetLib.NetConnectRequestPacket.Data + fullName: LiteNetLib.NetConnectRequestPacket.Data + nameWithType: NetConnectRequestPacket.Data +- uid: LiteNetLib.NetConnectRequestPacket.HeaderSize + name: HeaderSize + href: api/LiteNetLib.NetConnectRequestPacket.html#LiteNetLib_NetConnectRequestPacket_HeaderSize + commentId: F:LiteNetLib.NetConnectRequestPacket.HeaderSize + fullName: LiteNetLib.NetConnectRequestPacket.HeaderSize + nameWithType: NetConnectRequestPacket.HeaderSize +- uid: LiteNetLib.NetConnectRequestPacket.PeerId + name: PeerId + href: api/LiteNetLib.NetConnectRequestPacket.html#LiteNetLib_NetConnectRequestPacket_PeerId + commentId: F:LiteNetLib.NetConnectRequestPacket.PeerId + fullName: LiteNetLib.NetConnectRequestPacket.PeerId + nameWithType: NetConnectRequestPacket.PeerId +- uid: LiteNetLib.NetConnectRequestPacket.TargetAddress + name: TargetAddress + href: api/LiteNetLib.NetConnectRequestPacket.html#LiteNetLib_NetConnectRequestPacket_TargetAddress + commentId: F:LiteNetLib.NetConnectRequestPacket.TargetAddress + fullName: LiteNetLib.NetConnectRequestPacket.TargetAddress + nameWithType: NetConnectRequestPacket.TargetAddress - uid: LiteNetLib.NetConstants name: NetConstants href: api/LiteNetLib.NetConstants.html @@ -3331,15 +3421,28 @@ references: isSpec: "True" fullName: LiteNetLib.NetManager.Connect nameWithType: NetManager.Connect -- uid: LiteNetLib.NetManager.CreateIncomingPeer(LiteNetLib.ConnectionRequest,System.Int32) - name: CreateIncomingPeer(ConnectionRequest, int) - href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_CreateIncomingPeer_LiteNetLib_ConnectionRequest_System_Int32_ - commentId: M:LiteNetLib.NetManager.CreateIncomingPeer(LiteNetLib.ConnectionRequest,System.Int32) - name.vb: CreateIncomingPeer(ConnectionRequest, Integer) - fullName: LiteNetLib.NetManager.CreateIncomingPeer(LiteNetLib.ConnectionRequest, int) - fullName.vb: LiteNetLib.NetManager.CreateIncomingPeer(LiteNetLib.ConnectionRequest, Integer) - nameWithType: NetManager.CreateIncomingPeer(ConnectionRequest, int) - nameWithType.vb: NetManager.CreateIncomingPeer(ConnectionRequest, Integer) +- uid: LiteNetLib.NetManager.CreateConnectionRequest(System.Net.IPEndPoint,LiteNetLib.NetConnectRequestPacket) + name: CreateConnectionRequest(IPEndPoint, NetConnectRequestPacket) + href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_CreateConnectionRequest_System_Net_IPEndPoint_LiteNetLib_NetConnectRequestPacket_ + commentId: M:LiteNetLib.NetManager.CreateConnectionRequest(System.Net.IPEndPoint,LiteNetLib.NetConnectRequestPacket) + fullName: LiteNetLib.NetManager.CreateConnectionRequest(System.Net.IPEndPoint, LiteNetLib.NetConnectRequestPacket) + nameWithType: NetManager.CreateConnectionRequest(IPEndPoint, NetConnectRequestPacket) +- uid: LiteNetLib.NetManager.CreateConnectionRequest* + name: CreateConnectionRequest + href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_CreateConnectionRequest_ + commentId: Overload:LiteNetLib.NetManager.CreateConnectionRequest + isSpec: "True" + fullName: LiteNetLib.NetManager.CreateConnectionRequest + nameWithType: NetManager.CreateConnectionRequest +- uid: LiteNetLib.NetManager.CreateIncomingPeer(LiteNetLib.LiteConnectionRequest,System.Int32) + name: CreateIncomingPeer(LiteConnectionRequest, int) + href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_CreateIncomingPeer_LiteNetLib_LiteConnectionRequest_System_Int32_ + commentId: M:LiteNetLib.NetManager.CreateIncomingPeer(LiteNetLib.LiteConnectionRequest,System.Int32) + name.vb: CreateIncomingPeer(LiteConnectionRequest, Integer) + fullName: LiteNetLib.NetManager.CreateIncomingPeer(LiteNetLib.LiteConnectionRequest, int) + fullName.vb: LiteNetLib.NetManager.CreateIncomingPeer(LiteNetLib.LiteConnectionRequest, Integer) + nameWithType: NetManager.CreateIncomingPeer(LiteConnectionRequest, int) + nameWithType.vb: NetManager.CreateIncomingPeer(LiteConnectionRequest, Integer) - uid: LiteNetLib.NetManager.CreateIncomingPeer* name: CreateIncomingPeer href: api/LiteNetLib.NetManager.html#LiteNetLib_NetManager_CreateIncomingPeer_ @@ -4601,6 +4704,22 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataReader.GetDoubleArray nameWithType: NetDataReader.GetDoubleArray +- uid: LiteNetLib.Utils.NetDataReader.GetEnum* + name: GetEnum + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetEnum_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.GetEnum + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.GetEnum + nameWithType: NetDataReader.GetEnum +- uid: LiteNetLib.Utils.NetDataReader.GetEnum``1 + name: GetEnum() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetEnum__1 + commentId: M:LiteNetLib.Utils.NetDataReader.GetEnum``1 + name.vb: GetEnum(Of T)() + fullName: LiteNetLib.Utils.NetDataReader.GetEnum() + fullName.vb: LiteNetLib.Utils.NetDataReader.GetEnum(Of T)() + nameWithType: NetDataReader.GetEnum() + nameWithType.vb: NetDataReader.GetEnum(Of T)() - uid: LiteNetLib.Utils.NetDataReader.GetFloat name: GetFloat() href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetFloat @@ -4718,6 +4837,22 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataReader.GetLongArray nameWithType: NetDataReader.GetLongArray +- uid: LiteNetLib.Utils.NetDataReader.GetNullableUnmanaged* + name: GetNullableUnmanaged + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetNullableUnmanaged_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.GetNullableUnmanaged + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.GetNullableUnmanaged + nameWithType: NetDataReader.GetNullableUnmanaged +- uid: LiteNetLib.Utils.NetDataReader.GetNullableUnmanaged``1 + name: GetNullableUnmanaged() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetNullableUnmanaged__1 + commentId: M:LiteNetLib.Utils.NetDataReader.GetNullableUnmanaged``1 + name.vb: GetNullableUnmanaged(Of T)() + fullName: LiteNetLib.Utils.NetDataReader.GetNullableUnmanaged() + fullName.vb: LiteNetLib.Utils.NetDataReader.GetNullableUnmanaged(Of T)() + nameWithType: NetDataReader.GetNullableUnmanaged() + nameWithType.vb: NetDataReader.GetNullableUnmanaged(Of T)() - uid: LiteNetLib.Utils.NetDataReader.GetRemainingBytes name: GetRemainingBytes() href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetRemainingBytes @@ -4944,6 +5079,38 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataReader.GetUShortArray nameWithType: NetDataReader.GetUShortArray +- uid: LiteNetLib.Utils.NetDataReader.GetUnmanaged* + name: GetUnmanaged + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetUnmanaged_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.GetUnmanaged + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.GetUnmanaged + nameWithType: NetDataReader.GetUnmanaged +- uid: LiteNetLib.Utils.NetDataReader.GetUnmanagedArray* + name: GetUnmanagedArray + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetUnmanagedArray_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.GetUnmanagedArray + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.GetUnmanagedArray + nameWithType: NetDataReader.GetUnmanagedArray +- uid: LiteNetLib.Utils.NetDataReader.GetUnmanagedArray``1 + name: GetUnmanagedArray() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetUnmanagedArray__1 + commentId: M:LiteNetLib.Utils.NetDataReader.GetUnmanagedArray``1 + name.vb: GetUnmanagedArray(Of T)() + fullName: LiteNetLib.Utils.NetDataReader.GetUnmanagedArray() + fullName.vb: LiteNetLib.Utils.NetDataReader.GetUnmanagedArray(Of T)() + nameWithType: NetDataReader.GetUnmanagedArray() + nameWithType.vb: NetDataReader.GetUnmanagedArray(Of T)() +- uid: LiteNetLib.Utils.NetDataReader.GetUnmanaged``1 + name: GetUnmanaged() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_GetUnmanaged__1 + commentId: M:LiteNetLib.Utils.NetDataReader.GetUnmanaged``1 + name.vb: GetUnmanaged(Of T)() + fullName: LiteNetLib.Utils.NetDataReader.GetUnmanaged() + fullName.vb: LiteNetLib.Utils.NetDataReader.GetUnmanaged(Of T)() + nameWithType: NetDataReader.GetUnmanaged() + nameWithType.vb: NetDataReader.GetUnmanaged(Of T)() - uid: LiteNetLib.Utils.NetDataReader.Get``1 name: Get() href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Get__1 @@ -5171,6 +5338,22 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataReader.PeekUShort nameWithType: NetDataReader.PeekUShort +- uid: LiteNetLib.Utils.NetDataReader.PeekUnmanaged* + name: PeekUnmanaged + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekUnmanaged_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.PeekUnmanaged + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.PeekUnmanaged + nameWithType: NetDataReader.PeekUnmanaged +- uid: LiteNetLib.Utils.NetDataReader.PeekUnmanaged``1 + name: PeekUnmanaged() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekUnmanaged__1 + commentId: M:LiteNetLib.Utils.NetDataReader.PeekUnmanaged``1 + name.vb: PeekUnmanaged(Of T)() + fullName: LiteNetLib.Utils.NetDataReader.PeekUnmanaged() + fullName.vb: LiteNetLib.Utils.NetDataReader.PeekUnmanaged(Of T)() + nameWithType: NetDataReader.PeekUnmanaged() + nameWithType.vb: NetDataReader.PeekUnmanaged(Of T)() - uid: LiteNetLib.Utils.NetDataReader.Position name: Position href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_Position @@ -6049,6 +6232,22 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataWriter.PutBytesWithLength nameWithType: NetDataWriter.PutBytesWithLength +- uid: LiteNetLib.Utils.NetDataWriter.PutEnum* + name: PutEnum + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutEnum_ + commentId: Overload:LiteNetLib.Utils.NetDataWriter.PutEnum + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataWriter.PutEnum + nameWithType: NetDataWriter.PutEnum +- uid: LiteNetLib.Utils.NetDataWriter.PutEnum``1(``0) + name: PutEnum(T) + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutEnum__1___0_ + commentId: M:LiteNetLib.Utils.NetDataWriter.PutEnum``1(``0) + name.vb: PutEnum(Of T)(T) + fullName: LiteNetLib.Utils.NetDataWriter.PutEnum(T) + fullName.vb: LiteNetLib.Utils.NetDataWriter.PutEnum(Of T)(T) + nameWithType: NetDataWriter.PutEnum(T) + nameWithType.vb: NetDataWriter.PutEnum(Of T)(T) - uid: LiteNetLib.Utils.NetDataWriter.PutLargeString(System.String) name: PutLargeString(string) href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutLargeString_System_String_ @@ -6065,6 +6264,22 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataWriter.PutLargeString nameWithType: NetDataWriter.PutLargeString +- uid: LiteNetLib.Utils.NetDataWriter.PutNullableUnmanaged* + name: PutNullableUnmanaged + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutNullableUnmanaged_ + commentId: Overload:LiteNetLib.Utils.NetDataWriter.PutNullableUnmanaged + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataWriter.PutNullableUnmanaged + nameWithType: NetDataWriter.PutNullableUnmanaged +- uid: LiteNetLib.Utils.NetDataWriter.PutNullableUnmanaged``1(System.Nullable{``0}) + name: PutNullableUnmanaged(T?) + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutNullableUnmanaged__1_System_Nullable___0__ + commentId: M:LiteNetLib.Utils.NetDataWriter.PutNullableUnmanaged``1(System.Nullable{``0}) + name.vb: PutNullableUnmanaged(Of T)(T?) + fullName: LiteNetLib.Utils.NetDataWriter.PutNullableUnmanaged(T?) + fullName.vb: LiteNetLib.Utils.NetDataWriter.PutNullableUnmanaged(Of T)(T?) + nameWithType: NetDataWriter.PutNullableUnmanaged(T?) + nameWithType.vb: NetDataWriter.PutNullableUnmanaged(Of T)(T?) - uid: LiteNetLib.Utils.NetDataWriter.PutSBytesWithLength(System.SByte[]) name: PutSBytesWithLength(sbyte[]) href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutSBytesWithLength_System_SByte___ @@ -6090,6 +6305,54 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataWriter.PutSBytesWithLength nameWithType: NetDataWriter.PutSBytesWithLength +- uid: LiteNetLib.Utils.NetDataWriter.PutSpan* + name: PutSpan + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutSpan_ + commentId: Overload:LiteNetLib.Utils.NetDataWriter.PutSpan + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataWriter.PutSpan + nameWithType: NetDataWriter.PutSpan +- uid: LiteNetLib.Utils.NetDataWriter.PutSpan``1(System.Span{``0}) + name: PutSpan(Span) + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutSpan__1_System_Span___0__ + commentId: M:LiteNetLib.Utils.NetDataWriter.PutSpan``1(System.Span{``0}) + name.vb: PutSpan(Of T)(Span(Of T)) + fullName: LiteNetLib.Utils.NetDataWriter.PutSpan(System.Span) + fullName.vb: LiteNetLib.Utils.NetDataWriter.PutSpan(Of T)(System.Span(Of T)) + nameWithType: NetDataWriter.PutSpan(Span) + nameWithType.vb: NetDataWriter.PutSpan(Of T)(Span(Of T)) +- uid: LiteNetLib.Utils.NetDataWriter.PutUnmanaged* + name: PutUnmanaged + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutUnmanaged_ + commentId: Overload:LiteNetLib.Utils.NetDataWriter.PutUnmanaged + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataWriter.PutUnmanaged + nameWithType: NetDataWriter.PutUnmanaged +- uid: LiteNetLib.Utils.NetDataWriter.PutUnmanagedArray* + name: PutUnmanagedArray + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutUnmanagedArray_ + commentId: Overload:LiteNetLib.Utils.NetDataWriter.PutUnmanagedArray + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataWriter.PutUnmanagedArray + nameWithType: NetDataWriter.PutUnmanagedArray +- uid: LiteNetLib.Utils.NetDataWriter.PutUnmanagedArray``1(``0[]) + name: PutUnmanagedArray(T[]) + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutUnmanagedArray__1___0___ + commentId: M:LiteNetLib.Utils.NetDataWriter.PutUnmanagedArray``1(``0[]) + name.vb: PutUnmanagedArray(Of T)(T()) + fullName: LiteNetLib.Utils.NetDataWriter.PutUnmanagedArray(T[]) + fullName.vb: LiteNetLib.Utils.NetDataWriter.PutUnmanagedArray(Of T)(T()) + nameWithType: NetDataWriter.PutUnmanagedArray(T[]) + nameWithType.vb: NetDataWriter.PutUnmanagedArray(Of T)(T()) +- uid: LiteNetLib.Utils.NetDataWriter.PutUnmanaged``1(``0) + name: PutUnmanaged(T) + href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_PutUnmanaged__1___0_ + commentId: M:LiteNetLib.Utils.NetDataWriter.PutUnmanaged``1(``0) + name.vb: PutUnmanaged(Of T)(T) + fullName: LiteNetLib.Utils.NetDataWriter.PutUnmanaged(T) + fullName.vb: LiteNetLib.Utils.NetDataWriter.PutUnmanaged(Of T)(T) + nameWithType: NetDataWriter.PutUnmanaged(T) + nameWithType.vb: NetDataWriter.PutUnmanaged(Of T)(T) - uid: LiteNetLib.Utils.NetDataWriter.Put``1(``0) name: Put(T) href: api/LiteNetLib.Utils.NetDataWriter.html#LiteNetLib_Utils_NetDataWriter_Put__1___0_ From 982517e4516377cc87276f0c2780eb32f98a275d Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Sun, 22 Mar 2026 13:27:31 +0200 Subject: [PATCH 193/261] Disable push trigger for NuGet publish workflow Removed automatic push trigger for master branch. --- .github/workflows/nuget-publish.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/nuget-publish.yml b/.github/workflows/nuget-publish.yml index afe7e34b..a963bc33 100644 --- a/.github/workflows/nuget-publish.yml +++ b/.github/workflows/nuget-publish.yml @@ -1,8 +1,6 @@ name: Publish NuGet Package on: - push: - branches: [ master ] workflow_dispatch: jobs: From bf93dc473453c8b2f81fd8c5736ed5548f71ef66 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Sun, 22 Mar 2026 17:46:47 +0200 Subject: [PATCH 194/261] set position to _dataSize in all GetRemainingBytes methods --- LiteNetLib/Utils/NetDataReader.cs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index fcf3ee04..114dd25f 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -558,16 +558,24 @@ public T Get(Func constructor) where T : class, INetSerializable /// /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlySpan GetRemainingBytesSpan() => - new ReadOnlySpan(_data, _position, _dataSize - _position); + public ReadOnlySpan GetRemainingBytesSpan() + { + var result = new ReadOnlySpan(_data, _position, _dataSize - _position); + _position = _dataSize; + return result; + } /// /// Returns a of s containing all remaining data. /// /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlyMemory GetRemainingBytesMemory() => - new ReadOnlyMemory(_data, _position, _dataSize - _position); + public ReadOnlyMemory GetRemainingBytesMemory() + { + var result = new ReadOnlyMemory(_data, _position, _dataSize - _position); + _position = _dataSize; + return result; + } /// /// Reads all remaining s and returns them as a new array. @@ -578,8 +586,9 @@ public ReadOnlyMemory GetRemainingBytesMemory() => /// public byte[] GetRemainingBytes() { - byte[] outgoingData = new byte[AvailableBytes]; - Buffer.BlockCopy(_data, _position, outgoingData, 0, AvailableBytes); + int size = _dataSize - _position; + byte[] outgoingData = new byte[size]; + Buffer.BlockCopy(_data, _position, outgoingData, 0, size); _position = _dataSize; return outgoingData; } From 8d69673f5e1635db88cbf0f0cd1003e5ce6d8249 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:57:37 +0100 Subject: [PATCH 195/261] Fix compile error --- LiteNetLib/Utils/NetDataReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 114dd25f..a93114fa 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -778,7 +778,7 @@ public string PeekString() /// An unmanaged value type. /// The value read from the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T PeekUnmanaged() where T : unmanaged + public unsafe T PeekUnmanaged() where T : unmanaged { #if NET8_0_OR_GREATER return Unsafe.ReadUnaligned(ref _data[_position]); From a3e78276d6d377df7e5a1e1eeef435ba16abc0fa Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Sun, 22 Mar 2026 20:58:37 +0100 Subject: [PATCH 196/261] Remove allocations from Put IPEndPoint --- LiteNetLib/Utils/NetDataWriter.cs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 5c00a6e4..18a9fc6a 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -511,20 +511,35 @@ public void PutArray(string[] value, int strMaxLength) /// public void Put(IPEndPoint endPoint) { + int addressSize; + byte familyFlag; + if (endPoint.AddressFamily == AddressFamily.InterNetwork) { - Put((byte)0); + addressSize = 4; + familyFlag = 0; } else if (endPoint.AddressFamily == AddressFamily.InterNetworkV6) { - Put((byte)1); + addressSize = 16; + familyFlag = 1; } else { - throw new ArgumentException("Unsupported address family: " + endPoint.AddressFamily); + throw new ArgumentException($"Unsupported address family: {endPoint.AddressFamily}"); } - Put(endPoint.Address.GetAddressBytes()); + if (_autoResize) + ResizeIfNeed(_position + 1 + addressSize + 2); + + _data[_position++] = familyFlag; + + Span destination = _data.AsSpan(_position, addressSize); + if (!endPoint.Address.TryWriteBytes(destination, out int written)) + throw new ArgumentException("Failed to write IP bytes."); + + _position += written; + Put((ushort)endPoint.Port); } From 38dfa86b217062dcb290c290a14c82ccb7a9a43b Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Mon, 23 Mar 2026 10:23:23 +0100 Subject: [PATCH 197/261] Update docs --- LiteNetLib/ConnectionRequest.cs | 2 +- LiteNetLib/LiteNetManager.Socket.cs | 3 +-- LiteNetLib/LiteNetManager.cs | 8 ++++---- LiteNetLib/LiteNetPeer.cs | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 32b965eb..2c72d845 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -88,7 +88,7 @@ public LiteNetPeer Accept() /// Length of the data to be sent from the array. /// /// If , sends a single raw packet and immediately removes the request.
    - /// If , creates a temporary peer that sends a single rejection packet and lingers in memory until a timeout occurs to handle late-arriving packets. + /// If , creates a temporary peer that sends rejection packets and lingers in memory until a timeout occurs to handle late-arriving packets. /// public void Reject(byte[] rejectData, int start, int length, bool force) { diff --git a/LiteNetLib/LiteNetManager.Socket.cs b/LiteNetLib/LiteNetManager.Socket.cs index f77c015d..522e86a0 100644 --- a/LiteNetLib/LiteNetManager.Socket.cs +++ b/LiteNetLib/LiteNetManager.Socket.cs @@ -328,8 +328,7 @@ private void ReceiveLogic() /// /// When , disables internal background threads.
    /// You must manually call and .

    - /// Recommended for single-threaded environments like Unity or for - /// reducing multi-threading overhead and synchronization issues. + /// Can be used when e.g. 10,000 instances are running on the same machine, reducing the amount of threads used. /// public bool Start(IPAddress addressIPv4, IPAddress addressIPv6, int port, bool manualMode) { diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index e7b0102f..194b0b05 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -309,7 +309,7 @@ internal void DisconnectPeerForce(LiteNetPeer peer, /// The error code from the underlying socket, if any. /// /// If , immediately sets state to without sending a notification.
    - /// If , sends a single unreliable disconnect packet and sets state to . + /// If , sends unreliable disconnect packets until and sets state to . /// Peer will linger until to ignore late-arriving packets from the old session. /// /// Optional custom data to include in the disconnect packet. @@ -577,7 +577,7 @@ private void ProcessDelayedPackets() /// - /// Updates internal peer states, handles timeouts, and processes NTP requests. + /// Updates internal peer states, handles timeouts, processes NTP requests and sends buffered packets. /// /// Time passed since the last update frame. /// @@ -1296,10 +1296,10 @@ public void TriggerUpdate() => _updateTriggerEvent.Set(); /// - /// Reads data from the UDP sockets and processes pending events immediately. + /// Synchronizes arrived events from the background thread to your main-thread/ /// /// - /// Must be called continuously from the main loop if was set to . + /// Must be called continuously from the main loop if was set to to receive data from the UDP sockets. /// public void PollEvents() { diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index dacce2c6..8ca4e55c 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -706,7 +706,7 @@ internal virtual void AddToReliableChannelSendQueue(BaseChannel channel) /// Length of the data to send. /// /// If , immediately sets state to without sending a notification.
    - /// If , sends a single unreliable disconnect packet and sets state to + /// If , sends unreliable disconnect packets until a timeout occurs and sets state to /// Queued reliable packets are bypassed and dropped immediately. /// /// A indicating the state change transition. @@ -948,7 +948,7 @@ private void UpdateMtuLogic(float deltaTime) /// A directing how the manager should handle the request. /// /// If the state is , the peer lingers to ignore older connection requests - /// (where the packet timestamp is smaller than internal ), ensuring delayed or stale packets are dropped. + /// (where the packet timestamp is smaller than internal ), ensuring older connections are ignored. /// internal ConnectRequestResult ProcessConnectRequest(NetConnectRequestPacket connRequest) { From 2e33f8ec043a9990fb3df881357073fc75f93ddc Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Mon, 23 Mar 2026 11:23:18 +0100 Subject: [PATCH 198/261] Update docs --- LiteNetLib/ConnectionRequest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 2c72d845..055eb5ca 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -118,7 +118,7 @@ public void RejectForce(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, true); /// - /// Rejects the connection immediately without reliability and without additional data. + /// Rejects the connection immediately without sending any packet. /// public void RejectForce() => Reject(null, 0, 0, true); @@ -138,7 +138,7 @@ public void RejectForce(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, true); /// - /// Rejects the connection reliably without additional data. + /// Rejects the connection without sending any packet. /// public void Reject() => Reject(null, 0, 0, false); From 2f4da2345a7a747ac860bd4d499b6bb34e050f60 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Mon, 23 Mar 2026 11:26:49 +0100 Subject: [PATCH 199/261] Update docs --- LiteNetLib/ConnectionRequest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 055eb5ca..118f2415 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -87,7 +87,7 @@ public LiteNetPeer Accept() /// Offset in the array. /// Length of the data to be sent from the array. /// - /// If , sends a single raw packet and immediately removes the request.
    + /// If , rejects the connection immediately without sending any packet.
    /// If , creates a temporary peer that sends rejection packets and lingers in memory until a timeout occurs to handle late-arriving packets. /// public void Reject(byte[] rejectData, int start, int length, bool force) @@ -138,7 +138,7 @@ public void RejectForce(NetDataWriter rejectData) => Reject(rejectData.Data, 0, rejectData.Length, true); /// - /// Rejects the connection without sending any packet. + /// Rejects the connection reliably without additional data. /// public void Reject() => Reject(null, 0, 0, false); From c3c41da136a1c42606c9307d08556b625560f98b Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Mon, 23 Mar 2026 11:29:42 +0100 Subject: [PATCH 200/261] Update docs --- LiteNetLib/ConnectionRequest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 118f2415..3f770aa2 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -87,7 +87,7 @@ public LiteNetPeer Accept() /// Offset in the array. /// Length of the data to be sent from the array. /// - /// If , rejects the connection immediately without sending any packet.
    + /// If , immediately removes the request, if is not a reject packet is also sent.
    /// If , creates a temporary peer that sends rejection packets and lingers in memory until a timeout occurs to handle late-arriving packets. /// public void Reject(byte[] rejectData, int start, int length, bool force) @@ -108,7 +108,7 @@ public void Reject(byte[] rejectData, int start, int length) => Reject(rejectData, start, length, false); /// - /// Rejects the connection immediately without reliability. + /// Rejects the connection immediately without reliability. /// Minimizes resource usage by not creating an internal peer. /// /// Data to send with the rejection. From 6dd508e4362632575db6a741a2fea288af08e1a9 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Mon, 23 Mar 2026 12:34:57 +0200 Subject: [PATCH 201/261] generate docs --- .../api/LiteNetLib.LiteConnectionRequest.html | 71 +++++++++++++------ docs/api/LiteNetLib.LiteNetManager.html | 17 +++-- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/docs/api/LiteNetLib.LiteConnectionRequest.html b/docs/api/LiteNetLib.LiteConnectionRequest.html index 6eb76992..b624712a 100644 --- a/docs/api/LiteNetLib.LiteConnectionRequest.html +++ b/docs/api/LiteNetLib.LiteConnectionRequest.html @@ -213,7 +213,8 @@
    Returns

    Reject()

    -
    +

    Rejects the connection reliably without additional data.

    +
    Declaration
    @@ -223,7 +224,8 @@
    Declaration

    Reject(NetDataWriter)

    -
    +

    Rejects the connection reliably using data from a NetDataWriter.

    +
    Declaration
    @@ -242,7 +244,8 @@
    Parameters
    NetDataWriter rejectData - +

    Writer containing the data to send.

    + @@ -250,7 +253,8 @@
    Parameters

    Reject(byte[])

    -
    +

    Rejects the connection reliably.

    +
    Declaration
    @@ -269,7 +273,8 @@
    Parameters
    byte[] rejectData - +

    Data to send with the rejection.

    + @@ -277,7 +282,8 @@
    Parameters

    Reject(byte[], int, int)

    -
    +

    Rejects the connection reliably. Creates a temporary peer to handle packet loss.

    +
    Declaration
    @@ -296,17 +302,20 @@
    Parameters
    byte[] rejectData - +

    Data to send with the rejection.

    + int start - +

    Offset in the rejectData array.

    + int length - +

    Length of the data to be sent.

    + @@ -314,7 +323,8 @@
    Parameters

    Reject(byte[], int, int, bool)

    -
    +

    Rejects the connection request.

    +
    Declaration
    @@ -333,22 +343,27 @@
    Parameters
    byte[] rejectData - +

    Optional user data to send along with the rejection packet.

    + int start - +

    Offset in the rejectData array.

    + int length - +

    Length of the data to be sent from the rejectData array.

    + bool force - +

    If true, immediately removes the request, if rejectData is not null a reject packet is also sent.
    +If false, creates a temporary peer that sends rejection packets and lingers in memory until a timeout occurs to handle late-arriving packets.

    + @@ -356,7 +371,8 @@
    Parameters

    RejectForce()

    -
    +

    Rejects the connection immediately without sending any packet.

    +
    Declaration
    @@ -366,7 +382,8 @@
    Declaration

    RejectForce(NetDataWriter)

    -
    +

    Rejects the connection immediately without reliability using data from a NetDataWriter.

    +
    Declaration
    @@ -385,7 +402,8 @@
    Parameters
    NetDataWriter rejectData - +

    Writer containing the data to send.

    + @@ -393,7 +411,8 @@
    Parameters

    RejectForce(byte[])

    -
    +

    Rejects the connection immediately without reliability.

    +
    Declaration
    @@ -412,7 +431,8 @@
    Parameters
    byte[] rejectData - +

    Data to send with the rejection.

    + @@ -420,7 +440,9 @@
    Parameters

    RejectForce(byte[], int, int)

    -
    +

    Rejects the connection immediately without reliability. +Minimizes resource usage by not creating an internal peer.

    +
    Declaration
    @@ -439,17 +461,20 @@
    Parameters
    byte[] rejectData - +

    Data to send with the rejection.

    + int start - +

    Offset in the rejectData array.

    + int length - +

    Length of the data to be sent.

    + diff --git a/docs/api/LiteNetLib.LiteNetManager.html b/docs/api/LiteNetLib.LiteNetManager.html index cc9bd602..be29695b 100644 --- a/docs/api/LiteNetLib.LiteNetManager.html +++ b/docs/api/LiteNetLib.LiteNetManager.html @@ -2231,7 +2231,7 @@
    Returns

    ManualUpdate(float)

    -

    Update and send logic. Use this only when NetManager started in manual mode

    +

    Updates internal peer states, handles timeouts, processes NTP requests and sends buffered packets.

    Declaration
    @@ -2251,23 +2251,28 @@
    Parameters
    float elapsedMilliseconds -

    elapsed milliseconds since last update call

    +

    Time passed since the last update frame.

    +
    Remarks
    +

    Must be called continuously from the main loop if LiteNetLib.LiteNetManager._manualMode was set to true.

    +

    PollEvents()

    -

    Receive" pending events. Call this in game update code -In Manual mode it will call also socket Receive (which can be slow)

    +

    Synchronizes arrived events from the background thread to your main-thread/INetEventListener

    Declaration
    public void PollEvents()
    +
    Remarks
    +

    Must be called continuously from the main loop if LiteNetLib.LiteNetManager._manualMode was set to true to receive data from the UDP sockets.

    +
    @@ -3286,7 +3291,9 @@
    Parameters
    bool manualMode -

    mode of library

    +

    When true, disables internal background threads.
    +You must manually call PollEvents() and ManualUpdate(float).

    +Can be used when e.g. 10,000 instances are running on the same machine, reducing the amount of threads used.

    From 1da705560d02ac95a167fbd00974c7d6723b31c5 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 20:15:30 +0300 Subject: [PATCH 202/261] Use packet.Size for bounds check Fix a bounds check when merging packets by using packet.Size rather than packet.RawData.Length. This ensures the code checks against the actual packet payload length (Size) instead of the underlying buffer capacity, preventing potential reads past the valid packet data. --- LiteNetLib/LiteNetPeer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 8ca4e55c..334af37a 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -1049,7 +1049,7 @@ internal void ProcessPacket(NetPacket packet) break; pos += 2; - if (packet.RawData.Length - pos < size) + if (packet.Size - pos < size) break; NetPacket mergedPacket = NetManager.PoolGetPacket(size); From 7d7b08fb7509f9669a7442a19d5f7a9a63691ab0 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 21:14:53 +0300 Subject: [PATCH 203/261] Simplify IncomingFragments Replace the previous dual storage (small-array vs dictionary) with a single NetPacket[] Fragments in IncomingFragments and mark the class sealed. Remove Contains/TryGet/Set/Remove helpers and update RecycleAll to iterate, recycle and null entries. Update reassembly code to access the Fragments array directly, prevent duplicate fragment insertion, null out recycled fragments, and correct/clarify fragment size and position checks and error messages. These changes simplify memory handling and reduce branching/allocations during fragment assembly. --- LiteNetLib/LiteNetPeer.cs | 83 +++++++++++---------------------------- 1 file changed, 24 insertions(+), 59 deletions(-) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 96997b9e..fd4db9d4 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -98,17 +98,12 @@ private set private readonly object _mtuMutex = new object(); //Fragment - private class IncomingFragments + private sealed class IncomingFragments { - // Fragments with TotalFragments <= threshold use a fixed array (faster) - // Larger sets use a dictionary to avoid large upfront allocations - private const int ArrayThreshold = 64; - - private readonly NetPacket[] _array; - private readonly Dictionary _dict; - + public readonly NetPacket[] Fragments; public readonly ushort TotalFragments; public readonly byte ChannelId; + public int ReceivedCount; public int TotalSize; @@ -116,52 +111,19 @@ public IncomingFragments(ushort totalFragments, byte channelId) { TotalFragments = totalFragments; ChannelId = channelId; - if (totalFragments <= ArrayThreshold) - _array = new NetPacket[totalFragments]; - else - _dict = new Dictionary(); - } - - public bool Contains(ushort part) => - _array != null ? _array[part] != null : _dict.ContainsKey(part); - - public bool TryGet(ushort part, out NetPacket packet) - { - if (_array != null) - { - packet = _array[part]; - return packet != null; - } - return _dict.TryGetValue(part, out packet); - } - - public void Set(ushort part, NetPacket packet) - { - if (_array != null) - _array[part] = packet; - else - _dict[part] = packet; - } - - public void Remove(ushort part) - { - if (_array != null) - _array[part] = null; - else - _dict.Remove(part); + Fragments = new NetPacket[totalFragments]; } public void RecycleAll(LiteNetManager netManager) { - if (_array != null) + for (int i = 0; i < Fragments.Length; i++) { - foreach (var p in _array) - if (p != null) netManager.PoolRecycle(p); - } - else - { - foreach (var p in _dict.Values) - netManager.PoolRecycle(p); + NetPacket packet = Fragments[i]; + if (packet != null) + { + netManager.PoolRecycle(packet); + Fragments[i] = null; + } } } } @@ -851,13 +813,15 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) return; } - if (incomingFragments.Contains(p.FragmentPart)) + NetPacket[] fragments = incomingFragments.Fragments; + + if (fragments[p.FragmentPart] != null) { NetManager.PoolRecycle(p); return; } - incomingFragments.Set(p.FragmentPart, p); + fragments[p.FragmentPart] = p; incomingFragments.ReceivedCount++; incomingFragments.TotalSize += p.Size - NetConstants.FragmentedHeaderTotalSize; @@ -877,23 +841,23 @@ void AbortReassembly(string error) int pos = 0; for (ushort i = 0; i < incomingFragments.TotalFragments; i++) { - if (!incomingFragments.TryGet(i, out var fragment)) + NetPacket fragment = fragments[i]; + if (fragment == null) { AbortReassembly($"Fragment {i} missing during reassembly"); return; } - int writtenSize = fragment.Size - NetConstants.FragmentedHeaderTotalSize; - - if (pos + writtenSize > resultingPacket.RawData.Length) + if (fragment.Size > fragment.RawData.Length) { - AbortReassembly($"Fragment error pos: {pos + writtenSize} >= resultPacketSize: {resultingPacket.RawData.Length}"); + AbortReassembly($"Fragment error size: {fragment.Size} > fragment.RawData.Length: {fragment.RawData.Length}"); return; } - if (fragment.Size > fragment.RawData.Length) + int writtenSize = fragment.Size - NetConstants.FragmentedHeaderTotalSize; + if (pos + writtenSize > resultingPacket.RawData.Length) { - AbortReassembly($"Fragment error size: {fragment.Size} > fragment.RawData.Length: {fragment.RawData.Length}"); + AbortReassembly($"Fragment error pos: {pos + writtenSize} >= resultPacketSize: {resultingPacket.RawData.Length}"); return; } @@ -903,10 +867,11 @@ void AbortReassembly(string error) resultingPacket.RawData, pos, writtenSize); + pos += writtenSize; NetManager.PoolRecycle(fragment); - incomingFragments.Remove(i); + fragments[i] = null; } _holdedFragments.Remove(packetFragId); From 70d02004abf8378691e6bf484e74d9b22227fcb7 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 21:22:30 +0300 Subject: [PATCH 204/261] Comments --- LiteNetLib/LiteNetPeer.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index fd4db9d4..eac387a5 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -797,6 +797,7 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) if (!_holdedFragments.TryGetValue(packetFragId, out var incomingFragments)) { + //Holded fragments limit reached if (_holdedFragments.Count >= NetConstants.MaxFragmentsInWindow * ChannelsCount * NetConstants.FragmentedChannelsCount) { NetManager.PoolRecycle(p); @@ -813,21 +814,30 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) return; } - NetPacket[] fragments = incomingFragments.Fragments; + //Cache + var fragments = incomingFragments.Fragments; + //Error check if (fragments[p.FragmentPart] != null) { NetManager.PoolRecycle(p); return; } + //Fill array fragments[p.FragmentPart] = p; + + //Increase received fragments count incomingFragments.ReceivedCount++; + + //Increase total size incomingFragments.TotalSize += p.Size - NetConstants.FragmentedHeaderTotalSize; + //Check for finish if (incomingFragments.ReceivedCount != incomingFragments.TotalFragments) return; + //Just simple packet NetPacket resultingPacket = NetManager.PoolGetPacket(incomingFragments.TotalSize); void AbortReassembly(string error) @@ -861,6 +871,7 @@ void AbortReassembly(string error) return; } + //Create resulting big packet Buffer.BlockCopy( fragment.RawData, NetConstants.FragmentedHeaderTotalSize, @@ -870,11 +881,15 @@ void AbortReassembly(string error) pos += writtenSize; + //Free memory NetManager.PoolRecycle(fragment); fragments[i] = null; } + //Clear memory _holdedFragments.Remove(packetFragId); + + //Send to process NetManager.CreateReceiveEvent(resultingPacket, method, (byte)(packetChannelId / NetConstants.ChannelTypeCount), 0, this); } else //Just simple packet From 52d53635abb3851c0a1c41bbe6090a392d48b1ce Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 21:23:56 +0300 Subject: [PATCH 205/261] Comment x2 --- LiteNetLib/LiteNetPeer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index eac387a5..185c553b 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -791,6 +791,7 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) } NetDebug.Write($"Fragment. Id: {p.FragmentId}, Part: {p.FragmentPart}, Total: {p.FragmentsTotal}"); + //Get needed array from dictionary ushort packetFragId = p.FragmentId; byte packetChannelId = p.ChannelId; From ed7e0e6c35160d85b5b41ea988c926a5bb027f4a Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 21:24:59 +0300 Subject: [PATCH 206/261] Old code style --- LiteNetLib/LiteNetPeer.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 185c553b..bbf6dd3c 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -791,11 +791,10 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) } NetDebug.Write($"Fragment. Id: {p.FragmentId}, Part: {p.FragmentPart}, Total: {p.FragmentsTotal}"); - //Get needed array from dictionary + //Get needed array from dictionary ushort packetFragId = p.FragmentId; byte packetChannelId = p.ChannelId; - if (!_holdedFragments.TryGetValue(packetFragId, out var incomingFragments)) { //Holded fragments limit reached From 845db312a638e0f5a24b662e70966c4a802652d8 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 21:25:39 +0300 Subject: [PATCH 207/261] Old log --- LiteNetLib/LiteNetPeer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index bbf6dd3c..3ee24789 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -801,6 +801,7 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) if (_holdedFragments.Count >= NetConstants.MaxFragmentsInWindow * ChannelsCount * NetConstants.FragmentedChannelsCount) { NetManager.PoolRecycle(p); + //NetDebug.WriteError($"Holded fragments limit reached ({_holdedFragments.Count}/{(NetConstants.DefaultWindowSize / 2) * ChannelsCount * NetConstants.FragmentedChannelsCount}). Dropping fragment id: {packetFragId}"); return; } From 8258bdee8d4293370909a65f585ba81fd1522b2e Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 21:27:22 +0300 Subject: [PATCH 208/261] updates --- LiteNetLib/LiteNetPeer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 3ee24789..b395935c 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -791,7 +791,6 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) } NetDebug.Write($"Fragment. Id: {p.FragmentId}, Part: {p.FragmentPart}, Total: {p.FragmentsTotal}"); - //Get needed array from dictionary ushort packetFragId = p.FragmentId; byte packetChannelId = p.ChannelId; @@ -822,6 +821,7 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) if (fragments[p.FragmentPart] != null) { NetManager.PoolRecycle(p); + NetDebug.WriteError("Invalid fragment packet"); return; } From 0ee4563f81994dc26f57946992b0e47996013d82 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 21:28:00 +0300 Subject: [PATCH 209/261] latest mb --- LiteNetLib/LiteNetPeer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index b395935c..89b5b241 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -791,6 +791,7 @@ internal void AddReliablePacket(DeliveryMethod method, NetPacket p) } NetDebug.Write($"Fragment. Id: {p.FragmentId}, Part: {p.FragmentPart}, Total: {p.FragmentsTotal}"); + //Get needed array from dictionary ushort packetFragId = p.FragmentId; byte packetChannelId = p.ChannelId; From 7e650ea9e0d41fef564f0f2f2ca45df76b9eb8b4 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 21:45:31 +0300 Subject: [PATCH 210/261] Add ThrowNotEnoughData helper and uint check Replace the previous bounds check in EnsureAvailable with an unsigned comparison against a local available variable and extract the throw into a separate ThrowNotEnoughData method. The new helper is marked NoInlining and includes XML documentation. This reduces duplicated throw logic in hot paths and makes the bounds-check semantics clearer and more JIT-friendly. --- LiteNetLib/Utils/NetDataReader.cs | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index a93114fa..0c2fe732 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -93,9 +93,21 @@ public int AvailableBytes [MethodImpl(MethodImplOptions.AggressiveInlining)] private void EnsureAvailable(int count) { - if (count < 0 || count > AvailableBytes) - throw new InvalidOperationException( - $"Not enough data to read {count} byte(s). Position={_position}, DataSize={_dataSize}"); + int available = _dataSize - _position; + if ((uint)count > (uint)available) + ThrowNotEnoughData(count); + } + + /// + /// Throws an indicating that there is not enough data to read. + /// + /// The number of bytes that were attempted to be read. + /// Always thrown. + [MethodImpl(MethodImplOptions.NoInlining)] + private void ThrowNotEnoughData(int count) + { + throw new InvalidOperationException( + $"Not enough data to read {count} byte(s). Position={_position}, DataSize={_dataSize}"); } /// From ba43052a76b4e312484ca6906b3bdcdc76b2f545 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:00:22 +0300 Subject: [PATCH 211/261] Fix XML doc tag in NetDataReader Correct a typo in the XML documentation of LiteNetLib/Utils/NetDataReader.cs by replacing an invalid attribute with . This fixes documentation warnings and ensures the class reference renders correctly. --- LiteNetLib/Utils/NetDataReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 0c2fe732..a6327657 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -182,7 +182,7 @@ public void Get(out T result) where T : struct, INetSerializable } /// - /// Deserializes a that implements using a provided constructor. + /// Deserializes a that implements using a provided constructor. /// /// A type implementing . /// The deserialized instance output. From e723df27e6df4a46355f72d6acb004e26cba71a2 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:01:21 +0300 Subject: [PATCH 212/261] Call Get(out ...) overloads in Get methods Replace direct instantiation and obj.Deserialize(this) with calls to existing Get(out ...) overloads in both struct and class INetSerializable Get methods. This removes duplicated deserialization code and centralizes behavior without changing functionality. --- LiteNetLib/Utils/NetDataReader.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index a6327657..7de98580 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -547,9 +547,8 @@ public ArraySegment GetRemainingBytesSegment() /// The deserialized . public T Get() where T : struct, INetSerializable { - var obj = default(T); - obj.Deserialize(this); - return obj; + Get(out T result); + return result; } /// @@ -560,9 +559,8 @@ public T Get() where T : struct, INetSerializable /// A new instance of . public T Get(Func constructor) where T : class, INetSerializable { - var obj = constructor(); - obj.Deserialize(this); - return obj; + Get(out T result, constructor); + return result; } /// From cb68beda3a6c73ab06026d233a7d25eae8a0b768 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:04:49 +0300 Subject: [PATCH 213/261] Simplify GetIPEndPoint and add IP size constants Introduce IPv4Size and IPv6Size constants and consolidate IPv4/IPv6 branching in GetIPEndPoint. Read the IP version flag, compute the address size, ensure buffer availability, construct the IPAddress from a ReadOnlySpan, and advance the position. Removes duplicated code and magic numbers while preserving existing behavior. --- LiteNetLib/Utils/NetDataReader.cs | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 7de98580..ff5d6b9c 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -13,6 +13,9 @@ public class NetDataReader protected int _dataSize; protected int _offset; + private const int IPv4Size = 4; + private const int IPv6Size = 16; + /// /// Gets the internal array containing the raw network data. /// @@ -209,21 +212,13 @@ public void Get(out T result, Func constructor) where T : class, INetSeria /// public IPEndPoint GetIPEndPoint() { - IPAddress address; - //IPv4 - if (GetByte() == 0) - { - EnsureAvailable(4); - address = new IPAddress(new ReadOnlySpan(_data, _position, 4)); - _position += 4; - } - //IPv6 - else - { - EnsureAvailable(16); - address = new IPAddress(new ReadOnlySpan(_data, _position, 16)); - _position += 16; - } + bool isIPv4 = GetByte() == 0; + + int size = isIPv4 ? IPv4Size : IPv6Size; + EnsureAvailable(size); + + IPAddress address = new IPAddress(new ReadOnlySpan(_data, _position, size)); + _position += size; return new IPEndPoint(address, GetUShort()); } From d7542e3ad613af7423c5340631890f7d3f2350b0 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:16:12 +0300 Subject: [PATCH 214/261] Add bounds check to GetByte Call EnsureAvailable(1) before reading from the internal buffer in NetDataReader.GetByte to prevent out-of-range reads and provide consistent error handling. The method still increments the read position after returning the byte. --- LiteNetLib/Utils/NetDataReader.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index ff5d6b9c..74f5f5bc 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -268,7 +268,11 @@ public IPEndPoint GetIPEndPoint() public void Get(out Guid result) => result = GetGuid(); /// Reads the next from the buffer. - public byte GetByte() => _data[_position++]; + public byte GetByte() + { + EnsureAvailable(1); + return _data[_position++]; + } /// Reads the next from the buffer. public sbyte GetSByte() => (sbyte)GetByte(); From 62b45fe6e9c95d0f199c6db115edf96d24026a0b Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:20:33 +0300 Subject: [PATCH 215/261] Check overflow and availability in GetUnmanagedArray Use checked() when computing byteLength and call EnsureAvailable(byteLength) before taking a span. This prevents silent integer overflow on length * sizeof(T) and verifies there are enough bytes available for MemoryMarshal.Cast and subsequent array creation in GetUnmanagedArray(). --- LiteNetLib/Utils/NetDataReader.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 74f5f5bc..a6559922 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -285,7 +285,9 @@ public byte GetByte() public unsafe T[] GetUnmanagedArray() where T : unmanaged { ushort length = GetUShort(); - int byteLength = length * sizeof(T); + int byteLength = checked(length * sizeof(T)); + EnsureAvailable(byteLength); + ReadOnlySpan slice = _data.AsSpan(_position, byteLength); T[] result = MemoryMarshal.Cast(slice) .ToArray(); From 15a9a920a9e926026fcfa7a24f049fc4ff82bff7 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:21:04 +0300 Subject: [PATCH 216/261] Replace magic 16 with GuidSize constant Introduce a GuidSize constant (16) and use it in GetGuid() instead of hard-coded 16s. This improves readability and avoids repeated magic numbers when ensuring availability, constructing the Guid from the data span, and advancing the read position. --- LiteNetLib/Utils/NetDataReader.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index a6559922..f6827450 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -15,6 +15,7 @@ public class NetDataReader private const int IPv4Size = 4; private const int IPv6Size = 16; + private const int GuidSize = 16; /// /// Gets the internal array containing the raw network data. @@ -511,9 +512,9 @@ public string GetLargeString() /// The deserialized . public Guid GetGuid() { - EnsureAvailable(16); - var result = new Guid(_data.AsSpan(_position, 16)); - _position += 16; + EnsureAvailable(GuidSize); + var result = new Guid(_data.AsSpan(_position, GuidSize)); + _position += GuidSize; return result; } From 20d45eb892b0bfc4661d8d02432e99347f164f0c Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:23:12 +0300 Subject: [PATCH 217/261] Use named constants for IP and GUID sizes Introduce IPv4Size (4), IPv6Size (16) and GuidSize (16) constants in NetDataWriter.cs and replace magic numbers with these constants in Put(Guid) and when determining addressSize for IPEndPoint. This improves readability and maintainability by avoiding literal size values. --- LiteNetLib/Utils/NetDataWriter.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 18a9fc6a..00365548 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -14,6 +14,10 @@ public class NetDataWriter private const int InitialSize = 64; private readonly bool _autoResize; + private const int IPv4Size = 4; + private const int IPv6Size = 16; + private const int GuidSize = 16; + /// /// Gets the total capacity of the internal buffer. /// @@ -272,9 +276,9 @@ public int SetPosition(int position) public void Put(Guid value) { if (_autoResize) - ResizeIfNeed(_position + 16); + ResizeIfNeed(_position + GuidSize); value.TryWriteBytes(_data.AsSpan(_position)); - _position += 16; + _position += GuidSize; } /// @@ -516,12 +520,12 @@ public void Put(IPEndPoint endPoint) if (endPoint.AddressFamily == AddressFamily.InterNetwork) { - addressSize = 4; + addressSize = IPv4Size; familyFlag = 0; } else if (endPoint.AddressFamily == AddressFamily.InterNetworkV6) { - addressSize = 16; + addressSize = IPv6Size; familyFlag = 1; } else From d615f1068e455d7a05633cddb5c081df89984686 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:24:20 +0300 Subject: [PATCH 218/261] Code style --- LiteNetLib/Utils/NetDataReader.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index f6827450..a397fafa 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -286,6 +286,7 @@ public byte GetByte() public unsafe T[] GetUnmanagedArray() where T : unmanaged { ushort length = GetUShort(); + int byteLength = checked(length * sizeof(T)); EnsureAvailable(byteLength); From 72dfcff8fac0bb96839468747051e90b655a1bb6 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:33:16 +0300 Subject: [PATCH 219/261] Validate buffer and fix GetStringArray locals Add EnsureAvailable checks to both GetStringArray overloads to verify there are enough bytes for the array string lengths before reading (uses checked(length * sizeof(ushort)) to catch overflows). Also rename the local array variable from `arr` to `result` and return it, cleaning up the methods and improving safety against buffer overruns. --- LiteNetLib/Utils/NetDataReader.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index a397fafa..c2be230d 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -388,12 +388,15 @@ public T[] GetArray(Func constructor) where T : class, INetSerializable public string[] GetStringArray() { ushort length = GetUShort(); - string[] arr = new string[length]; + EnsureAvailable(checked(length * sizeof(ushort))); // 2 bytes (ushort) for string length + + string[] result = new string[length]; for (int i = 0; i < length; i++) { - arr[i] = GetString(); + result[i] = GetString(); } - return arr; + + return result; } /// @@ -407,12 +410,15 @@ public string[] GetStringArray() public string[] GetStringArray(int maxStringLength) { ushort length = GetUShort(); - string[] arr = new string[length]; + EnsureAvailable(checked(length * sizeof(ushort))); // 2 bytes (ushort) for string length + + string[] result = new string[length]; for (int i = 0; i < length; i++) { - arr[i] = GetString(maxStringLength); + result[i] = GetString(maxStringLength); } - return arr; + + return result; } /// Reads a value from the current position. From 19af39613b82172d25410aeef64c3ef5ad7a470f Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:37:52 +0300 Subject: [PATCH 220/261] Use AvailableBytes for remaining bytes APIs Replace direct calculation (_dataSize - _position) with the AvailableBytes property in GetRemainingBytesSpan and GetRemainingBytesMemory. This deduplicates logic, improves clarity, and ensures both methods use the same availability check when returning the remaining data slice before advancing the position. --- LiteNetLib/Utils/NetDataReader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index c2be230d..e500a3b7 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -579,7 +579,7 @@ public T Get(Func constructor) where T : class, INetSerializable [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan GetRemainingBytesSpan() { - var result = new ReadOnlySpan(_data, _position, _dataSize - _position); + var result = new ReadOnlySpan(_data, _position, AvailableBytes); _position = _dataSize; return result; } @@ -591,7 +591,7 @@ public ReadOnlySpan GetRemainingBytesSpan() [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlyMemory GetRemainingBytesMemory() { - var result = new ReadOnlyMemory(_data, _position, _dataSize - _position); + var result = new ReadOnlyMemory(_data, _position, AvailableBytes); _position = _dataSize; return result; } From cf9a9689bf8eca0d96f6775668b4cad6d4622a9d Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:41:02 +0300 Subject: [PATCH 221/261] Return Array.Empty for zero-length reads Avoid allocating a new byte[] when no data remains by returning Array.Empty() for size == 0. Also rename the temporary buffer to result for clarity; behavior for non-zero reads is unchanged (copy remaining bytes, advance position to end). This reduces allocations for empty reads. --- LiteNetLib/Utils/NetDataReader.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index e500a3b7..d49ac0d5 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -606,10 +606,13 @@ public ReadOnlyMemory GetRemainingBytesMemory() public byte[] GetRemainingBytes() { int size = _dataSize - _position; - byte[] outgoingData = new byte[size]; - Buffer.BlockCopy(_data, _position, outgoingData, 0, size); + if (size == 0) + return Array.Empty(); + + byte[] result = new byte[size]; + Buffer.BlockCopy(_data, _position, result, 0, size); _position = _dataSize; - return outgoingData; + return result; } /// From 13e6f9149b783caad39faa3ac77c2a15a3a4f27f Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:49:32 +0300 Subject: [PATCH 222/261] Use GetUnmanaged for GetEnum Replace the previous platform-specific unsafe read logic in GetEnum() with a direct call to GetUnmanaged(). This centralizes unmanaged enum reading, removes the NET8 conditional (Unsafe.ReadUnaligned / fixed pointer) and reduces duplicated unsafe buffer-reading code without changing behavior. --- LiteNetLib/Utils/NetDataReader.cs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index d49ac0d5..70dee381 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -709,20 +709,7 @@ public unsafe T GetUnmanaged() where T : unmanaged /// /// An unmanaged enum type to read. /// The enum value read from the buffer. - public unsafe T GetEnum() where T : unmanaged, Enum - { - int size = sizeof(T); - ReadOnlySpan span = new ReadOnlySpan(_data, _position, size); - _position += size; -#if NET8_0_OR_GREATER - return Unsafe.ReadUnaligned(ref MemoryMarshal.GetReference(span)); -#else - fixed (byte* ptr = span) - { - return *(T*)ptr; - } -#endif - } + public unsafe T GetEnum() where T : unmanaged, Enum => GetUnmanaged(); #endregion From d933a4e92f118aee77bda810632f271f710d5841 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 22:56:21 +0300 Subject: [PATCH 223/261] Code style --- LiteNetLib/Utils/NetDataReader.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 70dee381..60ba6748 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -800,9 +800,11 @@ public unsafe T PeekUnmanaged() where T : unmanaged return value; #endif } + #endregion #region TryGetMethods + /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . @@ -1032,6 +1034,7 @@ public bool TryGetBytesWithLength(out byte[] result) result = null; return false; } + #endregion /// Clears the reader state and releases the reference to the internal buffer. From 0c4fcc23fef0c4008bde180d944d6207fd23b5fd Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 23:10:30 +0300 Subject: [PATCH 224/261] Use GetSByte() in NetDataReader.Get(out sbyte) Replace casting from GetByte() with a direct call to GetSByte() in LiteNetLib/Utils/NetDataReader.cs. This ensures signed byte values are read using the dedicated reader method (preserving correct sign/semantics) and keeps the reading logic consistent. --- LiteNetLib/Utils/NetDataReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 60ba6748..49923548 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -227,7 +227,7 @@ public IPEndPoint GetIPEndPoint() public void Get(out byte result) => result = GetByte(); /// Reads an and assigns it to . - public void Get(out sbyte result) => result = (sbyte)GetByte(); + public void Get(out sbyte result) => result = GetSByte(); /// Reads a and assigns it to . public void Get(out bool result) => result = GetBool(); From b02d4b5a90ac4e2b093a4f32b7b6cf72aaa02634 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 23:11:01 +0300 Subject: [PATCH 225/261] Reposition GetByte/GetSByte in NetDataReader Move GetByte and GetSByte methods within LiteNetLib/Utils/NetDataReader.cs so they are grouped with other primitive read methods (placed before GetBool). This is a non-functional refactor to improve code organization and readability; no logic changes were made. --- LiteNetLib/Utils/NetDataReader.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 49923548..4e81f533 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -268,16 +268,6 @@ public IPEndPoint GetIPEndPoint() /// Reads a and assigns it to . public void Get(out Guid result) => result = GetGuid(); - /// Reads the next from the buffer. - public byte GetByte() - { - EnsureAvailable(1); - return _data[_position++]; - } - - /// Reads the next from the buffer. - public sbyte GetSByte() => (sbyte)GetByte(); - /// /// Reads an array of unmanaged values prefixed by a length. /// @@ -421,6 +411,16 @@ public string[] GetStringArray(int maxStringLength) return result; } + /// Reads the next from the buffer. + public byte GetByte() + { + EnsureAvailable(1); + return _data[_position++]; + } + + /// Reads the next from the buffer. + public sbyte GetSByte() => (sbyte)GetByte(); + /// Reads a value from the current position. /// if the byte is 1; otherwise, . public bool GetBool() => GetByte() == 1; From 8b4d4399089e02b58de776599ac3b51cf4aa3599 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 23:11:49 +0300 Subject: [PATCH 226/261] Use PeekByte/PeekUShort in Peek methods Refactor PeekSByte, PeekBool and PeekChar to call existing PeekByte()/PeekUShort() instead of directly accessing _data or PeekUnmanaged(). This centralizes byte/ushort read logic (and any bounds/validation behavior) to reduce duplication and potential subtle bugs while preserving external behavior. --- LiteNetLib/Utils/NetDataReader.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 4e81f533..b4bdaef9 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -719,13 +719,13 @@ public unsafe T GetUnmanaged() where T : unmanaged public byte PeekByte() => _data[_position]; /// Reads the at the current position without advancing the . - public sbyte PeekSByte() => (sbyte)_data[_position]; + public sbyte PeekSByte() => (sbyte)PeekByte(); /// Reads the at the current position without advancing the . - public bool PeekBool() => _data[_position] == 1; + public bool PeekBool() => PeekByte() == 1; /// Reads the at the current position without advancing the . - public char PeekChar() => PeekUnmanaged(); + public char PeekChar() => (char)PeekUShort(); /// Reads the at the current position without advancing the . public ushort PeekUShort() => PeekUnmanaged(); From a834bd72918814068d6b3b1622aea5155b999bfa Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 23:14:07 +0300 Subject: [PATCH 227/261] Update NetDataReader.cs --- LiteNetLib/Utils/NetDataReader.cs | 118 ++++++++++-------------------- 1 file changed, 38 insertions(+), 80 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index b4bdaef9..b29f0e3b 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -864,114 +864,42 @@ public bool TryGetChar(out char result) /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetShort(out short result) - { - if (AvailableBytes >= 2) - { - result = GetShort(); - return true; - } - result = 0; - return false; - } + public bool TryGetShort(out short result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetUShort(out ushort result) - { - if (AvailableBytes >= 2) - { - result = GetUShort(); - return true; - } - result = 0; - return false; - } + public bool TryGetUShort(out ushort result) => TryGetUnmanaged(out result); /// Attempts to read an without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetInt(out int result) - { - if (AvailableBytes >= 4) - { - result = GetInt(); - return true; - } - result = 0; - return false; - } + public bool TryGetInt(out int result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetUInt(out uint result) - { - if (AvailableBytes >= 4) - { - result = GetUInt(); - return true; - } - result = 0; - return false; - } + public bool TryGetUInt(out uint result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetLong(out long result) - { - if (AvailableBytes >= 8) - { - result = GetLong(); - return true; - } - result = 0; - return false; - } + public bool TryGetLong(out long result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetULong(out ulong result) - { - if (AvailableBytes >= 8) - { - result = GetULong(); - return true; - } - result = 0; - return false; - } + public bool TryGetULong(out ulong result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetFloat(out float result) - { - if (AvailableBytes >= 4) - { - result = GetFloat(); - return true; - } - result = 0; - return false; - } + public bool TryGetFloat(out float result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetDouble(out double result) - { - if (AvailableBytes >= 8) - { - result = GetDouble(); - return true; - } - result = 0; - return false; - } + public bool TryGetDouble(out double result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or if failed. @@ -1035,6 +963,36 @@ public bool TryGetBytesWithLength(out byte[] result) return false; } + /// + /// Attempts to read a value of type from the internal byte buffer at the current position, + /// advancing the position by the size of if successful. + /// + /// An unmanaged value type to read from the buffer. + /// When this method returns, contains the value read from the buffer, or the default value if the read failed. + /// if enough data was available to read the value; otherwise, . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public unsafe bool TryGetUnmanaged(out T result) where T : unmanaged + { + int size = sizeof(T); + if (AvailableBytes < size) + { + result = default; + return false; + } + +#if NET8_0_OR_GREATER + result = Unsafe.ReadUnaligned(ref _data[_position]); +#else + fixed (byte* ptr = &_data[_position]) + { + result = *(T*)ptr; + } +#endif + + _position += size; + return true; + } + #endregion /// Clears the reader state and releases the reference to the internal buffer. From a9a8ed9c44b4d949ef3acfdf5b1ed3d43821f268 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 23:17:37 +0300 Subject: [PATCH 228/261] Remove magic numbers --- LiteNetLib/Utils/NetDataReader.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index b29f0e3b..560281e2 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -763,9 +763,9 @@ public string PeekString(int maxLength) return string.Empty; int actualSize = size - 1; - return (maxLength > 0 && NetDataWriter.uTF8Encoding.GetCharCount(_data, _position + 2, actualSize) > maxLength) + return (maxLength > 0 && NetDataWriter.uTF8Encoding.GetCharCount(_data, _position + sizeof(ushort), actualSize) > maxLength) ? string.Empty - : NetDataWriter.uTF8Encoding.GetString(_data, _position + 2, actualSize); + : NetDataWriter.uTF8Encoding.GetString(_data, _position + sizeof(ushort), actualSize); } /// @@ -778,7 +778,7 @@ public string PeekString() return string.Empty; int actualSize = size - 1; - return NetDataWriter.uTF8Encoding.GetString(_data, _position + 2, actualSize); + return NetDataWriter.uTF8Encoding.GetString(_data, _position + sizeof(ushort), actualSize); } /// From 0765bb421b9ac98797bb8467acfb93116bf91de9 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 23:19:25 +0300 Subject: [PATCH 229/261] Code style --- LiteNetLib/Utils/NetDataReader.cs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 560281e2..a7ff4018 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -906,19 +906,23 @@ public bool TryGetChar(out char result) /// if enough data was available; otherwise, . public bool TryGetString(out string result) { - if (AvailableBytes >= 2) + if (AvailableBytes < sizeof(ushort)) { - ushort strSize = PeekUShort(); - int actualSize = strSize == 0 ? 0 : strSize - 1; + result = null; + return false; + } - if (AvailableBytes >= 2 + actualSize) - { - result = GetString(); - return true; - } + ushort size = PeekUShort(); + int actualSize = size == 0 ? 0 : size - 1; + + if (AvailableBytes < sizeof(ushort) + actualSize) + { + result = null; + return false; } - result = null; - return false; + + result = GetString(); + return true; } /// Attempts to read a array without throwing an exception. From 175d609967f5d8635b251b512300648924d770e9 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 23:21:12 +0300 Subject: [PATCH 230/261] Code style --- LiteNetLib/Utils/NetDataReader.cs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index a7ff4018..279e45dc 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -954,17 +954,21 @@ public bool TryGetStringArray(out string[] result) /// if enough data was available; otherwise, . public bool TryGetBytesWithLength(out byte[] result) { - if (AvailableBytes >= 2) + if (AvailableBytes < sizeof(ushort)) { - ushort length = PeekUShort(); - if (AvailableBytes >= 2 + length) - { - result = GetBytesWithLength(); - return true; - } + result = null; + return false; } - result = null; - return false; + + ushort length = PeekUShort(); + if (AvailableBytes < sizeof(ushort) + length) + { + result = null; + return false; + } + + result = GetBytesWithLength(); + return true; } /// From e8387e0cee324e9ad65155ac5c7d587d86eddca9 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Tue, 24 Mar 2026 23:25:52 +0300 Subject: [PATCH 231/261] TryGetStringArray roll back fix --- LiteNetLib/Utils/NetDataReader.cs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 279e45dc..ac91acef 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -930,22 +930,34 @@ public bool TryGetString(out string result) /// if enough data was available; otherwise, . public bool TryGetStringArray(out string[] result) { - if (!TryGetUShort(out ushort strArrayLength)) + if (AvailableBytes < sizeof(ushort)) { result = null; return false; } - result = new string[strArrayLength]; - for (int i = 0; i < strArrayLength; i++) + int startPosition = _position; + + ushort length = GetUShort(); + if (AvailableBytes < checked(length * sizeof(ushort))) // 2 bytes (ushort) for string length + { + _position = startPosition; // Roll back to the original position + result = null; + return false; + } + + string[] values = new string[length]; + for (int i = 0; i < length; i++) { - if (!TryGetString(out result[i])) + if (!TryGetString(out values[i])) { + _position = startPosition; // Roll back to the original position result = null; return false; } } + result = values; return true; } From ee593d1c180b297139fe2dafd9760a8cdfffef03 Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 25 Mar 2026 14:56:01 +0200 Subject: [PATCH 232/261] Update LiteNetLib/Utils/NetDataReader.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- LiteNetLib/Utils/NetDataReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index ac91acef..ae17b689 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -98,7 +98,7 @@ public int AvailableBytes private void EnsureAvailable(int count) { int available = _dataSize - _position; - if ((uint)count > (uint)available) + if (count < 0 || available < 0 || count > available) ThrowNotEnoughData(count); } From 7e71c26e9c81f53a5fcf6a4314204f28b0b9d3c7 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Wed, 25 Mar 2026 15:25:21 +0200 Subject: [PATCH 233/261] update version to 2.1.0 --- LiteNetLib/LiteNetLib.csproj | 6 +- docs/api/LiteNetLib.NetPacketReader.html | 15 +++-- docs/api/LiteNetLib.Utils.NetDataReader.html | 64 +++++++++++++++++++- docs/xrefmap.yml | 16 +++++ 4 files changed, 91 insertions(+), 10 deletions(-) diff --git a/LiteNetLib/LiteNetLib.csproj b/LiteNetLib/LiteNetLib.csproj index a896bb08..e53cde48 100644 --- a/LiteNetLib/LiteNetLib.csproj +++ b/LiteNetLib/LiteNetLib.csproj @@ -10,11 +10,11 @@ true 1701;1702;1705;1591 - 2.0.2 + 2.1.0 Lite reliable UDP library for Mono and .NET true true - 2.0.2 + 2.1.0 @@ -33,7 +33,7 @@ true $(DefineConstants);LITENETLIB_UNSAFE udp reliable-udp network - https://github.com/RevenantX/LiteNetLib/releases/tag/2.0.2 + https://github.com/RevenantX/LiteNetLib/releases/tag/2.1.0 git https://github.com/RevenantX/LiteNetLib https://github.com/RevenantX/LiteNetLib diff --git a/docs/api/LiteNetLib.NetPacketReader.html b/docs/api/LiteNetLib.NetPacketReader.html index a2634d2c..9a8ae4b3 100644 --- a/docs/api/LiteNetLib.NetPacketReader.html +++ b/docs/api/LiteNetLib.NetPacketReader.html @@ -177,12 +177,6 @@
    Inherited Members
    - - @@ -228,6 +222,12 @@
    Inherited Members
    + + @@ -402,6 +402,9 @@
    Inherited Members
    + diff --git a/docs/api/LiteNetLib.Utils.NetDataReader.html b/docs/api/LiteNetLib.Utils.NetDataReader.html index 4b8e7acb..e12c546e 100644 --- a/docs/api/LiteNetLib.Utils.NetDataReader.html +++ b/docs/api/LiteNetLib.Utils.NetDataReader.html @@ -2560,7 +2560,7 @@
    Type Parameters

    Get<T>(out T, Func<T>)

    -

    Deserializes a that implements INetSerializable using a provided constructor.

    +

    Deserializes a class that implements INetSerializable using a provided constructor.

    Declaration
    @@ -3868,6 +3868,68 @@
    Returns
    + + +

    TryGetUnmanaged<T>(out T)

    +

    Attempts to read a value of type T from the internal byte buffer at the current position, +advancing the position by the size of T if successful.

    +
    +
    +
    Declaration
    +
    +
    public bool TryGetUnmanaged<T>(out T result) where T : unmanaged
    +
    +
    Parameters
    + + + + + + + + + + + + + + + +
    TypeNameDescription
    Tresult

    When this method returns, contains the value read from the buffer, or the default value if the read failed.

    +
    +
    Returns
    + + + + + + + + + + + + + +
    TypeDescription
    bool

    true if enough data was available to read the value; otherwise, false.

    +
    +
    Type Parameters
    + + + + + + + + + + + + + +
    NameDescription
    T

    An unmanaged value type to read from the buffer.

    +
    +
    diff --git a/docs/xrefmap.yml b/docs/xrefmap.yml index c0c86392..3dde95bc 100644 --- a/docs/xrefmap.yml +++ b/docs/xrefmap.yml @@ -5696,6 +5696,22 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataReader.TryGetUShort nameWithType: NetDataReader.TryGetUShort +- uid: LiteNetLib.Utils.NetDataReader.TryGetUnmanaged* + name: TryGetUnmanaged + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_TryGetUnmanaged_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.TryGetUnmanaged + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.TryGetUnmanaged + nameWithType: NetDataReader.TryGetUnmanaged +- uid: LiteNetLib.Utils.NetDataReader.TryGetUnmanaged``1(``0@) + name: TryGetUnmanaged(out T) + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_TryGetUnmanaged__1___0__ + commentId: M:LiteNetLib.Utils.NetDataReader.TryGetUnmanaged``1(``0@) + name.vb: TryGetUnmanaged(Of T)(T) + fullName: LiteNetLib.Utils.NetDataReader.TryGetUnmanaged(out T) + fullName.vb: LiteNetLib.Utils.NetDataReader.TryGetUnmanaged(Of T)(T) + nameWithType: NetDataReader.TryGetUnmanaged(out T) + nameWithType.vb: NetDataReader.TryGetUnmanaged(Of T)(T) - uid: LiteNetLib.Utils.NetDataReader.UserDataOffset name: UserDataOffset href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_UserDataOffset From 56271b58b6a3dafb80ba54f322a11970ffdc7493 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 25 Mar 2026 19:34:11 +0300 Subject: [PATCH 234/261] Update NetDataWriter.cs --- LiteNetLib/Utils/NetDataWriter.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 00365548..80eed775 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -562,16 +562,14 @@ public void PutLargeString(string value) Put(0); return; } + int size = uTF8Encoding.GetByteCount(value); - if (size == 0) - { - Put(0); - return; - } Put(size); + if (_autoResize) ResizeIfNeed(_position + size); - uTF8Encoding.GetBytes(value, 0, size, _data, _position); + + uTF8Encoding.GetBytes(value, 0, value.Length, _data, _position); _position += size; } From 044b03f08a797ea4b40837876c1f113a428d3d22 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Wed, 25 Mar 2026 18:56:14 +0200 Subject: [PATCH 235/261] simplify fast bitConverter. Remove BIGENDIAN checks because BIGENDIAN is deprecated. Fixes for unity --- LiteNetLib/Utils/FastBitConverter.cs | 146 ++------------------------- 1 file changed, 6 insertions(+), 140 deletions(-) diff --git a/LiteNetLib/Utils/FastBitConverter.cs b/LiteNetLib/Utils/FastBitConverter.cs index b067a3db..1a6c3287 100644 --- a/LiteNetLib/Utils/FastBitConverter.cs +++ b/LiteNetLib/Utils/FastBitConverter.cs @@ -1,13 +1,13 @@ using System; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; +#if UNITY_ANDROID +using Unity.Collections.LowLevel.Unsafe; +#endif namespace LiteNetLib.Utils { public static class FastBitConverter { -#if (LITENETLIB_UNSAFE || NETCOREAPP3_1 || NET5_0 || NETCOREAPP3_0_OR_GREATER) && !BIGENDIAN -#if LITENETLIB_UNSAFE [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void GetBytes(byte[] bytes, int startIndex, T value) where T : unmanaged { @@ -16,12 +16,10 @@ public static unsafe void GetBytes(byte[] bytes, int startIndex, T value) whe ThrowIndexOutOfRangeException(); #if NET8_0_OR_GREATER Unsafe.WriteUnaligned(ref bytes[startIndex], value); -#elif NETCOREAPP3_1 || NET5_0 || NETCOREAPP3_0_OR_GREATER - Unsafe.As(ref bytes[startIndex]) = value; #else fixed (byte* ptr = &bytes[startIndex]) { -#if UNITY_ANDROID + #if UNITY_ANDROID // On some android systems, assigning *(T*)ptr throws a NRE if // the ptr isn't aligned (i.e. if Position is 1,2,3,5, etc.). // Here we have to use memcpy. @@ -33,145 +31,13 @@ public static unsafe void GetBytes(byte[] bytes, int startIndex, T value) whe // value types, but all blittable types are anyway. T* valueBuffer = stackalloc T[1] { value }; UnsafeUtility.MemCpy(ptr, valueBuffer, size); -#else + #else *(T*)ptr = value; -#endif + #endif } #endif } -#else - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, T value) where T : unmanaged - { - if (bytes.Length < startIndex + Unsafe.SizeOf()) - ThrowIndexOutOfRangeException(); - Unsafe.As(ref bytes[startIndex]) = value; - } -#endif private static void ThrowIndexOutOfRangeException() => throw new IndexOutOfRangeException(); -#else - [StructLayout(LayoutKind.Explicit)] - private struct ConverterHelperDouble - { - [FieldOffset(0)] - public ulong Along; - - [FieldOffset(0)] - public double Adouble; - } - - [StructLayout(LayoutKind.Explicit)] - private struct ConverterHelperFloat - { - [FieldOffset(0)] - public int Aint; - - [FieldOffset(0)] - public float Afloat; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteLittleEndian(byte[] buffer, int offset, ulong data) - { -#if BIGENDIAN - buffer[offset + 7] = (byte)(data); - buffer[offset + 6] = (byte)(data >> 8); - buffer[offset + 5] = (byte)(data >> 16); - buffer[offset + 4] = (byte)(data >> 24); - buffer[offset + 3] = (byte)(data >> 32); - buffer[offset + 2] = (byte)(data >> 40); - buffer[offset + 1] = (byte)(data >> 48); - buffer[offset ] = (byte)(data >> 56); -#else - buffer[offset] = (byte)(data); - buffer[offset + 1] = (byte)(data >> 8); - buffer[offset + 2] = (byte)(data >> 16); - buffer[offset + 3] = (byte)(data >> 24); - buffer[offset + 4] = (byte)(data >> 32); - buffer[offset + 5] = (byte)(data >> 40); - buffer[offset + 6] = (byte)(data >> 48); - buffer[offset + 7] = (byte)(data >> 56); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void WriteLittleEndian(byte[] buffer, int offset, int data) - { -#if BIGENDIAN - buffer[offset + 3] = (byte)(data); - buffer[offset + 2] = (byte)(data >> 8); - buffer[offset + 1] = (byte)(data >> 16); - buffer[offset ] = (byte)(data >> 24); -#else - buffer[offset] = (byte)(data); - buffer[offset + 1] = (byte)(data >> 8); - buffer[offset + 2] = (byte)(data >> 16); - buffer[offset + 3] = (byte)(data >> 24); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void WriteLittleEndian(byte[] buffer, int offset, short data) - { -#if BIGENDIAN - buffer[offset + 1] = (byte)(data); - buffer[offset ] = (byte)(data >> 8); -#else - buffer[offset] = (byte)(data); - buffer[offset + 1] = (byte)(data >> 8); -#endif - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, double value) - { - ConverterHelperDouble ch = new ConverterHelperDouble { Adouble = value }; - WriteLittleEndian(bytes, startIndex, ch.Along); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, float value) - { - ConverterHelperFloat ch = new ConverterHelperFloat { Afloat = value }; - WriteLittleEndian(bytes, startIndex, ch.Aint); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, short value) - { - WriteLittleEndian(bytes, startIndex, value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, ushort value) - { - WriteLittleEndian(bytes, startIndex, (short)value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, int value) - { - WriteLittleEndian(bytes, startIndex, value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, uint value) - { - WriteLittleEndian(bytes, startIndex, (int)value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, long value) - { - WriteLittleEndian(bytes, startIndex, (ulong)value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void GetBytes(byte[] bytes, int startIndex, ulong value) - { - WriteLittleEndian(bytes, startIndex, value); - } -#endif } } From 54eb7622f484de0b5f99e4db715197558b4825cd Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 25 Mar 2026 20:24:30 +0300 Subject: [PATCH 236/261] API Standardization --- LiteNetLib/Utils/NetDataReader.cs | 64 ++++++------------------------- LiteNetLib/Utils/NetDataWriter.cs | 2 +- 2 files changed, 13 insertions(+), 53 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index ae17b689..42647bac 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -412,21 +412,17 @@ public string[] GetStringArray(int maxStringLength) } /// Reads the next from the buffer. - public byte GetByte() - { - EnsureAvailable(1); - return _data[_position++]; - } + public byte GetByte() => GetUnmanaged(); /// Reads the next from the buffer. - public sbyte GetSByte() => (sbyte)GetByte(); + public sbyte GetSByte() => GetUnmanaged(); /// Reads a value from the current position. /// if the byte is 1; otherwise, . - public bool GetBool() => GetByte() == 1; + public bool GetBool() => GetUnmanaged(); /// Reads a value as a 2-byte . - public char GetChar() => (char)GetUShort(); + public char GetChar() => GetUnmanaged(); /// Reads a value using unmanaged memory access. public ushort GetUShort() => GetUnmanaged(); @@ -716,16 +712,16 @@ public unsafe T GetUnmanaged() where T : unmanaged #region PeekMethods /// Reads the at the current position without advancing the . - public byte PeekByte() => _data[_position]; + public byte PeekByte() => PeekUnmanaged(); /// Reads the at the current position without advancing the . - public sbyte PeekSByte() => (sbyte)PeekByte(); + public sbyte PeekSByte() => PeekUnmanaged(); /// Reads the at the current position without advancing the . - public bool PeekBool() => PeekByte() == 1; + public bool PeekBool() => PeekUnmanaged(); /// Reads the at the current position without advancing the . - public char PeekChar() => (char)PeekUShort(); + public char PeekChar() => PeekUnmanaged(); /// Reads the at the current position without advancing the . public ushort PeekUShort() => PeekUnmanaged(); @@ -808,58 +804,22 @@ public unsafe T PeekUnmanaged() where T : unmanaged /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetByte(out byte result) - { - if (AvailableBytes >= 1) - { - result = GetByte(); - return true; - } - result = 0; - return false; - } + public bool TryGetByte(out byte result) => TryGetUnmanaged(out result); /// Attempts to read an without throwing an exception. /// The deserialized , or 0 if failed. /// if enough data was available; otherwise, . - public bool TryGetSByte(out sbyte result) - { - if (AvailableBytes >= 1) - { - result = GetSByte(); - return true; - } - result = 0; - return false; - } + public bool TryGetSByte(out sbyte result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or if failed. /// if enough data was available; otherwise, . - public bool TryGetBool(out bool result) - { - if (AvailableBytes >= 1) - { - result = GetBool(); - return true; - } - result = false; - return false; - } + public bool TryGetBool(out bool result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or '\0' if failed. /// if enough data was available; otherwise, . - public bool TryGetChar(out char result) - { - if (!TryGetUShort(out ushort uShortValue)) - { - result = '\0'; - return false; - } - result = (char)uShortValue; - return true; - } + public bool TryGetChar(out char result) => TryGetUnmanaged(out result); /// Attempts to read a without throwing an exception. /// The deserialized , or 0 if failed. diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 80eed775..542d94f9 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -374,7 +374,7 @@ public void PutBytesWithLength(byte[] data, int offset, ushort length) /// Serializes a value as a single . ///
    /// The value to write. - public void Put(bool value) => Put((byte)(value ? 1 : 0)); + public void Put(bool value) => PutUnmanaged(value); /// /// Serializes an prefixed with a 2-byte length. From bcdbef38655771b38edd30e5f968c2df36415f8a Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 25 Mar 2026 21:57:22 +0300 Subject: [PATCH 237/261] Revert some changes --- LiteNetLib/Utils/NetDataReader.cs | 16 ++++++++++------ LiteNetLib/Utils/NetDataWriter.cs | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 42647bac..6ab35568 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -412,14 +412,18 @@ public string[] GetStringArray(int maxStringLength) } /// Reads the next from the buffer. - public byte GetByte() => GetUnmanaged(); + public byte GetByte() + { + EnsureAvailable(1); + return _data[_position++]; + } /// Reads the next from the buffer. - public sbyte GetSByte() => GetUnmanaged(); + public sbyte GetSByte() => (sbyte)GetByte(); /// Reads a value from the current position. /// if the byte is 1; otherwise, . - public bool GetBool() => GetUnmanaged(); + public bool GetBool() => GetByte() == 1; /// Reads a value as a 2-byte . public char GetChar() => GetUnmanaged(); @@ -712,13 +716,13 @@ public unsafe T GetUnmanaged() where T : unmanaged #region PeekMethods /// Reads the at the current position without advancing the . - public byte PeekByte() => PeekUnmanaged(); + public byte PeekByte() => _data[_position]; /// Reads the at the current position without advancing the . - public sbyte PeekSByte() => PeekUnmanaged(); + public sbyte PeekSByte() => (sbyte)PeekByte(); /// Reads the at the current position without advancing the . - public bool PeekBool() => PeekUnmanaged(); + public bool PeekBool() => PeekByte() == 1; /// Reads the at the current position without advancing the . public char PeekChar() => PeekUnmanaged(); diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 542d94f9..80eed775 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -374,7 +374,7 @@ public void PutBytesWithLength(byte[] data, int offset, ushort length) /// Serializes a value as a single . /// /// The value to write. - public void Put(bool value) => PutUnmanaged(value); + public void Put(bool value) => Put((byte)(value ? 1 : 0)); /// /// Serializes an prefixed with a 2-byte length. From bfe2282e796dc88ef0bcba3f2a358204b61ee04f Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Wed, 25 Mar 2026 20:26:42 +0100 Subject: [PATCH 238/261] Update docs --- LiteNetLib/BaseChannel.cs | 38 ++++++ LiteNetLib/ConnectionRequest.cs | 17 +++ LiteNetLib/INetEventListener.cs | 175 ++++++++++++++++++++++++- LiteNetLib/LiteNetManager.HashSet.cs | 2 +- LiteNetLib/LiteNetManager.cs | 8 ++ LiteNetLib/NatPunchModule.cs | 75 +++++++++++ LiteNetLib/NativeSocket.cs | 49 +++++++ LiteNetLib/NetConstants.cs | 49 ++++++- LiteNetLib/NetEvent.cs | 63 +++++++++ LiteNetLib/NetPacket.cs | 84 ++++++++++-- LiteNetLib/NetStatistics.cs | 54 ++++++++ LiteNetLib/NetUtils.cs | 22 ++++ LiteNetLib/Utils/FastBitConverter.cs | 10 ++ LiteNetLib/Utils/INetSerializable.cs | 15 +++ LiteNetLib/Utils/NetPacketProcessor.cs | 30 +++++ LiteNetLib/Utils/NtpRequest.cs | 24 ++++ LiteNetLib/Utils/Preserve.cs | 2 +- 17 files changed, 699 insertions(+), 18 deletions(-) diff --git a/LiteNetLib/BaseChannel.cs b/LiteNetLib/BaseChannel.cs index ce5ef10f..f8b6fd9c 100644 --- a/LiteNetLib/BaseChannel.cs +++ b/LiteNetLib/BaseChannel.cs @@ -3,17 +3,38 @@ namespace LiteNetLib { + /// + /// Base class for all communication channels (Reliable, Unreliable, Sequenced).
    + /// Handles the queuing and scheduling of outgoing packets. + ///
    internal abstract class BaseChannel { + /// + /// The peer associated with this channel. + /// protected readonly LiteNetPeer Peer; + /// + /// Queue containing packets waiting to be sent over the network. + /// protected readonly Queue OutgoingQueue = new Queue(NetConstants.DefaultWindowSize); private int _isAddedToPeerChannelSendQueue; + /// + /// Gets the number of packets currently residing in the outgoing queue. + /// public int PacketsInQueue => OutgoingQueue.Count; + /// + /// Initializes a new instance of the class. + /// + /// The peer that owns this channel. protected BaseChannel(LiteNetPeer peer) => Peer = peer; + /// + /// Adds a packet to the outgoing queue and notifies the peer to schedule a send update. + /// + /// The packet to be enqueued. public void AddToQueue(NetPacket packet) { lock (OutgoingQueue) @@ -23,12 +44,20 @@ public void AddToQueue(NetPacket packet) AddToPeerChannelSendQueue(); } + /// + /// Thread-safely marks this channel as having pending data and adds it to the peer's update list. + /// protected void AddToPeerChannelSendQueue() { if (Interlocked.CompareExchange(ref _isAddedToPeerChannelSendQueue, 1, 0) == 0) Peer.AddToReliableChannelSendQueue(this); } + /// + /// Attempts to send packets from the queue. If the queue becomes empty or throttled, + /// it resets the update flag. + /// + /// if there are still packets remaining to be sent in future updates. public bool SendAndCheckQueue() { bool hasPacketsToSend = SendNextPackets(); @@ -38,8 +67,17 @@ public bool SendAndCheckQueue() return hasPacketsToSend; } + /// + /// Abstract method to implement the specific logic for sending packets (e.g., windowing for reliable). + /// + /// if packets were sent and the channel should remain in the send queue. public abstract bool SendNextPackets(); + /// + /// Abstract method to handle an incoming packet received on this specific channel. + /// + /// The received packet. + /// if the packet was processed successfully. public abstract bool ProcessPacket(NetPacket packet); } } diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 3f770aa2..8fb15cf5 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -17,11 +17,17 @@ public class LiteConnectionRequest private readonly LiteNetManager _listener; private int _used; + /// + /// Data sent by the remote peer in the connection request. + /// public NetDataReader Data => InternalPacket.Data; internal ConnectionRequestResult Result { get; private set; } internal NetConnectRequestPacket InternalPacket; + /// + /// The remote endpoint (IP and Port) of the peer requesting the connection. + /// public readonly IPEndPoint RemoteEndPoint; internal void UpdateRequest(NetConnectRequestPacket connectRequest) @@ -47,6 +53,15 @@ internal LiteConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacke _listener = listener; } + /// + /// Accepts the connection if the first string in the matches the provided key. + /// + /// + /// This is a helper method for simple password/key validation. + /// If the key does not match or data is invalid, the connection is automatically rejected. + /// + /// The required string key to match. + /// A new if the key matches and connection is accepted; otherwise, null. public LiteNetPeer AcceptIfKey(string key) { if (!TryActivate()) @@ -164,8 +179,10 @@ internal ConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket re { } + /// public new NetPeer AcceptIfKey(string key) => (NetPeer)base.AcceptIfKey(key); + /// public new NetPeer Accept() => (NetPeer)base.Accept(); } } diff --git a/LiteNetLib/INetEventListener.cs b/LiteNetLib/INetEventListener.cs index bad9a074..17891c6e 100644 --- a/LiteNetLib/INetEventListener.cs +++ b/LiteNetLib/INetEventListener.cs @@ -224,37 +224,127 @@ void OnMessageDelivered(LiteNetPeer peer, object userData) { } ///
    public class EventBasedNetListener : INetEventListener { + /// + /// Delegate for the event that occurs when a new peer has successfully connected. + /// + /// The connected peer. public delegate void OnPeerConnected(NetPeer peer); + /// + /// Delegate for the event that occurs when a peer disconnects or the connection is lost. + /// + /// The disconnected peer. + /// Information regarding the reason and data associated with the disconnection. public delegate void OnPeerDisconnected(NetPeer peer, DisconnectInfo disconnectInfo); + /// + /// Delegate for the event that occurs when a network error is detected in the underlying socket. + /// + /// The endpoint associated with the error. + /// The specific socket error code. public delegate void OnNetworkError(IPEndPoint endPoint, SocketError socketError); + /// + /// Delegate for the event that occurs when data is received from a connected peer. + /// + /// The peer that sent the data. + /// The reader containing the received payload. + /// The channel on which the data was received. + /// The delivery method used for this packet. public delegate void OnNetworkReceive(NetPeer peer, NetPacketReader reader, byte channel, DeliveryMethod deliveryMethod); + /// + /// Delegate for the event that occurs when a message is received from an unconnected endpoint. + /// + /// The endpoint that sent the message. + /// The reader containing the received payload. + /// The type of unconnected message (e.g., Discovery or UnconnectedData). public delegate void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType); + /// + /// Delegate for the event that occurs when the round-trip time (RTT) to a peer is updated. + /// + /// The peer whose latency was updated. + /// The new latency value in milliseconds. public delegate void OnNetworkLatencyUpdate(NetPeer peer, int latency); + /// + /// Delegate for the event that occurs when a new connection request is received. + /// + /// The connection request object used to accept or reject the connection. public delegate void OnConnectionRequest(ConnectionRequest request); + /// + /// Delegate for the event that occurs when a reliable packet is successfully delivered or acknowledged. + /// + /// The peer that received the packet. + /// The custom user data that was attached to the sent packet. public delegate void OnDeliveryEvent(NetPeer peer, object userData); + /// + /// Delegate for the event that occurs when an NTP response is received from a time server. + /// + /// The NTP packet containing time information. public delegate void OnNtpResponseEvent(NtpPacket packet); + /// + /// Delegate for the event that occurs when a peer's remote address changes (roaming). + /// + /// The peer whose address changed. + /// The previous IP endpoint of the peer. public delegate void OnPeerAddressChangedEvent(NetPeer peer, IPEndPoint previousAddress); + /// + /// Occurs when a new peer has successfully connected. + /// public event OnPeerConnected PeerConnectedEvent; + /// + /// Occurs when a peer disconnects or the connection is lost. + /// public event OnPeerDisconnected PeerDisconnectedEvent; + /// + /// Occurs when a network error is detected in the underlying socket. + /// public event OnNetworkError NetworkErrorEvent; + /// + /// Occurs when data is received from a connected peer. + /// public event OnNetworkReceive NetworkReceiveEvent; + /// + /// Occurs when a message is received from an unconnected endpoint. + /// public event OnNetworkReceiveUnconnected NetworkReceiveUnconnectedEvent; + /// + /// Occurs when the round-trip time (RTT) to a peer is updated. + /// public event OnNetworkLatencyUpdate NetworkLatencyUpdateEvent; + /// + /// Occurs when a new connection request is received. + /// public event OnConnectionRequest ConnectionRequestEvent; + /// + /// Occurs when a reliable packet is successfully delivered or acknowledged. + /// public event OnDeliveryEvent DeliveryEvent; + /// + /// Occurs when an NTP response is received. + /// public event OnNtpResponseEvent NtpResponseEvent; + /// + /// Occurs when a peer's remote address changes. + /// public event OnPeerAddressChangedEvent PeerAddressChangedEvent; - public void ClearPeerConnectedEvent() => PeerConnectedEvent = null; + /// Clears all subscribers from . + public void ClearPeerConnectedEvent() => PeerConnectedEvent = null; + /// Clears all subscribers from . public void ClearPeerDisconnectedEvent() => PeerDisconnectedEvent = null; + /// Clears all subscribers from . public void ClearNetworkErrorEvent() => NetworkErrorEvent = null; + /// Clears all subscribers from . public void ClearNetworkReceiveEvent() => NetworkReceiveEvent = null; + /// Clears all subscribers from . public void ClearNetworkReceiveUnconnectedEvent() => NetworkReceiveUnconnectedEvent = null; + /// Clears all subscribers from . public void ClearNetworkLatencyUpdateEvent() => NetworkLatencyUpdateEvent = null; + /// Clears all subscribers from . public void ClearConnectionRequestEvent() => ConnectionRequestEvent = null; + /// Clears all subscribers from . public void ClearDeliveryEvent() => DeliveryEvent = null; + /// Clears all subscribers from . public void ClearNtpResponseEvent() => NtpResponseEvent = null; + /// Clears all subscribers from . public void ClearPeerAddressChangedEvent() => PeerAddressChangedEvent = null; void INetEventListener.OnPeerConnected(NetPeer peer) => @@ -293,34 +383,115 @@ void INetEventListener.OnPeerAddressChanged(NetPeer peer, IPEndPoint previousAdd ///
    public class EventBasedLiteNetListener : ILiteNetEventListener { + /// + /// Delegate for the event that occurs when a new peer has successfully connected. + /// + /// The connected peer. public delegate void OnPeerConnected(LiteNetPeer peer); + /// + /// Delegate for the event that occurs when a peer disconnects or the connection is lost. + /// + /// The disconnected peer. + /// Information regarding the reason and data associated with the disconnection. public delegate void OnPeerDisconnected(LiteNetPeer peer, DisconnectInfo disconnectInfo); + /// + /// Delegate for the event that occurs when a network error is detected in the underlying socket. + /// + /// The endpoint associated with the error. + /// The specific socket error code. public delegate void OnNetworkError(IPEndPoint endPoint, SocketError socketError); + /// + /// Delegate for the event that occurs when data is received from a connected peer. + /// + /// The peer that sent the data. + /// The reader containing the received payload. + /// The delivery method used for this packet. public delegate void OnNetworkReceive(LiteNetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod); + /// + /// Delegate for the event that occurs when a message is received from an unconnected endpoint. + /// + /// The endpoint that sent the message. + /// The reader containing the received payload. + /// The type of unconnected message (e.g., Discovery or UnconnectedData). public delegate void OnNetworkReceiveUnconnected(IPEndPoint remoteEndPoint, NetPacketReader reader, UnconnectedMessageType messageType); + /// + /// Delegate for the event that occurs when the round-trip time (RTT) to a peer is updated. + /// + /// The peer whose latency was updated. + /// The new latency value in milliseconds. public delegate void OnNetworkLatencyUpdate(LiteNetPeer peer, int latency); + /// + /// Delegate for the event that occurs when a new connection request is received. + /// + /// The connection request object used to accept or reject the connection. public delegate void OnConnectionRequest(LiteConnectionRequest request); + /// + /// Delegate for the event that occurs when a reliable packet is successfully delivered or acknowledged. + /// + /// The peer that received the packet. + /// The custom user data that was attached to the sent packet. public delegate void OnDeliveryEvent(LiteNetPeer peer, object userData); + /// + /// Delegate for the event that occurs when a peer's remote address changes (roaming). + /// + /// The peer whose address changed. + /// The previous IP endpoint of the peer. public delegate void OnPeerAddressChangedEvent(LiteNetPeer peer, IPEndPoint previousAddress); + /// + /// Occurs when a new peer has successfully connected. + /// public event OnPeerConnected PeerConnectedEvent; + /// + /// Occurs when a peer disconnects or the connection is lost. + /// public event OnPeerDisconnected PeerDisconnectedEvent; + /// + /// Occurs when a network error is detected in the underlying socket. + /// public event OnNetworkError NetworkErrorEvent; + /// + /// Occurs when data is received from a connected peer. + /// public event OnNetworkReceive NetworkReceiveEvent; + /// + /// Occurs when a message is received from an unconnected endpoint. + /// public event OnNetworkReceiveUnconnected NetworkReceiveUnconnectedEvent; + /// + /// Occurs when the round-trip time (RTT) to a peer is updated. + /// public event OnNetworkLatencyUpdate NetworkLatencyUpdateEvent; + /// + /// Occurs when a new connection request is received. + /// public event OnConnectionRequest ConnectionRequestEvent; + /// + /// Occurs when a reliable packet is successfully delivered or acknowledged. + /// public event OnDeliveryEvent DeliveryEvent; + /// + /// Occurs when a peer's remote address changes. + /// public event OnPeerAddressChangedEvent PeerAddressChangedEvent; - public void ClearPeerConnectedEvent() => PeerConnectedEvent = null; + /// Clears all subscribers from . + public void ClearPeerConnectedEvent() => PeerConnectedEvent = null; + /// Clears all subscribers from . public void ClearPeerDisconnectedEvent() => PeerDisconnectedEvent = null; + /// Clears all subscribers from . public void ClearNetworkErrorEvent() => NetworkErrorEvent = null; + /// Clears all subscribers from . public void ClearNetworkReceiveEvent() => NetworkReceiveEvent = null; + /// Clears all subscribers from . public void ClearNetworkReceiveUnconnectedEvent() => NetworkReceiveUnconnectedEvent = null; + /// Clears all subscribers from . public void ClearNetworkLatencyUpdateEvent() => NetworkLatencyUpdateEvent = null; + /// Clears all subscribers from . public void ClearConnectionRequestEvent() => ConnectionRequestEvent = null; + /// Clears all subscribers from . public void ClearDeliveryEvent() => DeliveryEvent = null; + /// Clears all subscribers from . public void ClearPeerAddressChangedEvent() => PeerAddressChangedEvent = null; void ILiteNetEventListener.OnPeerConnected(LiteNetPeer peer) => diff --git a/LiteNetLib/LiteNetManager.HashSet.cs b/LiteNetLib/LiteNetManager.HashSet.cs index 9d5fe2e3..11fdd114 100644 --- a/LiteNetLib/LiteNetManager.HashSet.cs +++ b/LiteNetLib/LiteNetManager.HashSet.cs @@ -118,7 +118,7 @@ public LiteNetPeer GetPeerById(int id) ///
    /// id of peer /// resulting peer - /// True if peer with id exist, otherwise false + /// if peer with id exist; otherwise public bool TryGetPeerById(int id, out LiteNetPeer peer) { peer = GetPeerById(id); diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index 194b0b05..5769b888 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -269,6 +269,14 @@ private struct OutboundDelayedPacket ///
    public int ConnectedPeersCount => (int)Interlocked.Read(ref _connectedPeersCount); + /// + /// Gets the additional size in bytes required by the active . + /// + /// + /// This value is used by to calculate the available MTU for user data.
    + /// If a packet layer is active (e.g., for encryption or CRC), this returns the overhead added to every packet. + /// Returns 0 if no packet layer is assigned. + ///
    public int ExtraPacketSizeForLayer => _extraPacketLayer?.ExtraPacketSizeForLayer ?? 0; /// diff --git a/LiteNetLib/NatPunchModule.cs b/LiteNetLib/NatPunchModule.cs index a124eb86..94251a86 100644 --- a/LiteNetLib/NatPunchModule.cs +++ b/LiteNetLib/NatPunchModule.cs @@ -6,24 +6,66 @@ namespace LiteNetLib { + /// + /// Specifies the type of network address discovered during NAT punchthrough. + /// public enum NatAddressType { + /// + /// Address within the local area network (LAN). + /// Internal, + /// + /// Publicly accessible address on the wide area network (WAN). + /// External } + /// + /// Interface for handling events related to NAT punchthrough and introduction. + /// public interface INatPunchListener { + /// + /// Called when a NAT introduction request is received from the mediator server. + /// + /// The local endpoint of the client requesting connection. + /// The remote endpoint of the client requesting connection. + /// Custom data token associated with the request. void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token); + + /// + /// Called when NAT punchthrough is successful and a direct connection can be established. + /// + /// The resolved endpoint of the remote peer. + /// The type of address (Internal or External) that succeeded. + /// Custom data token associated with the request. void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token); } + /// + /// An implementation of that maps callbacks to events. + /// public class EventBasedNatPunchListener : INatPunchListener { + /// + /// Delegate for NAT introduction request events. + /// public delegate void OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token); + + /// + /// Delegate for NAT introduction success events. + /// public delegate void OnNatIntroductionSuccess(IPEndPoint targetEndPoint, NatAddressType type, string token); + /// + /// Event triggered when a NAT introduction request is received. + /// public event OnNatIntroductionRequest NatIntroductionRequest; + + /// + /// Event triggered when NAT punchthrough is successfully completed. + /// public event OnNatIntroductionSuccess NatIntroductionSuccess; void INatPunchListener.OnNatIntroductionRequest(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, string token) @@ -84,6 +126,9 @@ class NatPunchPacket private readonly NetDataWriter _cacheWriter = new NetDataWriter(); private readonly NetPacketProcessor _netPacketProcessor = new NetPacketProcessor(MaxTokenLength); private INatPunchListener _natPunchListener; + /// + /// Maximum allowed length for the NAT introduction token string. + /// public const int MaxTokenLength = 256; /// @@ -108,6 +153,10 @@ internal void ProcessMessage(IPEndPoint senderEndPoint, NetPacket packet) } } + /// + /// Initializes the NAT punch module with a listener to handle punchthrough events. + /// + /// The listener implementation that will receive NAT events. public void Init(INatPunchListener listener) { _natPunchListener = listener; @@ -125,6 +174,15 @@ private void Send< _socket.SendRaw(_cacheWriter.Data, 0, _cacheWriter.Length, target); } + /// + /// Sends NAT introduction packets to both the host and the client to facilitate punchthrough. + /// This is typically called by a mediator (Master Server). + /// + /// Internal (LAN) endpoint of the host. + /// External (WAN) endpoint of the host. + /// Internal (LAN) endpoint of the client. + /// External (WAN) endpoint of the client. + /// Custom token or data to include in the introduction. public void NatIntroduce( IPEndPoint hostInternal, IPEndPoint hostExternal, @@ -148,6 +206,12 @@ public void NatIntroduce( Send(req, hostExternal); } + /// + /// Triggers queued NAT punchthrough events (Success or Request) on the provided . + /// + /// + /// This should be called from the main thread if is . + /// public void PollEvents() { if (UnsyncedEvents) @@ -170,11 +234,22 @@ public void PollEvents() } } + /// + /// Sends a request to the Master Server to introduce this peer to another peer. + /// + /// The hostname or IP of the Master Server. + /// The port of the Master Server. + /// Custom token to identify the connection or room. public void SendNatIntroduceRequest(string host, int port, string additionalInfo) { SendNatIntroduceRequest(NetUtils.MakeEndPoint(host, port), additionalInfo); } + /// + /// Sends a request to the Master Server to introduce this peer to another peer. + /// + /// The endpoint of the Master Server. + /// Custom token to identify the connection or room. public void SendNatIntroduceRequest(IPEndPoint masterServerEndPoint, string additionalInfo) { //prepare outgoing data diff --git a/LiteNetLib/NativeSocket.cs b/LiteNetLib/NativeSocket.cs index 5bac9e59..84ecedc4 100644 --- a/LiteNetLib/NativeSocket.cs +++ b/LiteNetLib/NativeSocket.cs @@ -55,12 +55,30 @@ internal static extern int sendto( [In] int socketAddressSize); } + /// + /// Indicates whether the native socket optimizations are supported on the current platform. + /// public static readonly bool IsSupported = false; + /// + /// Indicates whether the current environment requires Unix-style native socket calls. + /// public static readonly bool UnixMode = false; + /// + /// The size of the native sockaddr_in structure for IPv4. + /// public const int IPv4AddrSize = 16; + /// + /// The size of the native sockaddr_in6 structure for IPv6. + /// public const int IPv6AddrSize = 28; + /// + /// Native Address Family constant for IPv4 (AF_INET). + /// public const int AF_INET = 2; + /// + /// Native Address Family constant for IPv6 (AF_INET6). + /// public const int AF_INET6 = 10; private static readonly Dictionary NativeErrorToSocketError = new Dictionary @@ -122,6 +140,15 @@ static NativeSocket() } } + /// + /// Receives a datagram from the specified socket handle using native OS calls. + /// + /// The OS handle for the socket. + /// A pinned byte array to receive the data. + /// The number of s to receive. + /// A pinned byte array to store the source address (sockaddr). + /// The size of the structure. + /// The number of s received, or a negative value on error. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int RecvFrom( IntPtr socketHandle, @@ -133,6 +160,15 @@ public static int RecvFrom( ? UnixSock.recvfrom(socketHandle, pinnedBuffer, len, 0, socketAddress, ref socketAddressSize) : WinSock.recvfrom(socketHandle, pinnedBuffer, len, 0, socketAddress, ref socketAddressSize); + /// + /// Sends a datagram to the specified socket handle using native OS calls. + /// + /// The OS handle for the socket. + /// A pointer to the pinned memory containing data to send. + /// The number of s to send. + /// A pinned byte array containing the destination address (sockaddr). + /// The size of the structure. + /// The number of s sent, or a negative value on error. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe int SendTo( IntPtr socketHandle, @@ -144,6 +180,10 @@ public static unsafe int SendTo( ? UnixSock.sendto(socketHandle, pinnedBuffer, len, 0, socketAddress, socketAddressSize) : WinSock.sendto(socketHandle, pinnedBuffer, len, 0, socketAddress, socketAddressSize); + /// + /// Retrieves the last OS-specific socket error and translates it to . + /// + /// The translated . public static SocketError GetSocketError() { int error = Marshal.GetLastWin32Error(); @@ -154,6 +194,10 @@ public static SocketError GetSocketError() return (SocketError)error; } + /// + /// Retrieves the last OS-specific socket error and encapsulates it in a . + /// + /// A representing the last native error. public static SocketException GetSocketException() { int error = Marshal.GetLastWin32Error(); @@ -164,6 +208,11 @@ public static SocketException GetSocketException() return new SocketException(error); } + /// + /// Converts the of an endpoint to the corresponding native constant. + /// + /// The endpoint to evaluate. + /// The native address family identifier. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short GetNativeAddressFamily(IPEndPoint remoteEndPoint) => UnixMode diff --git a/LiteNetLib/NetConstants.cs b/LiteNetLib/NetConstants.cs index 31495d10..75dbea85 100644 --- a/LiteNetLib/NetConstants.cs +++ b/LiteNetLib/NetConstants.cs @@ -37,16 +37,46 @@ public enum DeliveryMethod : byte /// public static class NetConstants { - //can be tuned + /// + /// Default window size for reliable channels (number of packets). + /// public const int DefaultWindowSize = 64; - public const int SocketBufferSize = 1024 * 1024; //1mb + /// + /// Size of the underlying UDP socket receive and send buffers in bytes.
    + /// Default is 1MB. + ///
    + public const int SocketBufferSize = 1024 * 1024; + /// + /// Time To Live (TTL) for the UDP packets. + /// public const int SocketTTL = 255; + /// + /// Size of the base packet header (PacketProperty) in s. + /// public const int HeaderSize = 1; + /// + /// Size of the header for sequenced or reliable messages in s.
    + /// Includes , Sequence, and ChannelId. + ///
    public const int ChanneledHeaderSize = 4; + /// + /// Additional header size required for fragmented packets in s.
    + /// Includes FragmentId, FragmentPart, and FragmentsTotal. + ///
    public const int FragmentHeaderSize = 6; + /// + /// Total header size for a fragmented channeled packet in s.
    + /// Combines and . + ///
    public const int FragmentedHeaderTotalSize = ChanneledHeaderSize + FragmentHeaderSize; + /// + /// Maximum possible sequence number before wrapping back to zero. + /// public const ushort MaxSequence = 32768; + /// + /// Half of the , used for sequence comparison and wrap-around logic. + /// public const ushort HalfMaxSequence = MaxSequence / 2; //protocol @@ -67,12 +97,23 @@ public static class NetConstants 1500 - MaxUdpHeaderSize //Ethernet II (RFC 1191) }; - //Max possible single packet size + /// + /// The starting Maximum Transmission Unit (MTU) used for new connections before path MTU discovery. + /// public static readonly int InitialMtu = PossibleMtu[0]; + /// + /// Maximum possible packet size allowed by the library based on the largest supported MTU. + /// public static readonly int MaxPacketSize = PossibleMtu[PossibleMtu.Length - 1]; + /// + /// Maximum payload size for a single unreliable packet in s.
    + /// Calculated as - . + ///
    public static readonly int MaxUnreliableDataSize = MaxPacketSize - HeaderSize; - //peer specific + /// + /// Maximum number of simultaneous connection attempts (pending connections) allowed per peer. + /// public const byte MaxConnectionNumber = 4; } } diff --git a/LiteNetLib/NetEvent.cs b/LiteNetLib/NetEvent.cs index b54f60aa..7b701e69 100644 --- a/LiteNetLib/NetEvent.cs +++ b/LiteNetLib/NetEvent.cs @@ -8,34 +8,97 @@ namespace LiteNetLib ///
    public sealed class NetEvent { + /// + /// Reference to the next event in the pool or event queue. + /// public NetEvent Next; + /// + /// Specifies the category of the network event. + /// public enum EType { + /// New peer connected. Connect, + /// Peer disconnected. Disconnect, + /// Data received from a connected peer. Receive, + /// Unconnected message received. ReceiveUnconnected, + /// Socket or internal protocol error occurred. Error, + /// Round-trip time (RTT) for a peer has been updated. ConnectionLatencyUpdated, + /// Broadcast message received. Broadcast, + /// Incoming connection request from a new peer. ConnectionRequest, + /// Reliable message was successfully delivered to the remote peer. MessageDelivered, + /// The IP address or port of an existing peer has changed (e.g., roaming). PeerAddressChanged } + + /// + /// The type of network event that occurred. + /// public EType Type; + /// + /// The peer associated with this event. for unconnected events. + /// public LiteNetPeer Peer; + + /// + /// The remote endpoint (IP and Port) from which the event originated. + /// public IPEndPoint RemoteEndPoint; + + /// + /// Optional user data associated with a connection request or disconnect. + /// public object UserData; + + /// + /// The updated latency value in milliseconds. Only valid when is . + /// public int Latency; + + /// + /// The specific socket error. Only valid when is . + /// public SocketError ErrorCode; + + /// + /// The reason for a peer's disconnection. Only valid when is . + /// public DisconnectReason DisconnectReason; + + /// + /// Information about an incoming connection. Only valid when is . + /// public LiteConnectionRequest ConnectionRequest; + + /// + /// The delivery method used for the received packet. Only valid when is . + /// public DeliveryMethod DeliveryMethod; + + /// + /// The channel on which the packet was received. + /// public byte ChannelNumber; + + /// + /// A reader for accessing the payload of received data, broadcast, or unconnected messages. + /// public readonly NetPacketReader DataReader; + /// + /// Initializes a new instance of the class. + /// + /// The that owns the packet pool and buffers for this event. public NetEvent(LiteNetManager manager) { DataReader = new NetPacketReader(manager, this); diff --git a/LiteNetLib/NetPacket.cs b/LiteNetLib/NetPacket.cs index 495e6ad9..e22541ff 100644 --- a/LiteNetLib/NetPacket.cs +++ b/LiteNetLib/NetPacket.cs @@ -66,81 +66,145 @@ static NetPacket() } } - //Header + /// + /// Gets or sets the packet property (type). + /// Stored in the first 5 bits of the first byte (0x1F mask). + /// public PacketProperty Property { get => (PacketProperty)(RawData[0] & 0x1F); set => RawData[0] = (byte)((RawData[0] & 0xE0) | (byte)value); } + /// + /// Gets or sets the connection number used to distinguish between multiple connections from the same endpoint.
    + /// Stored in bits 6 and 7 of the first byte (0x60 mask). + ///
    public byte ConnectionNumber { get => (byte)((RawData[0] & 0x60) >> 5); - set => RawData[0] = (byte) ((RawData[0] & 0x9F) | (value << 5)); + set => RawData[0] = (byte)((RawData[0] & 0x9F) | (value << 5)); } + /// + /// Gets or sets the sequence number of the packet. + /// Located at offset 1 in . + /// public ushort Sequence { get => BitConverter.ToUInt16(RawData, 1); set => FastBitConverter.GetBytes(RawData, 1, value); } + /// + /// Returns if the fragmentation bit (the highest bit of the first byte) is set. + /// public bool IsFragmented => (RawData[0] & 0x80) != 0; - public void MarkFragmented() => RawData[0] |= 0x80; //set first bit + /// + /// Sets the fragmentation bit (0x80) in the packet header. + /// + public void MarkFragmented() => RawData[0] |= 0x80; + /// + /// Gets or sets the channel identifier. + /// Located at offset 3 in . + /// public byte ChannelId { get => RawData[3]; set => RawData[3] = value; } + /// + /// Gets or sets the unique identifier for a fragmented message. + /// Located at offset 4 in . + /// public ushort FragmentId { get => BitConverter.ToUInt16(RawData, 4); set => FastBitConverter.GetBytes(RawData, 4, value); } + /// + /// Gets or sets the index of the current fragment part. + /// Located at offset 6 in . + /// public ushort FragmentPart { get => BitConverter.ToUInt16(RawData, 6); set => FastBitConverter.GetBytes(RawData, 6, value); } + /// + /// Gets or sets the total number of fragments in the message. + /// Located at offset 8 in . + /// public ushort FragmentsTotal { get => BitConverter.ToUInt16(RawData, 8); set => FastBitConverter.GetBytes(RawData, 8, value); } - //Data + /// + /// The raw array containing the packet header and payload. + /// public byte[] RawData; + + /// + /// The actual size of the data in , including headers. + /// public int Size; - //Delivery + /// + /// Custom user data associated with this packet. Used for delivery notifications. + /// public object UserData; - //Pool node + /// + /// Reference to the next packet in the NetPacketPool. + /// public NetPacket Next; + /// + /// Initializes a new instance of the class with a specific buffer size. + /// + /// Total size of the packet including headers. public NetPacket(int size) { RawData = new byte[size]; Size = size; } - public NetPacket(PacketProperty property, int size) + /// + /// Initializes a new instance of the class, calculating the required size based on the property. + /// + /// The type of packet to create. + /// Size of the user data payload. + public NetPacket(PacketProperty property, int payloadSize) { - size += GetHeaderSize(property); - RawData = new byte[size]; + int totalSize = payloadSize + GetHeaderSize(property); + RawData = new byte[totalSize]; Property = property; - Size = size; + Size = totalSize; } + /// + /// Gets the fixed header size for a specific . + /// + /// The packet type. + /// Header size in bytes. public static int GetHeaderSize(PacketProperty property) => HeaderSizes[(int)property]; + /// + /// Gets the header size of the current packet based on its property bits. + /// public int HeaderSize => HeaderSizes[RawData[0] & 0x1F]; + /// + /// Performs a basic sanity check on the packet header and size. + /// + /// True if the packet property is valid and the size is sufficient for the headers. public bool Verify() { byte property = (byte)(RawData[0] & 0x1F); diff --git a/LiteNetLib/NetStatistics.cs b/LiteNetLib/NetStatistics.cs index 5b3d8fd2..e2d0304c 100644 --- a/LiteNetLib/NetStatistics.cs +++ b/LiteNetLib/NetStatistics.cs @@ -2,6 +2,9 @@ namespace LiteNetLib { + /// + /// Thread-safe counter for network statistics including sent/received packets, bytes, and packet loss. + /// public sealed class NetStatistics { private long _packetsSent; @@ -10,12 +13,35 @@ public sealed class NetStatistics private long _bytesReceived; private long _packetLoss; + /// + /// Total number of packets sent. + /// public long PacketsSent => Interlocked.Read(ref _packetsSent); + + /// + /// Total number of packets received. + /// public long PacketsReceived => Interlocked.Read(ref _packetsReceived); + + /// + /// Total number of bytes sent. + /// public long BytesSent => Interlocked.Read(ref _bytesSent); + + /// + /// Total number of bytes received. + /// public long BytesReceived => Interlocked.Read(ref _bytesReceived); + + /// + /// Total number of packets lost during transmission. + /// public long PacketLoss => Interlocked.Read(ref _packetLoss); + /// + /// Percentage of sent packets that were lost. + /// Calculated as (PacketLoss * 100) / PacketsSent. + /// public long PacketLossPercent { get @@ -26,6 +52,9 @@ public long PacketLossPercent } } + /// + /// Resets all statistical counters to zero. + /// public void Reset() { Interlocked.Exchange(ref _packetsSent, 0); @@ -35,24 +64,49 @@ public void Reset() Interlocked.Exchange(ref _packetLoss, 0); } + /// + /// Increments the count of sent packets by one. + /// public void IncrementPacketsSent() => Interlocked.Increment(ref _packetsSent); + /// + /// Increments the count of received packets by one. + /// public void IncrementPacketsReceived() => Interlocked.Increment(ref _packetsReceived); + /// + /// Adds a specific amount to the total bytes sent. + /// + /// Number of bytes to add. public void AddBytesSent(long bytesSent) => Interlocked.Add(ref _bytesSent, bytesSent); + /// + /// Adds a specific amount to the total bytes received. + /// + /// Number of bytes to add. public void AddBytesReceived(long bytesReceived) => Interlocked.Add(ref _bytesReceived, bytesReceived); + /// + /// Increments the count of lost packets by one. + /// public void IncrementPacketLoss() => Interlocked.Increment(ref _packetLoss); + /// + /// Adds a specific amount to the total packet loss count. + /// + /// Number of lost packets to add. public void AddPacketLoss(long packetLoss) => Interlocked.Add(ref _packetLoss, packetLoss); + /// + /// Returns a string representation of the current network statistics. + /// + /// A formatted string containing bytes received/sent, packets received/sent, and loss information. public override string ToString() { return diff --git a/LiteNetLib/NetUtils.cs b/LiteNetLib/NetUtils.cs index 9d9ab733..593c2f2a 100644 --- a/LiteNetLib/NetUtils.cs +++ b/LiteNetLib/NetUtils.cs @@ -25,9 +25,25 @@ public static class NetUtils { private static readonly NetworkSorter NetworkSorter = new NetworkSorter(); + /// + /// Creates an from a host string and a port. + /// + /// The host name or IP address string to resolve. + /// The port number for the endpoint. + /// A new instance. public static IPEndPoint MakeEndPoint(string hostStr, int port) => new IPEndPoint(ResolveAddress(hostStr), port); + /// + /// Resolves a host string into an . + /// + /// + /// This method handles "localhost" specifically, attempts to parse the string as a direct IP, + /// and falls back to DNS resolution. It prioritizes IPv6 if is enabled. + /// + /// The host name or IP address string (e.g., "127.0.0.1", "localhost", or "google.com"). + /// The resolved . + /// Thrown when the address cannot be resolved or is invalid. public static IPAddress ResolveAddress(string hostStr) { if(hostStr == "localhost") @@ -46,6 +62,12 @@ public static IPAddress ResolveAddress(string hostStr) return ipAddress; } + /// + /// Resolves a host string using DNS for a specific . + /// + /// The host name to resolve via DNS. + /// The preferred address family (e.g., or ). + /// The first matching the family, or if no match is found. public static IPAddress ResolveAddress(string hostStr, AddressFamily addressFamily) { IPAddress[] addresses = Dns.GetHostEntry(hostStr).AddressList; diff --git a/LiteNetLib/Utils/FastBitConverter.cs b/LiteNetLib/Utils/FastBitConverter.cs index 1a6c3287..202cf134 100644 --- a/LiteNetLib/Utils/FastBitConverter.cs +++ b/LiteNetLib/Utils/FastBitConverter.cs @@ -8,6 +8,16 @@ namespace LiteNetLib.Utils { public static class FastBitConverter { + /// + /// Converts a value of type into a byte array starting at the specified index. + /// + /// The type of the value to convert. Must be an unmanaged/blittable type. + /// The destination byte array. + /// The zero-based index in at which to begin writing. + /// The value to be converted and written. + /// + /// Thrown when the array is too small to contain the value at the given . + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void GetBytes(byte[] bytes, int startIndex, T value) where T : unmanaged { diff --git a/LiteNetLib/Utils/INetSerializable.cs b/LiteNetLib/Utils/INetSerializable.cs index 92f14bee..423e0468 100644 --- a/LiteNetLib/Utils/INetSerializable.cs +++ b/LiteNetLib/Utils/INetSerializable.cs @@ -1,8 +1,23 @@ namespace LiteNetLib.Utils { + /// + /// Interface for implementing custom data serialization for network transmission. + /// + /// + /// This is the most efficient way to send complex objects as it avoids reflection. + /// public interface INetSerializable { + /// + /// Writes the object data into the provided . + /// + /// The writer to pack data into. void Serialize(NetDataWriter writer); + + /// + /// Reads the object data from the provided . + /// + /// The reader to extract data from. void Deserialize(NetDataReader reader); } } diff --git a/LiteNetLib/Utils/NetPacketProcessor.cs b/LiteNetLib/Utils/NetPacketProcessor.cs index c18683e5..e3d8d981 100644 --- a/LiteNetLib/Utils/NetPacketProcessor.cs +++ b/LiteNetLib/Utils/NetPacketProcessor.cs @@ -229,6 +229,13 @@ public void SubscribeReusable< }; } + /// + /// Registers a callback for a packet type that implements , using a custom constructor and supporting user data. + /// + /// The type of the packet. Must implement . + /// The type of the user data (typically ). + /// The delegate to be executed when the packet is received. + /// A function that returns a new instance of . public void SubscribeNetSerializable( Action onReceive, Func packetConstructor) where T : INetSerializable @@ -241,6 +248,12 @@ public void SubscribeNetSerializable( }; } + /// + /// Registers a callback for a packet type that implements , using a custom constructor. + /// + /// The type of the packet. Must implement . + /// The delegate to be executed when the packet is received. + /// A function that returns a new instance of . public void SubscribeNetSerializable( Action onReceive, Func packetConstructor) where T : INetSerializable @@ -253,6 +266,15 @@ public void SubscribeNetSerializable( }; } + /// + /// Registers a callback for a packet type that implements and has a parameterless constructor, supporting user data. + /// + /// + /// To reduce allocations, this method uses a single internal reference to for deserialization. + /// + /// The type of the packet. Must implement and have a () constraint. + /// The type of the user data (typically ). + /// The delegate to be executed when the packet is received. public void SubscribeNetSerializable( Action onReceive) where T : INetSerializable, new() { @@ -264,6 +286,14 @@ public void SubscribeNetSerializable( }; } + /// + /// Registers a callback for a packet type that implements and has a parameterless constructor. + /// + /// + /// To reduce allocations, this method uses a single internal reference to for deserialization. + /// + /// The type of the packet. Must implement and have a () constraint. + /// The delegate to be executed when the packet is received. public void SubscribeNetSerializable( Action onReceive) where T : INetSerializable, new() { diff --git a/LiteNetLib/Utils/NtpRequest.cs b/LiteNetLib/Utils/NtpRequest.cs index ca83c8d0..dc0c2aed 100644 --- a/LiteNetLib/Utils/NtpRequest.cs +++ b/LiteNetLib/Utils/NtpRequest.cs @@ -3,22 +3,46 @@ namespace LiteNetLib.Utils { + /// + /// Represents an active NTP (Network Time Protocol) query to a remote time server. + /// Handles retransmission and lifetime management of the request. + /// internal sealed class NtpRequest { private const int ResendTimer = 1000; private const int KillTimer = 10000; + /// + /// Standard UDP port used by NTP servers. + /// public const int DefaultPort = 123; private readonly IPEndPoint _ntpEndPoint; private float _resendTime = ResendTimer; private float _killTime = 0; + /// + /// Initializes a new instance of the class for a specific server. + /// + /// The IP endpoint of the NTP server. public NtpRequest(IPEndPoint endPoint) { _ntpEndPoint = endPoint; } + /// + /// Gets a value indicating whether the request has exceeded its maximum lifetime and should be removed. + /// public bool NeedToKill => _killTime >= KillTimer; + /// + /// Attempts to send an NTP query packet to the remote endpoint. + /// + /// + /// The packet is only sent if the internal retransmission timer has elapsed. + /// Updates internal timers for both retransmission and total lifetime. + /// + /// The underlying socket used to send the datagram. + /// The amount of time elapsed since the last update/call, in seconds. + /// if the packet was successfully transmitted; otherwise, . public bool Send(Socket socket, float time) { _resendTime += time; diff --git a/LiteNetLib/Utils/Preserve.cs b/LiteNetLib/Utils/Preserve.cs index b73e1b90..057798b9 100644 --- a/LiteNetLib/Utils/Preserve.cs +++ b/LiteNetLib/Utils/Preserve.cs @@ -3,7 +3,7 @@ namespace LiteNetLib.Utils { /// - /// PreserveAttribute prevents byte code stripping from removing a class, method, field, or property. + /// PreserveAttribute prevents byte code stripping from removing a class, method, field, or property. /// [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] public class PreserveAttribute : Attribute From f20ced73612f1a496f5566565670e1769df5584e Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 25 Mar 2026 22:28:51 +0300 Subject: [PATCH 239/261] ResizeIfNeed now throws error if need resize but !_autoResize --- LiteNetLib/Utils/NetDataWriter.cs | 89 +++++++++++++++++-------------- 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 80eed775..4a508b44 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -125,36 +125,56 @@ public static NetDataWriter FromString(string value) } /// - /// Ensures the internal buffer is at least . + /// Ensures that the internal buffer is at least bytes long. /// /// The required minimum size of the buffer. - /// - /// If an allocation is necessary, the buffer grows to either - /// or doubles its current size, whichever is larger. - /// + /// + /// Thrown when exceeds the current buffer capacity + /// and automatic resizing is disabled. + /// + /// + /// Thrown when is negative. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ResizeIfNeed(int newSize) { - if (_data.Length < newSize) - { - Array.Resize(ref _data, Math.Max(newSize, _data.Length * 2)); - } + if (newSize < 0) + ThrowCapacityExceeded(newSize); + + if (_data.Length >= newSize) + return; + + if (!_autoResize) + ThrowCapacityExceeded(newSize); + + Array.Resize(ref _data, Math.Max(newSize, _data.Length * 2)); } /// - /// Ensures the internal buffer can accommodate more s. + /// Throws an indicating that the buffer capacity was exceeded + /// while automatic resizing is disabled. /// - /// The number of additional s to fit. - /// - /// This checks against the current . If the capacity is insufficient, - /// the buffer grows to either the required size or doubles its current size. - /// + /// The total buffer size that was required. + /// Always thrown. + [MethodImpl(MethodImplOptions.NoInlining)] + private void ThrowCapacityExceeded(int requiredSize) + { + throw new InvalidOperationException( + $"Not enough capacity to write {requiredSize - _position} byte(s). " + + $"Position={_position}, Capacity={_data.Length}, RequiredSize={requiredSize}"); + } + + /// + /// Ensures that the internal buffer can accommodate more bytes + /// from the current write position. + /// + /// The number of additional bytes that must fit. [MethodImpl(MethodImplOptions.AggressiveInlining)] public void EnsureFit(int additionalSize) { - if (_data.Length < _position + additionalSize) + if (additionalSize > 0) { - Array.Resize(ref _data, Math.Max(_position + additionalSize, _data.Length * 2)); + ResizeIfNeed(_position + additionalSize); } } @@ -275,8 +295,7 @@ public int SetPosition(int position) /// The value to write. public void Put(Guid value) { - if (_autoResize) - ResizeIfNeed(_position + GuidSize); + ResizeIfNeed(_position + GuidSize); value.TryWriteBytes(_data.AsSpan(_position)); _position += GuidSize; } @@ -307,8 +326,7 @@ public void Put(byte[] data) /// The span of data to write. public void Put(ReadOnlySpan data) { - if (_autoResize) - ResizeIfNeed(_position + data.Length); + ResizeIfNeed(_position + data.Length); data.CopyTo(_data.AsSpan(_position)); _position += data.Length; } @@ -321,8 +339,7 @@ public void Put(ReadOnlySpan data) /// The number of elements to write. public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) { - if (_autoResize) - ResizeIfNeed(_position + 2 + length); + ResizeIfNeed(_position + 2 + length); FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -351,8 +368,7 @@ public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) /// The number of s to write. public void PutBytesWithLength(byte[] data, int offset, ushort length) { - if (_autoResize) - ResizeIfNeed(_position + 2 + length); + ResizeIfNeed(_position + 2 + length); FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -389,8 +405,7 @@ public void PutArray(Array arr, int sz) { ushort length = arr == null ? (ushort)0 : (ushort)arr.Length; sz *= length; - if (_autoResize) - ResizeIfNeed(_position + sz + 2); + ResizeIfNeed(_position + sz + 2); FastBitConverter.GetBytes(_data, _position, length); if (arr != null) Buffer.BlockCopy(arr, 0, _data, _position + 2, sz); @@ -421,8 +436,7 @@ public unsafe void PutSpan(Span span) where T : unmanaged var length = (ushort)span.Length; var byteLength = length * sizeof(T); - if (_autoResize) - ResizeIfNeed(_position + byteLength + 2); + ResizeIfNeed(_position + byteLength + 2); FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -533,8 +547,7 @@ public void Put(IPEndPoint endPoint) throw new ArgumentException($"Unsupported address family: {endPoint.AddressFamily}"); } - if (_autoResize) - ResizeIfNeed(_position + 1 + addressSize + 2); + ResizeIfNeed(_position + 1 + addressSize + 2); _data[_position++] = familyFlag; @@ -566,8 +579,7 @@ public void PutLargeString(string value) int size = uTF8Encoding.GetByteCount(value); Put(size); - if (_autoResize) - ResizeIfNeed(_position + size); + ResizeIfNeed(_position + size); uTF8Encoding.GetBytes(value, 0, value.Length, _data, _position); _position += size; @@ -595,8 +607,7 @@ public void Put(string value, int maxLength = 0) int length = maxLength > 0 && value.Length > maxLength ? maxLength : value.Length; int maxSize = uTF8Encoding.GetMaxByteCount(length); - if (_autoResize) - ResizeIfNeed(_position + maxSize + sizeof(ushort)); + ResizeIfNeed(_position + maxSize + sizeof(ushort)); int size = uTF8Encoding.GetBytes(value, 0, length, _data, _position + sizeof(ushort)); if (size == 0) { @@ -617,8 +628,7 @@ public void Put(string value, int maxLength = 0) public unsafe void PutUnmanaged(T value) where T : unmanaged { int size = sizeof(T); - if (_autoResize) - ResizeIfNeed(_position + size); + ResizeIfNeed(_position + size); FastBitConverter.GetBytes(_data, _position, value); _position += size; } @@ -654,10 +664,7 @@ public void PutNullableUnmanaged(T? value) where T : unmanaged public unsafe void PutEnum(T value) where T : unmanaged, Enum { var size = sizeof(T); - if (_autoResize) - { - ResizeIfNeed(_position + size); - } + ResizeIfNeed(_position + size); FastBitConverter.GetBytes(_data, _position, value); _position += size; From 584ae16122faf01021bed456310e2e495f700daa Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 25 Mar 2026 22:32:15 +0300 Subject: [PATCH 240/261] revert --- LiteNetLib/Utils/NetDataWriter.cs | 91 ++++++++++++++----------------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 4a508b44..3c3892f1 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; @@ -125,56 +125,36 @@ public static NetDataWriter FromString(string value) } /// - /// Ensures that the internal buffer is at least bytes long. + /// Ensures the internal buffer is at least . /// /// The required minimum size of the buffer. - /// - /// Thrown when exceeds the current buffer capacity - /// and automatic resizing is disabled. - /// - /// - /// Thrown when is negative. - /// + /// + /// If an allocation is necessary, the buffer grows to either + /// or doubles its current size, whichever is larger. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ResizeIfNeed(int newSize) { - if (newSize < 0) - ThrowCapacityExceeded(newSize); - - if (_data.Length >= newSize) - return; - - if (!_autoResize) - ThrowCapacityExceeded(newSize); - - Array.Resize(ref _data, Math.Max(newSize, _data.Length * 2)); - } - - /// - /// Throws an indicating that the buffer capacity was exceeded - /// while automatic resizing is disabled. - /// - /// The total buffer size that was required. - /// Always thrown. - [MethodImpl(MethodImplOptions.NoInlining)] - private void ThrowCapacityExceeded(int requiredSize) - { - throw new InvalidOperationException( - $"Not enough capacity to write {requiredSize - _position} byte(s). " + - $"Position={_position}, Capacity={_data.Length}, RequiredSize={requiredSize}"); + if (_data.Length < newSize) + { + Array.Resize(ref _data, Math.Max(newSize, _data.Length * 2)); + } } /// - /// Ensures that the internal buffer can accommodate more bytes - /// from the current write position. + /// Ensures the internal buffer can accommodate more s. /// - /// The number of additional bytes that must fit. + /// The number of additional s to fit. + /// + /// This checks against the current . If the capacity is insufficient, + /// the buffer grows to either the required size or doubles its current size. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public void EnsureFit(int additionalSize) { - if (additionalSize > 0) + if (_data.Length < _position + additionalSize) { - ResizeIfNeed(_position + additionalSize); + Array.Resize(ref _data, Math.Max(_position + additionalSize, _data.Length * 2)); } } @@ -295,7 +275,8 @@ public int SetPosition(int position) /// The value to write. public void Put(Guid value) { - ResizeIfNeed(_position + GuidSize); + if (_autoResize) + ResizeIfNeed(_position + GuidSize); value.TryWriteBytes(_data.AsSpan(_position)); _position += GuidSize; } @@ -326,7 +307,8 @@ public void Put(byte[] data) /// The span of data to write. public void Put(ReadOnlySpan data) { - ResizeIfNeed(_position + data.Length); + if (_autoResize) + ResizeIfNeed(_position + data.Length); data.CopyTo(_data.AsSpan(_position)); _position += data.Length; } @@ -339,7 +321,8 @@ public void Put(ReadOnlySpan data) /// The number of elements to write. public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) { - ResizeIfNeed(_position + 2 + length); + if (_autoResize) + ResizeIfNeed(_position + 2 + length); FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -368,7 +351,8 @@ public void PutSBytesWithLength(sbyte[] data, int offset, ushort length) /// The number of s to write. public void PutBytesWithLength(byte[] data, int offset, ushort length) { - ResizeIfNeed(_position + 2 + length); + if (_autoResize) + ResizeIfNeed(_position + 2 + length); FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -405,7 +389,8 @@ public void PutArray(Array arr, int sz) { ushort length = arr == null ? (ushort)0 : (ushort)arr.Length; sz *= length; - ResizeIfNeed(_position + sz + 2); + if (_autoResize) + ResizeIfNeed(_position + sz + 2); FastBitConverter.GetBytes(_data, _position, length); if (arr != null) Buffer.BlockCopy(arr, 0, _data, _position + 2, sz); @@ -436,7 +421,8 @@ public unsafe void PutSpan(Span span) where T : unmanaged var length = (ushort)span.Length; var byteLength = length * sizeof(T); - ResizeIfNeed(_position + byteLength + 2); + if (_autoResize) + ResizeIfNeed(_position + byteLength + 2); FastBitConverter.GetBytes(_data, _position, length); _position += 2; @@ -547,7 +533,8 @@ public void Put(IPEndPoint endPoint) throw new ArgumentException($"Unsupported address family: {endPoint.AddressFamily}"); } - ResizeIfNeed(_position + 1 + addressSize + 2); + if (_autoResize) + ResizeIfNeed(_position + 1 + addressSize + 2); _data[_position++] = familyFlag; @@ -579,7 +566,8 @@ public void PutLargeString(string value) int size = uTF8Encoding.GetByteCount(value); Put(size); - ResizeIfNeed(_position + size); + if (_autoResize) + ResizeIfNeed(_position + size); uTF8Encoding.GetBytes(value, 0, value.Length, _data, _position); _position += size; @@ -607,7 +595,8 @@ public void Put(string value, int maxLength = 0) int length = maxLength > 0 && value.Length > maxLength ? maxLength : value.Length; int maxSize = uTF8Encoding.GetMaxByteCount(length); - ResizeIfNeed(_position + maxSize + sizeof(ushort)); + if (_autoResize) + ResizeIfNeed(_position + maxSize + sizeof(ushort)); int size = uTF8Encoding.GetBytes(value, 0, length, _data, _position + sizeof(ushort)); if (size == 0) { @@ -628,7 +617,8 @@ public void Put(string value, int maxLength = 0) public unsafe void PutUnmanaged(T value) where T : unmanaged { int size = sizeof(T); - ResizeIfNeed(_position + size); + if (_autoResize) + ResizeIfNeed(_position + size); FastBitConverter.GetBytes(_data, _position, value); _position += size; } @@ -664,7 +654,10 @@ public void PutNullableUnmanaged(T? value) where T : unmanaged public unsafe void PutEnum(T value) where T : unmanaged, Enum { var size = sizeof(T); - ResizeIfNeed(_position + size); + if (_autoResize) + { + ResizeIfNeed(_position + size); + } FastBitConverter.GetBytes(_data, _position, value); _position += size; From 9c7a93df030b855e9411e3f040116582de8f41ac Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 25 Mar 2026 22:34:13 +0300 Subject: [PATCH 241/261] Length optimization --- LiteNetLib/Utils/NetDataWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 3c3892f1..901e3abf 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -97,7 +97,7 @@ public static NetDataWriter FromBytes(byte[] bytes, bool copy) /// Length of array public static NetDataWriter FromBytes(byte[] bytes, int offset, int length) { - var netDataWriter = new NetDataWriter(true, bytes.Length); + var netDataWriter = new NetDataWriter(true, length); netDataWriter.Put(bytes, offset, length); return netDataWriter; } From a05e8c7585c1c3f99f44a9006812c0128c601586 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 25 Mar 2026 22:36:11 +0300 Subject: [PATCH 242/261] Fix doc --- LiteNetLib/Utils/NetDataWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 901e3abf..639f1fae 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -574,7 +574,7 @@ public void PutLargeString(string value) } /// - /// Serializes a string using a 2-byte length header. + /// Serializes a string using a 2-byte length header. /// /// The string to write to the buffer. /// From 91d510b88eddc7997e2a9a00beefbc973afac9d9 Mon Sep 17 00:00:00 2001 From: FUTURE-SL Date: Wed, 25 Mar 2026 22:47:49 +0300 Subject: [PATCH 243/261] Update NetDataWriter.cs --- LiteNetLib/Utils/NetDataWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 639f1fae..9d693ba5 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -243,7 +243,7 @@ public int SetPosition(int position) /// Serializes a value as a . ///
    /// The value to write. - public void Put(char value) => Put((ushort)value); + public void Put(char value) => PutUnmanaged(value); /// /// Serializes a value. From 4b3ed86aa47d4a12feb6e3c88b29a9b8621b856a Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Wed, 25 Mar 2026 21:08:02 +0100 Subject: [PATCH 244/261] Update docs --- LiteNetLib/NatPunchModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/LiteNetLib/NatPunchModule.cs b/LiteNetLib/NatPunchModule.cs index 94251a86..3259384b 100644 --- a/LiteNetLib/NatPunchModule.cs +++ b/LiteNetLib/NatPunchModule.cs @@ -176,8 +176,10 @@ private void Send< /// /// Sends NAT introduction packets to both the host and the client to facilitate punchthrough. - /// This is typically called by a mediator (Master Server). /// + /// + /// This is typically called by a mediator (e.g. a master server). + /// /// Internal (LAN) endpoint of the host. /// External (WAN) endpoint of the host. /// Internal (LAN) endpoint of the client. From 6b1fcbf2cd72c84b805f58f00d66edc630bc9cd6 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Wed, 25 Mar 2026 21:09:51 +0100 Subject: [PATCH 245/261] Update docs --- LiteNetLib/NetPacket.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LiteNetLib/NetPacket.cs b/LiteNetLib/NetPacket.cs index e22541ff..fcb271e9 100644 --- a/LiteNetLib/NetPacket.cs +++ b/LiteNetLib/NetPacket.cs @@ -202,9 +202,9 @@ public NetPacket(PacketProperty property, int payloadSize) public int HeaderSize => HeaderSizes[RawData[0] & 0x1F]; /// - /// Performs a basic sanity check on the packet header and size. + /// Performs a basic check on the packet header and size. /// - /// True if the packet property is valid and the size is sufficient for the headers. + /// if the packet property is valid and the size is sufficient for the headers. public bool Verify() { byte property = (byte)(RawData[0] & 0x1F); From bdaa143792b0d89c7273ca86b350e65ce858b023 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Wed, 25 Mar 2026 21:29:08 +0100 Subject: [PATCH 246/261] Use spans for put string --- LiteNetLib/Utils/NetDataWriter.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/Utils/NetDataWriter.cs b/LiteNetLib/Utils/NetDataWriter.cs index 9d693ba5..24f09b8d 100644 --- a/LiteNetLib/Utils/NetDataWriter.cs +++ b/LiteNetLib/Utils/NetDataWriter.cs @@ -593,11 +593,16 @@ public void Put(string value, int maxLength = 0) return; } - int length = maxLength > 0 && value.Length > maxLength ? maxLength : value.Length; - int maxSize = uTF8Encoding.GetMaxByteCount(length); + ReadOnlySpan source = value.AsSpan(); + if (maxLength > 0 && source.Length > maxLength) + { + source = source.Slice(0, maxLength); + } + + int maxSize = uTF8Encoding.GetMaxByteCount(source.Length); if (_autoResize) ResizeIfNeed(_position + maxSize + sizeof(ushort)); - int size = uTF8Encoding.GetBytes(value, 0, length, _data, _position + sizeof(ushort)); + int size = uTF8Encoding.GetBytes(source, _data.AsSpan(_position + sizeof(ushort))); if (size == 0) { Put((ushort)0); From dfbd90bd35df83492439088b5d2cc6082c6427e9 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Wed, 25 Mar 2026 21:50:34 +0100 Subject: [PATCH 247/261] Update docs --- LiteNetLib/BaseChannel.cs | 2 +- LiteNetLib/NetConstants.cs | 7 ++++++- LiteNetLib/NetPacket.cs | 5 ++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/BaseChannel.cs b/LiteNetLib/BaseChannel.cs index f8b6fd9c..1dd969c5 100644 --- a/LiteNetLib/BaseChannel.cs +++ b/LiteNetLib/BaseChannel.cs @@ -4,7 +4,7 @@ namespace LiteNetLib { /// - /// Base class for all communication channels (Reliable, Unreliable, Sequenced).
    + /// Base class for reliable and sequenced communication channels.
    /// Handles the queuing and scheduling of outgoing packets. ///
    internal abstract class BaseChannel diff --git a/LiteNetLib/NetConstants.cs b/LiteNetLib/NetConstants.cs index 75dbea85..947cc865 100644 --- a/LiteNetLib/NetConstants.cs +++ b/LiteNetLib/NetConstants.cs @@ -112,8 +112,13 @@ public static class NetConstants public static readonly int MaxUnreliableDataSize = MaxPacketSize - HeaderSize; /// - /// Maximum number of simultaneous connection attempts (pending connections) allowed per peer. + /// Maximum possible value for . /// + /// + /// This value is used to distinguish between different connection instances from the same .
    + /// It allows the receiver to identify and discard packets belonging to previous connection attempts that may arrive + /// late due to network jitter, even if they originate from the same address and port.
    + ///
    public const byte MaxConnectionNumber = 4; } } diff --git a/LiteNetLib/NetPacket.cs b/LiteNetLib/NetPacket.cs index fcb271e9..d0ecdd6a 100644 --- a/LiteNetLib/NetPacket.cs +++ b/LiteNetLib/NetPacket.cs @@ -77,9 +77,12 @@ public PacketProperty Property } /// - /// Gets or sets the connection number used to distinguish between multiple connections from the same endpoint.
    + /// Gets or sets the connection number used to distinguish between multiple connection instances from the same endpoint. /// Stored in bits 6 and 7 of the first byte (0x60 mask). ///
    + /// + /// Used to discard packets from previous connections made in the same frame/time. + /// public byte ConnectionNumber { get => (byte)((RawData[0] & 0x60) >> 5); From 79e9af312e2a8e75d158bbd177358423b4df76f5 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Wed, 25 Mar 2026 22:55:34 +0200 Subject: [PATCH 248/261] generate docs --- docs/api/LiteNetLib.ConnectionRequest.html | 19 ++++-- .../LiteNetLib.EventBasedLiteNetListener.html | 54 +++++++++++------ ...LiteNetLib.EventBasedNatPunchListener.html | 11 ++-- .../api/LiteNetLib.EventBasedNetListener.html | 60 ++++++++++++------- docs/api/LiteNetLib.INatPunchListener.html | 29 +++++---- .../api/LiteNetLib.LiteConnectionRequest.html | 19 ++++-- docs/api/LiteNetLib.LiteNetManager.html | 10 +++- docs/api/LiteNetLib.NatAddressType.html | 11 ++-- docs/api/LiteNetLib.NatPunchModule.html | 57 ++++++++++++------ docs/api/LiteNetLib.NetConstants.html | 49 +++++++++++---- docs/api/LiteNetLib.NetEvent.EType.html | 35 +++++++---- docs/api/LiteNetLib.NetEvent.html | 42 ++++++++----- docs/api/LiteNetLib.NetStatistics.html | 58 +++++++++++------- docs/api/LiteNetLib.NetUtils.html | 53 ++++++++++++---- .../LiteNetLib.Utils.FastBitConverter.html | 31 ++++++++-- .../LiteNetLib.Utils.INetSerializable.html | 20 +++++-- docs/api/LiteNetLib.Utils.NetDataWriter.html | 2 +- .../LiteNetLib.Utils.NetPacketProcessor.html | 54 ++++++++++++----- docs/api/LiteNetLib.Utils.html | 3 +- docs/api/LiteNetLib.html | 15 +++-- docs/manifest.json | 14 ++--- 21 files changed, 450 insertions(+), 196 deletions(-) diff --git a/docs/api/LiteNetLib.ConnectionRequest.html b/docs/api/LiteNetLib.ConnectionRequest.html index 9b89b5ca..1c60018b 100644 --- a/docs/api/LiteNetLib.ConnectionRequest.html +++ b/docs/api/LiteNetLib.ConnectionRequest.html @@ -127,7 +127,8 @@

    Methods

    Accept()

    -
    +

    Accept connection and get new NetPeer as result

    +
    Declaration
    @@ -144,7 +145,8 @@
    Returns
    NetPeer - +

    Connected NetPeer

    + @@ -152,7 +154,8 @@
    Returns

    AcceptIfKey(string)

    -
    +

    Accepts the connection if the first string in the Data matches the provided key.

    +
    Declaration
    @@ -171,7 +174,8 @@
    Parameters
    string key - +

    The required string key to match.

    + @@ -186,10 +190,15 @@
    Returns
    NetPeer - +

    A new LiteNetPeer if the key matches and connection is accepted; otherwise, null.

    + +
    Remarks
    +

    This is a helper method for simple password/key validation. +If the key does not match or data is invalid, the connection is automatically rejected.

    +
    diff --git a/docs/api/LiteNetLib.EventBasedLiteNetListener.html b/docs/api/LiteNetLib.EventBasedLiteNetListener.html index 2c275bf9..9dcfbc72 100644 --- a/docs/api/LiteNetLib.EventBasedLiteNetListener.html +++ b/docs/api/LiteNetLib.EventBasedLiteNetListener.html @@ -95,7 +95,8 @@

    Methods

    ClearConnectionRequestEvent()

    -
    +

    Clears all subscribers from ConnectionRequestEvent.

    +
    Declaration
    @@ -105,7 +106,8 @@
    Declaration

    ClearDeliveryEvent()

    -
    +

    Clears all subscribers from DeliveryEvent.

    +
    Declaration
    @@ -115,7 +117,8 @@
    Declaration

    ClearNetworkErrorEvent()

    -
    +

    Clears all subscribers from NetworkErrorEvent.

    +
    Declaration
    @@ -125,7 +128,8 @@
    Declaration

    ClearNetworkLatencyUpdateEvent()

    -
    +

    Clears all subscribers from NetworkLatencyUpdateEvent.

    +
    Declaration
    @@ -135,7 +139,8 @@
    Declaration

    ClearNetworkReceiveEvent()

    -
    +

    Clears all subscribers from NetworkReceiveEvent.

    +
    Declaration
    @@ -145,7 +150,8 @@
    Declaration

    ClearNetworkReceiveUnconnectedEvent()

    -
    +

    Clears all subscribers from NetworkReceiveUnconnectedEvent.

    +
    Declaration
    @@ -155,7 +161,8 @@
    Declaration

    ClearPeerAddressChangedEvent()

    -
    +

    Clears all subscribers from PeerAddressChangedEvent.

    +
    Declaration
    @@ -165,7 +172,8 @@
    Declaration

    ClearPeerConnectedEvent()

    -
    +

    Clears all subscribers from PeerConnectedEvent.

    +
    Declaration
    @@ -175,7 +183,8 @@
    Declaration

    ClearPeerDisconnectedEvent()

    -
    +

    Clears all subscribers from PeerDisconnectedEvent.

    +
    Declaration
    @@ -186,7 +195,8 @@

    Events

    ConnectionRequestEvent

    -
    +

    Occurs when a new connection request is received.

    +
    Declaration
    @@ -210,7 +220,8 @@
    Event Type

    DeliveryEvent

    -
    +

    Occurs when a reliable packet is successfully delivered or acknowledged.

    +
    Declaration
    @@ -234,7 +245,8 @@
    Event Type

    NetworkErrorEvent

    -
    +

    Occurs when a network error is detected in the underlying socket.

    +
    Declaration
    @@ -258,7 +270,8 @@
    Event Type

    NetworkLatencyUpdateEvent

    -
    +

    Occurs when the round-trip time (RTT) to a peer is updated.

    +
    Declaration
    @@ -282,7 +295,8 @@
    Event Type

    NetworkReceiveEvent

    -
    +

    Occurs when data is received from a connected peer.

    +
    Declaration
    @@ -306,7 +320,8 @@
    Event Type

    NetworkReceiveUnconnectedEvent

    -
    +

    Occurs when a message is received from an unconnected endpoint.

    +
    Declaration
    @@ -330,7 +345,8 @@
    Event Type

    PeerAddressChangedEvent

    -
    +

    Occurs when a peer's remote address changes.

    +
    Declaration
    @@ -354,7 +370,8 @@
    Event Type

    PeerConnectedEvent

    -
    +

    Occurs when a new peer has successfully connected.

    +
    Declaration
    @@ -378,7 +395,8 @@
    Event Type

    PeerDisconnectedEvent

    -
    +

    Occurs when a peer disconnects or the connection is lost.

    +
    Declaration
    diff --git a/docs/api/LiteNetLib.EventBasedNatPunchListener.html b/docs/api/LiteNetLib.EventBasedNatPunchListener.html index 0d78135f..64a64655 100644 --- a/docs/api/LiteNetLib.EventBasedNatPunchListener.html +++ b/docs/api/LiteNetLib.EventBasedNatPunchListener.html @@ -9,7 +9,7 @@ - + @@ -71,7 +71,8 @@

    Class EventBasedNatPunchListener

    -
    +

    An implementation of INatPunchListener that maps callbacks to events.

    +
    Inheritance
    @@ -93,7 +94,8 @@

    Events

    NatIntroductionRequest

    -
    +

    Event triggered when a NAT introduction request is received.

    +
    Declaration
    @@ -117,7 +119,8 @@
    Event Type

    NatIntroductionSuccess

    -
    +

    Event triggered when NAT punchthrough is successfully completed.

    +
    Declaration
    diff --git a/docs/api/LiteNetLib.EventBasedNetListener.html b/docs/api/LiteNetLib.EventBasedNetListener.html index 0f67c1fa..d319a771 100644 --- a/docs/api/LiteNetLib.EventBasedNetListener.html +++ b/docs/api/LiteNetLib.EventBasedNetListener.html @@ -95,7 +95,8 @@

    Methods

    ClearConnectionRequestEvent()

    -
    +

    Clears all subscribers from ConnectionRequestEvent.

    +
    Declaration
    @@ -105,7 +106,8 @@
    Declaration

    ClearDeliveryEvent()

    -
    +

    Clears all subscribers from DeliveryEvent.

    +
    Declaration
    @@ -115,7 +117,8 @@
    Declaration

    ClearNetworkErrorEvent()

    -
    +

    Clears all subscribers from NetworkErrorEvent.

    +
    Declaration
    @@ -125,7 +128,8 @@
    Declaration

    ClearNetworkLatencyUpdateEvent()

    -
    +

    Clears all subscribers from NetworkLatencyUpdateEvent.

    +
    Declaration
    @@ -135,7 +139,8 @@
    Declaration

    ClearNetworkReceiveEvent()

    -
    +

    Clears all subscribers from NetworkReceiveEvent.

    +
    Declaration
    @@ -145,7 +150,8 @@
    Declaration

    ClearNetworkReceiveUnconnectedEvent()

    -
    +

    Clears all subscribers from NetworkReceiveUnconnectedEvent.

    +
    Declaration
    @@ -155,7 +161,8 @@
    Declaration

    ClearNtpResponseEvent()

    -
    +

    Clears all subscribers from NtpResponseEvent.

    +
    Declaration
    @@ -165,7 +172,8 @@
    Declaration

    ClearPeerAddressChangedEvent()

    -
    +

    Clears all subscribers from PeerAddressChangedEvent.

    +
    Declaration
    @@ -175,7 +183,8 @@
    Declaration

    ClearPeerConnectedEvent()

    -
    +

    Clears all subscribers from PeerConnectedEvent.

    +
    Declaration
    @@ -185,7 +194,8 @@
    Declaration

    ClearPeerDisconnectedEvent()

    -
    +

    Clears all subscribers from PeerDisconnectedEvent.

    +
    Declaration
    @@ -196,7 +206,8 @@

    Events

    ConnectionRequestEvent

    -
    +

    Occurs when a new connection request is received.

    +
    Declaration
    @@ -220,7 +231,8 @@
    Event Type

    DeliveryEvent

    -
    +

    Occurs when a reliable packet is successfully delivered or acknowledged.

    +
    Declaration
    @@ -244,7 +256,8 @@
    Event Type

    NetworkErrorEvent

    -
    +

    Occurs when a network error is detected in the underlying socket.

    +
    Declaration
    @@ -268,7 +281,8 @@
    Event Type

    NetworkLatencyUpdateEvent

    -
    +

    Occurs when the round-trip time (RTT) to a peer is updated.

    +
    Declaration
    @@ -292,7 +306,8 @@
    Event Type

    NetworkReceiveEvent

    -
    +

    Occurs when data is received from a connected peer.

    +
    Declaration
    @@ -316,7 +331,8 @@
    Event Type

    NetworkReceiveUnconnectedEvent

    -
    +

    Occurs when a message is received from an unconnected endpoint.

    +
    Declaration
    @@ -340,7 +356,8 @@
    Event Type

    NtpResponseEvent

    -
    +

    Occurs when an NTP response is received.

    +
    Declaration
    @@ -364,7 +381,8 @@
    Event Type

    PeerAddressChangedEvent

    -
    +

    Occurs when a peer's remote address changes.

    +
    Declaration
    @@ -388,7 +406,8 @@
    Event Type

    PeerConnectedEvent

    -
    +

    Occurs when a new peer has successfully connected.

    +
    Declaration
    @@ -412,7 +431,8 @@
    Event Type

    PeerDisconnectedEvent

    -
    +

    Occurs when a peer disconnects or the connection is lost.

    +
    Declaration
    diff --git a/docs/api/LiteNetLib.INatPunchListener.html b/docs/api/LiteNetLib.INatPunchListener.html index 6f93cc69..579fcb36 100644 --- a/docs/api/LiteNetLib.INatPunchListener.html +++ b/docs/api/LiteNetLib.INatPunchListener.html @@ -9,7 +9,7 @@ - + @@ -71,7 +71,8 @@

    Interface INatPunchListener

    -
    +

    Interface for handling events related to NAT punchthrough and introduction.

    +
    Namespace: LiteNetLib
    Assembly: LiteNetLib.dll
    @@ -85,7 +86,8 @@

    Methods

    OnNatIntroductionRequest(IPEndPoint, IPEndPoint, string)

    -
    +

    Called when a NAT introduction request is received from the mediator server.

    +
    Declaration
    @@ -104,17 +106,20 @@
    Parameters
    IPEndPoint localEndPoint - +

    The local endpoint of the client requesting connection.

    + IPEndPoint remoteEndPoint - +

    The remote endpoint of the client requesting connection.

    + string token - +

    Custom data token associated with the request.

    + @@ -122,7 +127,8 @@
    Parameters

    OnNatIntroductionSuccess(IPEndPoint, NatAddressType, string)

    -
    +

    Called when NAT punchthrough is successful and a direct connection can be established.

    +
    Declaration
    @@ -141,17 +147,20 @@
    Parameters
    IPEndPoint targetEndPoint - +

    The resolved endpoint of the remote peer.

    + NatAddressType type - +

    The type of address (Internal or External) that succeeded.

    + string token - +

    Custom data token associated with the request.

    + diff --git a/docs/api/LiteNetLib.LiteConnectionRequest.html b/docs/api/LiteNetLib.LiteConnectionRequest.html index b624712a..68fb5ad5 100644 --- a/docs/api/LiteNetLib.LiteConnectionRequest.html +++ b/docs/api/LiteNetLib.LiteConnectionRequest.html @@ -90,7 +90,8 @@

    Fields

    RemoteEndPoint

    -
    +

    The remote endpoint (IP and Port) of the peer requesting the connection.

    +
    Declaration
    @@ -117,7 +118,8 @@

    Properties

    Data

    -
    +

    Data sent by the remote peer in the connection request.

    +
    Declaration
    @@ -171,7 +173,8 @@
    Returns

    AcceptIfKey(string)

    -
    +

    Accepts the connection if the first string in the Data matches the provided key.

    +
    Declaration
    @@ -190,7 +193,8 @@
    Parameters
    string key - +

    The required string key to match.

    + @@ -205,10 +209,15 @@
    Returns
    LiteNetPeer - +

    A new LiteNetPeer if the key matches and connection is accepted; otherwise, null.

    + +
    Remarks
    +

    This is a helper method for simple password/key validation. +If the key does not match or data is invalid, the connection is automatically rejected.

    +
    diff --git a/docs/api/LiteNetLib.LiteNetManager.html b/docs/api/LiteNetLib.LiteNetManager.html index be29695b..b687ab16 100644 --- a/docs/api/LiteNetLib.LiteNetManager.html +++ b/docs/api/LiteNetLib.LiteNetManager.html @@ -1015,7 +1015,8 @@
    Property Value

    ExtraPacketSizeForLayer

    -
    +

    Gets the additional size in bytes required by the active PacketLayerBase.

    +
    Declaration
    @@ -1036,6 +1037,11 @@
    Property Value
    +
    Remarks
    +

    This value is used by NetManager to calculate the available MTU for user data.
    +If a packet layer is active (e.g., for encryption or CRC), this returns the overhead added to every packet. +Returns 0 if no packet layer is assigned.

    +
    @@ -3631,7 +3637,7 @@
    Returns
    bool -

    True if peer with id exist, otherwise false

    +

    true if peer with id exist; otherwise false

    diff --git a/docs/api/LiteNetLib.NatAddressType.html b/docs/api/LiteNetLib.NatAddressType.html index 3dcf0b2d..feae78d5 100644 --- a/docs/api/LiteNetLib.NatAddressType.html +++ b/docs/api/LiteNetLib.NatAddressType.html @@ -9,7 +9,7 @@ - + @@ -72,7 +72,8 @@

    Enum NatAddressType

    -
    +

    Specifies the type of network address discovered during NAT punchthrough.

    +
    Namespace: LiteNetLib
    Assembly: LiteNetLib.dll
    @@ -92,11 +93,13 @@

    Fields External - +

    Publicly accessible address on the wide area network (WAN).

    + Internal - +

    Address within the local area network (LAN).

    + diff --git a/docs/api/LiteNetLib.NatPunchModule.html b/docs/api/LiteNetLib.NatPunchModule.html index 27210701..a789e407 100644 --- a/docs/api/LiteNetLib.NatPunchModule.html +++ b/docs/api/LiteNetLib.NatPunchModule.html @@ -90,7 +90,8 @@

    Fields

    MaxTokenLength

    -
    +

    Maximum allowed length for the NAT introduction token string.

    +
    Declaration
    @@ -142,7 +143,8 @@

    Methods

    Init(INatPunchListener)

    -
    +

    Initializes the NAT punch module with a listener to handle punchthrough events.

    +
    Declaration
    @@ -161,7 +163,8 @@
    Parameters
    INatPunchListener listener - +

    The listener implementation that will receive NAT events.

    + @@ -169,7 +172,8 @@
    Parameters

    NatIntroduce(IPEndPoint, IPEndPoint, IPEndPoint, IPEndPoint, string)

    -
    +

    Sends NAT introduction packets to both the host and the client to facilitate punchthrough.

    +
    Declaration
    @@ -188,45 +192,58 @@
    Parameters
    IPEndPoint hostInternal - +

    Internal (LAN) endpoint of the host.

    + IPEndPoint hostExternal - +

    External (WAN) endpoint of the host.

    + IPEndPoint clientInternal - +

    Internal (LAN) endpoint of the client.

    + IPEndPoint clientExternal - +

    External (WAN) endpoint of the client.

    + string additionalInfo - +

    Custom token or data to include in the introduction.

    + +
    Remarks
    +

    This is typically called by a mediator (e.g. a master server).

    +

    PollEvents()

    -
    +

    Triggers queued NAT punchthrough events (Success or Request) on the provided INatPunchListener.

    +
    Declaration
    public void PollEvents()
    +
    Remarks
    +

    This should be called from the main thread if UnsyncedEvents is false.

    +

    SendNatIntroduceRequest(IPEndPoint, string)

    -
    +

    Sends a request to the Master Server to introduce this peer to another peer.

    +
    Declaration
    @@ -245,12 +262,14 @@
    Parameters
    IPEndPoint masterServerEndPoint - +

    The endpoint of the Master Server.

    + string additionalInfo - +

    Custom token to identify the connection or room.

    + @@ -258,7 +277,8 @@
    Parameters

    SendNatIntroduceRequest(string, int, string)

    -
    +

    Sends a request to the Master Server to introduce this peer to another peer.

    +
    Declaration
    @@ -277,17 +297,20 @@
    Parameters
    string host - +

    The hostname or IP of the Master Server.

    + int port - +

    The port of the Master Server.

    + string additionalInfo - +

    Custom token to identify the connection or room.

    + diff --git a/docs/api/LiteNetLib.NetConstants.html b/docs/api/LiteNetLib.NetConstants.html index 1b95fedf..e89a2a94 100644 --- a/docs/api/LiteNetLib.NetConstants.html +++ b/docs/api/LiteNetLib.NetConstants.html @@ -90,7 +90,9 @@

    Fields

    ChanneledHeaderSize

    -
    +

    Size of the header for sequenced or reliable messages in bytes.
    +Includes HeaderSize, Sequence, and ChannelId.

    +
    Declaration
    @@ -114,7 +116,8 @@
    Field Value

    DefaultWindowSize

    -
    +

    Default window size for reliable channels (number of packets).

    +
    Declaration
    @@ -138,7 +141,9 @@
    Field Value

    FragmentHeaderSize

    -
    +

    Additional header size required for fragmented packets in bytes.
    +Includes FragmentId, FragmentPart, and FragmentsTotal.

    +
    Declaration
    @@ -162,7 +167,9 @@
    Field Value

    FragmentedHeaderTotalSize

    -
    +

    Total header size for a fragmented channeled packet in bytes.
    +Combines ChanneledHeaderSize and FragmentHeaderSize.

    +
    Declaration
    @@ -186,7 +193,8 @@
    Field Value

    HalfMaxSequence

    -
    +

    Half of the MaxSequence, used for sequence comparison and wrap-around logic.

    +
    Declaration
    @@ -210,7 +218,8 @@
    Field Value

    HeaderSize

    -
    +

    Size of the base packet header (PacketProperty) in bytes.

    +
    Declaration
    @@ -234,7 +243,8 @@
    Field Value

    InitialMtu

    -
    +

    The starting Maximum Transmission Unit (MTU) used for new connections before path MTU discovery.

    +
    Declaration
    @@ -258,7 +268,8 @@
    Field Value

    MaxConnectionNumber

    -
    +

    Maximum possible value for LiteNetLib.NetPacket.ConnectionNumber.

    +
    Declaration
    @@ -279,10 +290,16 @@
    Field Value
    +
    Remarks
    +

    This value is used to distinguish between different connection instances from the same IPEndPoint.
    +It allows the receiver to identify and discard packets belonging to previous connection attempts that may arrive +late due to network jitter, even if they originate from the same address and port.

    +

    MaxPacketSize

    -
    +

    Maximum possible packet size allowed by the library based on the largest supported MTU.

    +
    Declaration
    @@ -306,7 +323,8 @@
    Field Value

    MaxSequence

    -
    +

    Maximum possible sequence number before wrapping back to zero.

    +
    Declaration
    @@ -330,7 +348,9 @@
    Field Value

    MaxUnreliableDataSize

    -
    +

    Maximum payload size for a single unreliable packet in bytes.
    +Calculated as MaxPacketSize - HeaderSize.

    +
    Declaration
    @@ -354,7 +374,9 @@
    Field Value

    SocketBufferSize

    -
    +

    Size of the underlying UDP socket receive and send buffers in bytes.
    +Default is 1MB.

    +
    Declaration
    @@ -378,7 +400,8 @@
    Field Value

    SocketTTL

    -
    +

    Time To Live (TTL) for the UDP packets.

    +
    Declaration
    diff --git a/docs/api/LiteNetLib.NetEvent.EType.html b/docs/api/LiteNetLib.NetEvent.EType.html index 86acddf9..40a3bc78 100644 --- a/docs/api/LiteNetLib.NetEvent.EType.html +++ b/docs/api/LiteNetLib.NetEvent.EType.html @@ -9,7 +9,7 @@ - + @@ -72,7 +72,8 @@

    Enum NetEvent.EType

    -
    +

    Specifies the category of the network event.

    +
    Namespace: LiteNetLib
    Assembly: LiteNetLib.dll
    @@ -92,43 +93,53 @@

    Fields Broadcast - +

    Broadcast message received.

    + Connect - +

    New peer connected.

    + ConnectionLatencyUpdated - +

    Round-trip time (RTT) for a peer has been updated.

    + ConnectionRequest - +

    Incoming connection request from a new peer.

    + Disconnect - +

    Peer disconnected.

    + Error - +

    Socket or internal protocol error occurred.

    + MessageDelivered - +

    Reliable message was successfully delivered to the remote peer.

    + PeerAddressChanged - +

    The IP address or port of an existing peer has changed (e.g., roaming).

    + Receive - +

    Data received from a connected peer.

    + ReceiveUnconnected - +

    Unconnected message received.

    + diff --git a/docs/api/LiteNetLib.NetEvent.html b/docs/api/LiteNetLib.NetEvent.html index bea06f3b..2235de1f 100644 --- a/docs/api/LiteNetLib.NetEvent.html +++ b/docs/api/LiteNetLib.NetEvent.html @@ -91,7 +91,8 @@

    Constructors

    NetEvent(LiteNetManager)

    -
    +

    Initializes a new instance of the NetEvent class.

    +
    Declaration
    @@ -110,7 +111,8 @@
    Parameters
    LiteNetManager manager - +

    The LiteNetManager that owns the packet pool and buffers for this event.

    + @@ -119,7 +121,8 @@

    Fields

    ChannelNumber

    -
    +

    The channel on which the packet was received.

    +
    Declaration
    @@ -143,7 +146,8 @@
    Field Value

    ConnectionRequest

    -
    +

    Information about an incoming connection. Only valid when Type is ConnectionRequest.

    +
    Declaration
    @@ -167,7 +171,8 @@
    Field Value

    DataReader

    -
    +

    A reader for accessing the payload of received data, broadcast, or unconnected messages.

    +
    Declaration
    @@ -191,7 +196,8 @@
    Field Value

    DeliveryMethod

    -
    +

    The delivery method used for the received packet. Only valid when Type is Receive.

    +
    Declaration
    @@ -215,7 +221,8 @@
    Field Value

    DisconnectReason

    -
    +

    The reason for a peer's disconnection. Only valid when Type is Disconnect.

    +
    Declaration
    @@ -239,7 +246,8 @@
    Field Value

    ErrorCode

    -
    +

    The specific socket error. Only valid when Type is Error.

    +
    Declaration
    @@ -263,7 +271,8 @@
    Field Value

    Latency

    -
    +

    The updated latency value in milliseconds. Only valid when Type is ConnectionLatencyUpdated.

    +
    Declaration
    @@ -287,7 +296,8 @@
    Field Value

    Next

    -
    +

    Reference to the next event in the pool or event queue.

    +
    Declaration
    @@ -311,7 +321,8 @@
    Field Value

    Peer

    -
    +

    The peer associated with this event. null for unconnected events.

    +
    Declaration
    @@ -335,7 +346,8 @@
    Field Value

    RemoteEndPoint

    -
    +

    The remote endpoint (IP and Port) from which the event originated.

    +
    Declaration
    @@ -359,7 +371,8 @@
    Field Value

    Type

    -
    +

    The type of network event that occurred.

    +
    Declaration
    @@ -383,7 +396,8 @@
    Field Value

    UserData

    -
    +

    Optional user data associated with a connection request or disconnect.

    +
    Declaration
    diff --git a/docs/api/LiteNetLib.NetStatistics.html b/docs/api/LiteNetLib.NetStatistics.html index 796ea08e..19c6e66b 100644 --- a/docs/api/LiteNetLib.NetStatistics.html +++ b/docs/api/LiteNetLib.NetStatistics.html @@ -9,7 +9,7 @@ - + @@ -71,7 +71,8 @@

    Class NetStatistics

    -
    +

    Thread-safe counter for network statistics including sent/received packets, bytes, and packet loss.

    +
    Inheritance
    @@ -90,7 +91,8 @@

    Properties

    BytesReceived

    -
    +

    Total number of bytes received.

    +
    Declaration
    @@ -115,7 +117,8 @@
    Property Value

    BytesSent

    -
    +

    Total number of bytes sent.

    +
    Declaration
    @@ -140,7 +143,8 @@
    Property Value

    PacketLoss

    -
    +

    Total number of packets lost during transmission.

    +
    Declaration
    @@ -165,7 +169,9 @@
    Property Value

    PacketLossPercent

    -
    +

    Percentage of sent packets that were lost. +Calculated as (PacketLoss * 100) / PacketsSent.

    +
    Declaration
    @@ -190,7 +196,8 @@
    Property Value

    PacketsReceived

    -
    +

    Total number of packets received.

    +
    Declaration
    @@ -215,7 +222,8 @@
    Property Value

    PacketsSent

    -
    +

    Total number of packets sent.

    +
    Declaration
    @@ -242,7 +250,8 @@

    Methods

    AddBytesReceived(long)

    -
    +

    Adds a specific amount to the total bytes received.

    +
    Declaration
    @@ -261,7 +270,8 @@
    Parameters
    long bytesReceived - +

    Number of bytes to add.

    + @@ -269,7 +279,8 @@
    Parameters

    AddBytesSent(long)

    -
    +

    Adds a specific amount to the total bytes sent.

    +
    Declaration
    @@ -288,7 +299,8 @@
    Parameters
    long bytesSent - +

    Number of bytes to add.

    + @@ -296,7 +308,8 @@
    Parameters

    AddPacketLoss(long)

    -
    +

    Adds a specific amount to the total packet loss count.

    +
    Declaration
    @@ -315,7 +328,8 @@
    Parameters
    long packetLoss - +

    Number of lost packets to add.

    + @@ -323,7 +337,8 @@
    Parameters

    IncrementPacketLoss()

    -
    +

    Increments the count of lost packets by one.

    +
    Declaration
    @@ -333,7 +348,8 @@
    Declaration

    IncrementPacketsReceived()

    -
    +

    Increments the count of received packets by one.

    +
    Declaration
    @@ -343,7 +359,8 @@
    Declaration

    IncrementPacketsSent()

    -
    +

    Increments the count of sent packets by one.

    +
    Declaration
    @@ -353,7 +370,8 @@
    Declaration

    Reset()

    -
    +

    Resets all statistical counters to zero.

    +
    Declaration
    @@ -363,7 +381,7 @@
    Declaration

    ToString()

    -

    Returns a string that represents the current object.

    +

    Returns a string representation of the current network statistics.

    Declaration
    @@ -381,7 +399,7 @@
    Returns
    string -

    A string that represents the current object.

    +

    A formatted string containing bytes received/sent, packets received/sent, and loss information.

    diff --git a/docs/api/LiteNetLib.NetUtils.html b/docs/api/LiteNetLib.NetUtils.html index bdd956e7..18dba861 100644 --- a/docs/api/LiteNetLib.NetUtils.html +++ b/docs/api/LiteNetLib.NetUtils.html @@ -216,7 +216,8 @@
    Parameters

    MakeEndPoint(string, int)

    -
    +

    Creates an IPEndPoint from a host string and a port.

    +
    Declaration
    @@ -235,12 +236,14 @@
    Parameters
    string hostStr - +

    The host name or IP address string to resolve.

    + int port - +

    The port number for the endpoint.

    + @@ -255,7 +258,8 @@
    Returns
    IPEndPoint - +

    A new IPEndPoint instance.

    + @@ -263,7 +267,8 @@
    Returns

    ResolveAddress(string)

    -
    +

    Resolves a host string into an IPAddress.

    +
    Declaration
    @@ -282,7 +287,8 @@
    Parameters
    string hostStr - +

    The host name or IP address string (e.g., "127.0.0.1", "localhost", or "google.com").

    + @@ -297,7 +303,28 @@
    Returns
    IPAddress - +

    The resolved IPAddress.

    + + + + +
    Remarks
    +

    This method handles "localhost" specifically, attempts to parse the string as a direct IP, +and falls back to DNS resolution. It prioritizes IPv6 if IPv6Support is enabled.

    +
    +
    Exceptions
    + + + + + + + + + + +
    TypeCondition
    ArgumentException

    Thrown when the address cannot be resolved or is invalid.

    +
    @@ -305,7 +332,8 @@
    Returns

    ResolveAddress(string, AddressFamily)

    -
    +

    Resolves a host string using DNS for a specific AddressFamily.

    +
    Declaration
    @@ -324,12 +352,14 @@
    Parameters
    string hostStr - +

    The host name to resolve via DNS.

    + AddressFamily addressFamily - +

    The preferred address family (e.g., InterNetwork or InterNetworkV6).

    + @@ -344,7 +374,8 @@
    Returns
    IPAddress - +

    The first IPAddress matching the family, or null if no match is found.

    + diff --git a/docs/api/LiteNetLib.Utils.FastBitConverter.html b/docs/api/LiteNetLib.Utils.FastBitConverter.html index 63a61722..ba3f4c92 100644 --- a/docs/api/LiteNetLib.Utils.FastBitConverter.html +++ b/docs/api/LiteNetLib.Utils.FastBitConverter.html @@ -90,7 +90,8 @@

    Methods

    GetBytes<T>(byte[], int, T)

    -
    +

    Converts a value of type T into a byte array starting at the specified index.

    +
    Declaration
    @@ -109,17 +110,20 @@
    Parameters
    byte[] bytes - +

    The destination byte array.

    + int startIndex - +

    The zero-based index in bytes at which to begin writing.

    + T value - +

    The value to be converted and written.

    + @@ -134,7 +138,24 @@
    Type Parameters
    T - +

    The type of the value to convert. Must be an unmanaged/blittable type.

    + + + + +
    Exceptions
    + + + + + + + + + + +
    TypeCondition
    IndexOutOfRangeException

    Thrown when the bytes array is too small to contain the value at the given startIndex.

    +
    diff --git a/docs/api/LiteNetLib.Utils.INetSerializable.html b/docs/api/LiteNetLib.Utils.INetSerializable.html index 5dbba128..f536537a 100644 --- a/docs/api/LiteNetLib.Utils.INetSerializable.html +++ b/docs/api/LiteNetLib.Utils.INetSerializable.html @@ -9,7 +9,7 @@ - + @@ -71,7 +71,8 @@

    Interface INetSerializable

    -
    +

    Interface for implementing custom data serialization for network transmission.

    +
    Namespace: LiteNetLib.Utils
    Assembly: LiteNetLib.dll
    @@ -79,13 +80,17 @@
    Syntax
    public interface INetSerializable
    +
    Remarks
    +

    This is the most efficient way to send complex objects as it avoids reflection.

    +

    Methods

    Deserialize(NetDataReader)

    -
    +

    Reads the object data from the provided NetDataReader.

    +
    Declaration
    @@ -104,7 +109,8 @@
    Parameters
    NetDataReader reader - +

    The reader to extract data from.

    + @@ -112,7 +118,8 @@
    Parameters

    Serialize(NetDataWriter)

    -
    +

    Writes the object data into the provided NetDataWriter.

    +
    Declaration
    @@ -131,7 +138,8 @@
    Parameters
    NetDataWriter writer - +

    The writer to pack data into.

    + diff --git a/docs/api/LiteNetLib.Utils.NetDataWriter.html b/docs/api/LiteNetLib.Utils.NetDataWriter.html index d24d1d4a..39a22e04 100644 --- a/docs/api/LiteNetLib.Utils.NetDataWriter.html +++ b/docs/api/LiteNetLib.Utils.NetDataWriter.html @@ -1022,7 +1022,7 @@
    Parameters

    Put(string, int)

    -

    Serializes a string using a 2-byte float length header.

    +

    Serializes a string using a 2-byte ushort length header.

    Declaration
    diff --git a/docs/api/LiteNetLib.Utils.NetPacketProcessor.html b/docs/api/LiteNetLib.Utils.NetPacketProcessor.html index 8e539bf5..b80de24b 100644 --- a/docs/api/LiteNetLib.Utils.NetPacketProcessor.html +++ b/docs/api/LiteNetLib.Utils.NetPacketProcessor.html @@ -549,7 +549,8 @@
    Type Parameters

    SubscribeNetSerializable<T>(Action<T>)

    -
    +

    Registers a callback for a packet type that implements INetSerializable and has a parameterless constructor.

    +
    Declaration
    @@ -568,7 +569,8 @@
    Parameters
    Action<T> onReceive - +

    The delegate to be executed when the packet is received.

    + @@ -583,15 +585,20 @@
    Type Parameters
    T - +

    The type of the packet. Must implement INetSerializable and have a new() constraint.

    + +
    Remarks
    +

    To reduce allocations, this method uses a single internal reference to T for deserialization.

    +

    SubscribeNetSerializable<T>(Action<T>, Func<T>)

    -
    +

    Registers a callback for a packet type that implements INetSerializable, using a custom constructor.

    +
    Declaration
    @@ -610,12 +617,14 @@
    Parameters
    Action<T> onReceive - +

    The delegate to be executed when the packet is received.

    + Func<T> packetConstructor - +

    A function that returns a new instance of T.

    + @@ -630,7 +639,8 @@
    Type Parameters
    T - +

    The type of the packet. Must implement INetSerializable.

    + @@ -638,7 +648,8 @@
    Type Parameters

    SubscribeNetSerializable<T, TUserData>(Action<T, TUserData>)

    -
    +

    Registers a callback for a packet type that implements INetSerializable and has a parameterless constructor, supporting user data.

    +
    Declaration
    @@ -657,7 +668,8 @@
    Parameters
    Action<T, TUserData> onReceive - +

    The delegate to be executed when the packet is received.

    + @@ -672,19 +684,25 @@
    Type Parameters
    T - +

    The type of the packet. Must implement INetSerializable and have a new() constraint.

    + TUserData - +

    The type of the user data (typically NetPeer).

    + +
    Remarks
    +

    To reduce allocations, this method uses a single internal reference to T for deserialization.

    +

    SubscribeNetSerializable<T, TUserData>(Action<T, TUserData>, Func<T>)

    -
    +

    Registers a callback for a packet type that implements INetSerializable, using a custom constructor and supporting user data.

    +
    Declaration
    @@ -703,12 +721,14 @@
    Parameters
    Action<T, TUserData> onReceive - +

    The delegate to be executed when the packet is received.

    + Func<T> packetConstructor - +

    A function that returns a new instance of T.

    + @@ -723,11 +743,13 @@
    Type Parameters
    T - +

    The type of the packet. Must implement INetSerializable.

    + TUserData - +

    The type of the user data (typically NetPeer).

    + diff --git a/docs/api/LiteNetLib.Utils.html b/docs/api/LiteNetLib.Utils.html index 6e58066d..344fbc61 100644 --- a/docs/api/LiteNetLib.Utils.html +++ b/docs/api/LiteNetLib.Utils.html @@ -101,7 +101,8 @@

    Interfaces

    INetSerializable

    -
    +

    Interface for implementing custom data serialization for network transmission.

    +

    Enums

    diff --git a/docs/api/LiteNetLib.html b/docs/api/LiteNetLib.html index 842b779e..323dc0da 100644 --- a/docs/api/LiteNetLib.html +++ b/docs/api/LiteNetLib.html @@ -81,7 +81,8 @@

    EventBasedL

    Simple event based listener for simple setups and benchmarks

    EventBasedNatPunchListener

    -
    +

    An implementation of INatPunchListener that maps callbacks to events.

    +

    EventBasedNetListener

    Simple event based listener for simple setups and benchmarks

    @@ -119,7 +120,8 @@

    NetPeer

    Improved LiteNetPeer with full multi-channel support

    NetStatistics

    -
    +

    Thread-safe counter for network statistics including sent/received packets, bytes, and packet loss.

    +

    NetUtils

    Some specific network utilities

    @@ -142,7 +144,8 @@

    ILiteNetEventLi

    Interface for implementing own ILiteNetEventListener. This is a bit faster than use EventBasedListener

    INatPunchListener

    -
    +

    Interface for handling events related to NAT punchthrough and introduction.

    +

    INetEventListener

    Interface for implementing own INetEventListener. This is a bit faster than use EventBasedListener

    @@ -165,9 +168,11 @@

    LocalAddrType

    Address type that you want to receive from NetUtils.GetLocalIp method

    NatAddressType

    -
    +

    Specifies the type of network address discovered during NAT punchthrough.

    +

    NetEvent.EType

    -
    +

    Specifies the category of the network event.

    +

    NetLogLevel

    UnconnectedMessageType

    diff --git a/docs/manifest.json b/docs/manifest.json index 09864182..3d87716c 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -98,7 +98,7 @@ "Uid": null, "IsMRef": true, "Title": "LiteNetLib.EventBasedNatPunchListener", - "Summary": null + "Summary": "

    An implementation of that maps callbacks to events.

    \n" }, { "type": "ManagedReference", @@ -140,7 +140,7 @@ "Uid": null, "IsMRef": true, "Title": "LiteNetLib.INatPunchListener", - "Summary": null + "Summary": "

    Interface for handling events related to NAT punchthrough and introduction.

    \n" }, { "type": "ManagedReference", @@ -336,7 +336,7 @@ "Uid": null, "IsMRef": true, "Title": "LiteNetLib.NatAddressType", - "Summary": null + "Summary": "

    Specifies the type of network address discovered during NAT punchthrough.

    \n" }, { "type": "ManagedReference", @@ -406,7 +406,7 @@ "Uid": null, "IsMRef": true, "Title": "LiteNetLib.NetEvent.EType", - "Summary": null + "Summary": "

    Specifies the category of the network event.

    \n" }, { "type": "ManagedReference", @@ -490,7 +490,7 @@ "Uid": null, "IsMRef": true, "Title": "LiteNetLib.NetStatistics", - "Summary": null + "Summary": "

    Thread-safe counter for network statistics including sent/received packets, bytes, and packet loss.

    \n" }, { "type": "ManagedReference", @@ -588,7 +588,7 @@ "Uid": null, "IsMRef": true, "Title": "LiteNetLib.Utils.INetSerializable", - "Summary": null + "Summary": "

    Interface for implementing custom data serialization for network transmission.

    \n" }, { "type": "ManagedReference", @@ -728,7 +728,7 @@ "Uid": null, "IsMRef": true, "Title": "LiteNetLib.Utils.PreserveAttribute", - "Summary": "

    PreserveAttribute prevents byte code stripping from removing a class, method, field, or property.

    \n" + "Summary": "

    PreserveAttribute prevents byte code stripping from removing a class, method, field, or property.

    \n" }, { "type": "ManagedReference", From baf4601f87462c987593e72819a38f7dec463bb3 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Wed, 25 Mar 2026 23:03:49 +0200 Subject: [PATCH 249/261] version 2.1.2 --- .github/workflows/nuget-publish.yml | 4 ++-- LiteNetLib/LiteNetLib.csproj | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/nuget-publish.yml b/.github/workflows/nuget-publish.yml index a963bc33..fd5ee070 100644 --- a/.github/workflows/nuget-publish.yml +++ b/.github/workflows/nuget-publish.yml @@ -33,10 +33,10 @@ jobs: PACKAGE_NAME="litenetlib" # Extract version from project file - LOCAL_VERSION=$(grep -o '[^<]*' "$PROJECT_PATH" | sed 's/\(.*\)<\/Version>/\1/') + LOCAL_VERSION=$(grep -o '[^<]*' "$PROJECT_PATH" | sed 's/\(.*\)<\/PackageVersion>/\1/') if [ -z "$LOCAL_VERSION" ]; then - echo "No tag found in $PROJECT_PATH" + echo "No tag found in $PROJECT_PATH" echo "has_packages=false" >> $GITHUB_OUTPUT exit 0 fi diff --git a/LiteNetLib/LiteNetLib.csproj b/LiteNetLib/LiteNetLib.csproj index e53cde48..856206b5 100644 --- a/LiteNetLib/LiteNetLib.csproj +++ b/LiteNetLib/LiteNetLib.csproj @@ -10,11 +10,11 @@ true 1701;1702;1705;1591 - 2.1.0 + 2.1.2 Lite reliable UDP library for Mono and .NET true true - 2.1.0 + 2.1.2 @@ -33,7 +33,7 @@ true $(DefineConstants);LITENETLIB_UNSAFE udp reliable-udp network - https://github.com/RevenantX/LiteNetLib/releases/tag/2.1.0 + https://github.com/RevenantX/LiteNetLib/releases/tag/2.1.2 git https://github.com/RevenantX/LiteNetLib https://github.com/RevenantX/LiteNetLib From 55f1d306dcb988c7bddd6bfe52e48d3bcd5d2447 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Fri, 27 Mar 2026 16:37:18 +0200 Subject: [PATCH 250/261] add MaxPacketPerManualReceive option and fix macos manual mode (cherry picked from commit e2de9ed52bfc576434634c9980d99f46f67fd01b) --- LiteNetLib/LiteNetManager.Socket.cs | 11 ++++++++--- LiteNetLib/LiteNetManager.cs | 6 ++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/LiteNetManager.Socket.cs b/LiteNetLib/LiteNetManager.Socket.cs index 522e86a0..2f1e35a3 100644 --- a/LiteNetLib/LiteNetManager.Socket.cs +++ b/LiteNetLib/LiteNetManager.Socket.cs @@ -101,9 +101,14 @@ private void ManualReceive(Socket socket, EndPoint bufferEndPoint) //Reading data try { - int available = socket.Available; - while (available > 0) - available -= ReceiveFrom(socket, ref bufferEndPoint); + int count = MaxPacketPerManualReceive; + while (socket.Available > 0 && (count > 0 || MaxPacketPerManualReceive == 0)) + { + if(ReceiveFrom(socket, ref bufferEndPoint) > 0) + count--; + else + break; + } } catch (SocketException ex) { diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index 5769b888..2903e8d8 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -269,6 +269,12 @@ private struct OutboundDelayedPacket ///
    public int ConnectedPeersCount => (int)Interlocked.Read(ref _connectedPeersCount); + /// + /// Maximum packets that can be received per one ManualReceive (PollEvents when started using StartInManualMode) + /// 0 - infinite - but this can cause some big delays there is too many incoming packets + /// + public int MaxPacketPerManualReceive = 256; + /// /// Gets the additional size in bytes required by the active . /// From 8c6300bc9001d5a2184c03b49ff9397c51186436 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Fri, 27 Mar 2026 17:04:22 +0200 Subject: [PATCH 251/261] add advance (default true) argument for GetRemainingBytes for some use cases --- LiteNetLib/Utils/NetDataReader.cs | 70 +++++++++++++++++-------------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 6ab35568..230f3df4 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -541,69 +541,53 @@ public ArraySegment GetBytesSegment(int count) /// /// Gets an containing all remaining s. /// + /// advance position after call /// An from the current position to the end of the data. - public ArraySegment GetRemainingBytesSegment() + public ArraySegment GetRemainingBytesSegment(bool advance = true) { ArraySegment segment = new ArraySegment(_data, _position, AvailableBytes); - _position = _dataSize; + if(advance) + _position = _dataSize; return segment; } - /// - /// Deserializes a that implements . - /// - /// A type implementing . - /// The deserialized . - public T Get() where T : struct, INetSerializable - { - Get(out T result); - return result; - } - - /// - /// Deserializes a that implements using a provided constructor. - /// - /// A type implementing . - /// The factory used to instantiate the . - /// A new instance of . - public T Get(Func constructor) where T : class, INetSerializable - { - Get(out T result, constructor); - return result; - } - /// /// Returns a of s containing all remaining data. /// + /// advance position after call /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlySpan GetRemainingBytesSpan() + public ReadOnlySpan GetRemainingBytesSpan(bool advance = true) { var result = new ReadOnlySpan(_data, _position, AvailableBytes); - _position = _dataSize; + if(advance) + _position = _dataSize; return result; } /// /// Returns a of s containing all remaining data. /// + /// advance position after call /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlyMemory GetRemainingBytesMemory() + public ReadOnlyMemory GetRemainingBytesMemory(bool advance = true) { var result = new ReadOnlyMemory(_data, _position, AvailableBytes); - _position = _dataSize; + if(advance) + _position = _dataSize; return result; } /// /// Reads all remaining s and returns them as a new array. /// + /// advance position after call /// A new array containing the remaining data. /// /// This method performs a heap allocation and advances the to the end of the data. /// - public byte[] GetRemainingBytes() + public byte[] GetRemainingBytes(bool advance = true) { int size = _dataSize - _position; if (size == 0) @@ -611,7 +595,31 @@ public byte[] GetRemainingBytes() byte[] result = new byte[size]; Buffer.BlockCopy(_data, _position, result, 0, size); - _position = _dataSize; + if(advance) + _position = _dataSize; + return result; + } + + /// + /// Deserializes a that implements . + /// + /// A type implementing . + /// The deserialized . + public T Get() where T : struct, INetSerializable + { + Get(out T result); + return result; + } + + /// + /// Deserializes a that implements using a provided constructor. + /// + /// A type implementing . + /// The factory used to instantiate the . + /// A new instance of . + public T Get(Func constructor) where T : class, INetSerializable + { + Get(out T result, constructor); return result; } From b691c7fdf351e9b2843f4e871f03966ec3d65a65 Mon Sep 17 00:00:00 2001 From: Lacyway <20912169+Lacyway@users.noreply.github.com> Date: Fri, 27 Mar 2026 17:11:14 +0100 Subject: [PATCH 252/261] Update methods to stay more consistent with rest of API --- LiteNetLib/Utils/NetDataReader.cs | 62 +++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/LiteNetLib/Utils/NetDataReader.cs b/LiteNetLib/Utils/NetDataReader.cs index 230f3df4..2e230009 100644 --- a/LiteNetLib/Utils/NetDataReader.cs +++ b/LiteNetLib/Utils/NetDataReader.cs @@ -541,53 +541,46 @@ public ArraySegment GetBytesSegment(int count) /// /// Gets an containing all remaining s. /// - /// advance position after call /// An from the current position to the end of the data. - public ArraySegment GetRemainingBytesSegment(bool advance = true) + public ArraySegment GetRemainingBytesSegment() { ArraySegment segment = new ArraySegment(_data, _position, AvailableBytes); - if(advance) - _position = _dataSize; + _position = _dataSize; return segment; } /// /// Returns a of s containing all remaining data. /// - /// advance position after call /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlySpan GetRemainingBytesSpan(bool advance = true) + public ReadOnlySpan GetRemainingBytesSpan() { var result = new ReadOnlySpan(_data, _position, AvailableBytes); - if(advance) - _position = _dataSize; + _position = _dataSize; return result; } /// /// Returns a of s containing all remaining data. /// - /// advance position after call /// A from the current to the end of the buffer. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ReadOnlyMemory GetRemainingBytesMemory(bool advance = true) + public ReadOnlyMemory GetRemainingBytesMemory() { var result = new ReadOnlyMemory(_data, _position, AvailableBytes); - if(advance) - _position = _dataSize; + _position = _dataSize; return result; } /// /// Reads all remaining s and returns them as a new array. /// - /// advance position after call /// A new array containing the remaining data. /// /// This method performs a heap allocation and advances the to the end of the data. /// - public byte[] GetRemainingBytes(bool advance = true) + public byte[] GetRemainingBytes() { int size = _dataSize - _position; if (size == 0) @@ -595,8 +588,7 @@ public byte[] GetRemainingBytes(bool advance = true) byte[] result = new byte[size]; Buffer.BlockCopy(_data, _position, result, 0, size); - if(advance) - _position = _dataSize; + _position = _dataSize; return result; } @@ -809,6 +801,44 @@ public unsafe T PeekUnmanaged() where T : unmanaged #endif } + /// + /// Returns a of s containing all remaining data without advancing the reader . + /// + /// A from the current to the end of the buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan PeekRemainingBytesSpan() + { + return new ReadOnlySpan(_data, _position, AvailableBytes); + } + + /// + /// Returns a of s containing all remaining data without advancing the reader . + /// + /// A from the current to the end of the buffer. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlyMemory PeekRemainingBytesMemory() + { + return new ReadOnlyMemory(_data, _position, AvailableBytes); + } + + /// + /// Reads all remaining s and returns them as a new array without advancing the reader . + /// + /// A new array containing the remaining data. + /// + /// This method performs a heap allocation by copying the data into a new array. + /// + public byte[] PeekRemainingBytes() + { + int size = _dataSize - _position; + if (size == 0) + return Array.Empty(); + + byte[] result = new byte[size]; + Buffer.BlockCopy(_data, _position, result, 0, size); + return result; + } + #endregion #region TryGetMethods From 329b16c1423db86bd64deead216afbab0cd972c6 Mon Sep 17 00:00:00 2001 From: Stiefel Jackal Date: Wed, 15 Apr 2026 22:11:58 -0500 Subject: [PATCH 253/261] fix(LiteNetPeer): get packets count in reliable unordered channel --- LiteNetLib/LiteNetPeer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index fd4cc561..78ba2e9d 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -339,7 +339,7 @@ private void OverrideMtu(int mtuValue) /// type of channel ReliableOrdered or ReliableUnordered /// packets count in channel queue public int GetPacketsCountInReliableQueue(bool ordered) => - _reliableChannel?.PacketsInQueue ?? 0; + (ordered ? _reliableChannel : _reliableUnorderedChannel)?.PacketsInQueue ?? 0; /// /// Create temporary packet (maximum size MTU - headerSize) to send later without additional copies From ef66d4fbff11783c6662729801548fc28cc2e402 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Sat, 18 Apr 2026 09:30:51 +0300 Subject: [PATCH 254/261] Add GetPacketsCountInReliableQueue new method for NetPeer --- LiteNetLib/NetPeer.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/LiteNetLib/NetPeer.cs b/LiteNetLib/NetPeer.cs index fcc304c5..3be8844e 100644 --- a/LiteNetLib/NetPeer.cs +++ b/LiteNetLib/NetPeer.cs @@ -195,6 +195,14 @@ public int GetPacketsCountInReliableQueue(byte channelNumber, bool ordered) return ((ReliableChannel)_channels[idx])?.PacketsInQueue ?? 0; } + /// + /// Returns packets count in queue for reliable channel 0 + /// + /// type of channel ReliableOrdered or ReliableUnordered + /// packets count in channel queue + public new int GetPacketsCountInReliableQueue(bool ordered) => + GetPacketsCountInReliableQueue(0, ordered); + protected override void UpdateChannels() { //Pending send From ed6ac2e8384d76f76c5f56d85bd558cb9a9f4618 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Sat, 18 Apr 2026 09:31:41 +0300 Subject: [PATCH 255/261] 2.1.3 and docs --- LiteNetLib/LiteNetLib.csproj | 6 +- docs/api/LiteNetLib.LiteNetManager.html | 26 ++++++ docs/api/LiteNetLib.NetManager.html | 3 + docs/api/LiteNetLib.NetPacketReader.html | 19 +++-- docs/api/LiteNetLib.NetPeer.html | 48 ++++++++++- docs/api/LiteNetLib.Utils.NetDataReader.html | 84 ++++++++++++++++++++ docs/xrefmap.yml | 54 +++++++++++++ 7 files changed, 229 insertions(+), 11 deletions(-) diff --git a/LiteNetLib/LiteNetLib.csproj b/LiteNetLib/LiteNetLib.csproj index 856206b5..fa18ce06 100644 --- a/LiteNetLib/LiteNetLib.csproj +++ b/LiteNetLib/LiteNetLib.csproj @@ -10,11 +10,11 @@ true 1701;1702;1705;1591 - 2.1.2 + 2.1.3 Lite reliable UDP library for Mono and .NET true true - 2.1.2 + 2.1.3 @@ -33,7 +33,7 @@ true $(DefineConstants);LITENETLIB_UNSAFE udp reliable-udp network - https://github.com/RevenantX/LiteNetLib/releases/tag/2.1.2 + https://github.com/RevenantX/LiteNetLib/releases/tag/2.1.3 git https://github.com/RevenantX/LiteNetLib https://github.com/RevenantX/LiteNetLib diff --git a/docs/api/LiteNetLib.LiteNetManager.html b/docs/api/LiteNetLib.LiteNetManager.html index b687ab16..96542635 100644 --- a/docs/api/LiteNetLib.LiteNetManager.html +++ b/docs/api/LiteNetLib.LiteNetManager.html @@ -409,6 +409,32 @@
    Field Value
    +

    MaxPacketPerManualReceive

    +

    Maximum packets that can be received per one ManualReceive (PollEvents when started using StartInManualMode) +0 - infinite - but this can cause some big delays there is too many incoming packets

    +
    +
    +
    Declaration
    +
    +
    public int MaxPacketPerManualReceive
    +
    +
    Field Value
    + + + + + + + + + + + + + +
    TypeDescription
    int
    + +

    MtuDiscovery

    Automatically discovery mtu starting from. Use at own risk because some routers can break MTU detection and connection in result

    diff --git a/docs/api/LiteNetLib.NetManager.html b/docs/api/LiteNetLib.NetManager.html index 86c94fa8..4e240dbe 100644 --- a/docs/api/LiteNetLib.NetManager.html +++ b/docs/api/LiteNetLib.NetManager.html @@ -184,6 +184,9 @@
    Inherited Members
    + diff --git a/docs/api/LiteNetLib.NetPacketReader.html b/docs/api/LiteNetLib.NetPacketReader.html index 9a8ae4b3..df51c9cb 100644 --- a/docs/api/LiteNetLib.NetPacketReader.html +++ b/docs/api/LiteNetLib.NetPacketReader.html @@ -277,19 +277,19 @@
    Inherited Members
    NetDataReader.GetRemainingBytesSegment()
    NetDataReader.GetBytes(byte[], int, int) @@ -357,6 +357,15 @@
    Inherited Members
    + + + diff --git a/docs/api/LiteNetLib.NetPeer.html b/docs/api/LiteNetLib.NetPeer.html index 45070f98..c8234ae8 100644 --- a/docs/api/LiteNetLib.NetPeer.html +++ b/docs/api/LiteNetLib.NetPeer.html @@ -132,9 +132,6 @@
    Inherited Members
    - @@ -298,6 +295,51 @@
    Returns
    + +

    GetPacketsCountInReliableQueue(bool)

    +

    Returns packets count in queue for reliable channel 0

    +
    +
    +
    Declaration
    +
    +
    public int GetPacketsCountInReliableQueue(bool ordered)
    +
    +
    Parameters
    + + + + + + + + + + + + + + + +
    TypeNameDescription
    boolordered

    type of channel ReliableOrdered or ReliableUnordered

    +
    +
    Returns
    + + + + + + + + + + + + + +
    TypeDescription
    int

    packets count in channel queue

    +
    + +

    GetPacketsCountInReliableQueue(byte, bool)

    Returns packets count in queue for reliable channel

    diff --git a/docs/api/LiteNetLib.Utils.NetDataReader.html b/docs/api/LiteNetLib.Utils.NetDataReader.html index e12c546e..4b210e38 100644 --- a/docs/api/LiteNetLib.Utils.NetDataReader.html +++ b/docs/api/LiteNetLib.Utils.NetDataReader.html @@ -2791,6 +2791,90 @@
    Returns
    + +

    PeekRemainingBytes()

    +

    Reads all remaining bytes and returns them as a new array without advancing the reader _position.

    +
    +
    +
    Declaration
    +
    +
    public byte[] PeekRemainingBytes()
    +
    +
    Returns
    + + + + + + + + + + + + + +
    TypeDescription
    byte[]

    A new byte array containing the remaining data.

    +
    +
    Remarks
    +

    This method performs a heap allocation by copying the data into a new array.

    +
    + + + +

    PeekRemainingBytesMemory()

    +

    Returns a ReadOnlyMemory<T> of bytes containing all remaining data without advancing the reader _position.

    +
    +
    +
    Declaration
    +
    +
    public ReadOnlyMemory<byte> PeekRemainingBytesMemory()
    +
    +
    Returns
    + + + + + + + + + + + + + +
    TypeDescription
    ReadOnlyMemory<byte>

    A ReadOnlyMemory<T> from the current Position to the end of the buffer.

    +
    + + + +

    PeekRemainingBytesSpan()

    +

    Returns a ReadOnlySpan<T> of bytes containing all remaining data without advancing the reader _position.

    +
    +
    +
    Declaration
    +
    +
    public ReadOnlySpan<byte> PeekRemainingBytesSpan()
    +
    +
    Returns
    + + + + + + + + + + + + + +
    TypeDescription
    ReadOnlySpan<byte>

    A ReadOnlySpan<T> from the current Position to the end of the buffer.

    +
    + +

    PeekSByte()

    Reads the sbyte at the current position without advancing the Position.

    diff --git a/docs/xrefmap.yml b/docs/xrefmap.yml index 3dde95bc..02999b85 100644 --- a/docs/xrefmap.yml +++ b/docs/xrefmap.yml @@ -1789,6 +1789,12 @@ references: commentId: F:LiteNetLib.LiteNetManager.MaxFragmentsCount fullName: LiteNetLib.LiteNetManager.MaxFragmentsCount nameWithType: LiteNetManager.MaxFragmentsCount +- uid: LiteNetLib.LiteNetManager.MaxPacketPerManualReceive + name: MaxPacketPerManualReceive + href: api/LiteNetLib.LiteNetManager.html#LiteNetLib_LiteNetManager_MaxPacketPerManualReceive + commentId: F:LiteNetLib.LiteNetManager.MaxPacketPerManualReceive + fullName: LiteNetLib.LiteNetManager.MaxPacketPerManualReceive + nameWithType: LiteNetManager.MaxPacketPerManualReceive - uid: LiteNetLib.LiteNetManager.MtuDiscovery name: MtuDiscovery href: api/LiteNetLib.LiteNetManager.html#LiteNetLib_LiteNetManager_MtuDiscovery @@ -3715,6 +3721,15 @@ references: isSpec: "True" fullName: LiteNetLib.NetPeer.CreatePacketFromPool nameWithType: NetPeer.CreatePacketFromPool +- uid: LiteNetLib.NetPeer.GetPacketsCountInReliableQueue(System.Boolean) + name: GetPacketsCountInReliableQueue(bool) + href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_GetPacketsCountInReliableQueue_System_Boolean_ + commentId: M:LiteNetLib.NetPeer.GetPacketsCountInReliableQueue(System.Boolean) + name.vb: GetPacketsCountInReliableQueue(Boolean) + fullName: LiteNetLib.NetPeer.GetPacketsCountInReliableQueue(bool) + fullName.vb: LiteNetLib.NetPeer.GetPacketsCountInReliableQueue(Boolean) + nameWithType: NetPeer.GetPacketsCountInReliableQueue(bool) + nameWithType.vb: NetPeer.GetPacketsCountInReliableQueue(Boolean) - uid: LiteNetLib.NetPeer.GetPacketsCountInReliableQueue(System.Byte,System.Boolean) name: GetPacketsCountInReliableQueue(byte, bool) href: api/LiteNetLib.NetPeer.html#LiteNetLib_NetPeer_GetPacketsCountInReliableQueue_System_Byte_System_Boolean_ @@ -5251,6 +5266,45 @@ references: isSpec: "True" fullName: LiteNetLib.Utils.NetDataReader.PeekLong nameWithType: NetDataReader.PeekLong +- uid: LiteNetLib.Utils.NetDataReader.PeekRemainingBytes + name: PeekRemainingBytes() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekRemainingBytes + commentId: M:LiteNetLib.Utils.NetDataReader.PeekRemainingBytes + fullName: LiteNetLib.Utils.NetDataReader.PeekRemainingBytes() + nameWithType: NetDataReader.PeekRemainingBytes() +- uid: LiteNetLib.Utils.NetDataReader.PeekRemainingBytes* + name: PeekRemainingBytes + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekRemainingBytes_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.PeekRemainingBytes + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.PeekRemainingBytes + nameWithType: NetDataReader.PeekRemainingBytes +- uid: LiteNetLib.Utils.NetDataReader.PeekRemainingBytesMemory + name: PeekRemainingBytesMemory() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekRemainingBytesMemory + commentId: M:LiteNetLib.Utils.NetDataReader.PeekRemainingBytesMemory + fullName: LiteNetLib.Utils.NetDataReader.PeekRemainingBytesMemory() + nameWithType: NetDataReader.PeekRemainingBytesMemory() +- uid: LiteNetLib.Utils.NetDataReader.PeekRemainingBytesMemory* + name: PeekRemainingBytesMemory + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekRemainingBytesMemory_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.PeekRemainingBytesMemory + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.PeekRemainingBytesMemory + nameWithType: NetDataReader.PeekRemainingBytesMemory +- uid: LiteNetLib.Utils.NetDataReader.PeekRemainingBytesSpan + name: PeekRemainingBytesSpan() + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekRemainingBytesSpan + commentId: M:LiteNetLib.Utils.NetDataReader.PeekRemainingBytesSpan + fullName: LiteNetLib.Utils.NetDataReader.PeekRemainingBytesSpan() + nameWithType: NetDataReader.PeekRemainingBytesSpan() +- uid: LiteNetLib.Utils.NetDataReader.PeekRemainingBytesSpan* + name: PeekRemainingBytesSpan + href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekRemainingBytesSpan_ + commentId: Overload:LiteNetLib.Utils.NetDataReader.PeekRemainingBytesSpan + isSpec: "True" + fullName: LiteNetLib.Utils.NetDataReader.PeekRemainingBytesSpan + nameWithType: NetDataReader.PeekRemainingBytesSpan - uid: LiteNetLib.Utils.NetDataReader.PeekSByte name: PeekSByte() href: api/LiteNetLib.Utils.NetDataReader.html#LiteNetLib_Utils_NetDataReader_PeekSByte From 67e3d310b7b53b4b8fe1b461500cbfe56fdddbcd Mon Sep 17 00:00:00 2001 From: Kirill Artemov Date: Sun, 3 May 2026 18:46:57 +0200 Subject: [PATCH 256/261] Add NetManager.SendToAll overloads with ReadOnlySpan support --- LiteNetLib/NetManager.cs | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/LiteNetLib/NetManager.cs b/LiteNetLib/NetManager.cs index 8ff80cfe..fc02a659 100644 --- a/LiteNetLib/NetManager.cs +++ b/LiteNetLib/NetManager.cs @@ -314,6 +314,39 @@ public void SendToAll(byte[] data, int start, int length, byte channelNumber, De } } + /// + /// Send data to all connected peers + /// + /// Data + /// Number of channel (from 0 to channelsCount - 1) + /// Send options (reliable, unreliable, etc.) + public void SendToAll(ReadOnlySpan data, byte channelNumber, DeliveryMethod options) => + SendToAll(data, channelNumber, options, null); + + /// + /// Send data to all connected peers + /// + /// Data + /// Number of channel (from 0 to channelsCount - 1) + /// Send options (reliable, unreliable, etc.) + /// Excluded peer + public void SendToAll(ReadOnlySpan data, byte channelNumber, DeliveryMethod options, LiteNetPeer excludePeer) + { + try + { + _peersLock.EnterReadLock(); + for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) + { + if (netPeer != excludePeer) + ((NetPeer)netPeer).Send(data, channelNumber, options); + } + } + finally + { + _peersLock.ExitReadLock(); + } + } + /// /// Connect to remote host /// From ae8ece75ee2c5014a46ebd641319eb4097c1e39d Mon Sep 17 00:00:00 2001 From: Ruslan Pyrch Date: Wed, 6 May 2026 10:08:02 +0300 Subject: [PATCH 257/261] Update README.md for LiteNetLib (fix #609) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a21898fd..85caa020 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ var listener = new EventBasedNetListener(); var client = new NetManager(listener); client.Start(); client.Connect("localhost" /* host IP or name */, 9050 /* port */, "SomeConnectionKey" /* text key or NetDataWriter */); -listener.NetworkReceiveEvent += (fromPeer, dataReader, deliveryMethod, channel) => +listener.NetworkReceiveEvent += (fromPeer, dataReader, channel, deliveryMethod) => { Console.WriteLine("We got: {0}", dataReader.GetString(100 /* max length of string */)); dataReader.Recycle(); From f9d506f26e5677a18a233f3612dedde3fd419dcd Mon Sep 17 00:00:00 2001 From: RevenantX Date: Tue, 19 May 2026 10:56:18 +0300 Subject: [PATCH 258/261] do not simulate outbound latency for disconnect message. Also optimize a bit SendRaw --- LiteNetLib/LiteNetManager.Socket.cs | 18 ++++-------------- LiteNetLib/LiteNetManager.cs | 27 +++++++++++++++++---------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/LiteNetLib/LiteNetManager.Socket.cs b/LiteNetLib/LiteNetManager.Socket.cs index 2f1e35a3..97d6870b 100644 --- a/LiteNetLib/LiteNetManager.Socket.cs +++ b/LiteNetLib/LiteNetManager.Socket.cs @@ -545,20 +545,10 @@ internal int SendRaw(byte[] message, int start, int length, IPEndPoint remoteEnd } #endif - return SendRawCoreWithCleanup(message, start, length, remoteEndPoint, expandedPacket); - } - - private int SendRawCoreWithCleanup(byte[] message, int start, int length, IPEndPoint remoteEndPoint, NetPacket expandedPacket) - { - try - { - return SendRawCore(message, start, length, remoteEndPoint); - } - finally - { - if (expandedPacket != null) - PoolRecycle(expandedPacket); - } + int result = SendRawCore(message, start, length, remoteEndPoint); + if (expandedPacket != null) + PoolRecycle(expandedPacket); + return result; } // Core socket sending logic without simulation - used by both SendRaw and delayed packet processing diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index 2903e8d8..d093accc 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -45,6 +45,7 @@ public void Reset() => object IEnumerator.Current => _p; } +#if DEBUG || SIMULATE_NETWORK private struct IncomingData { public NetPacket Data; @@ -53,7 +54,6 @@ private struct IncomingData } private readonly List _pingSimulationList = new List(); -#if DEBUG || SIMULATE_NETWORK private struct OutboundDelayedPacket { public byte[] Data; @@ -556,6 +556,7 @@ private void ProcessDelayedPackets() if (!SimulateLatency) return; +#if DEBUG || SIMULATE_NETWORK var time = DateTime.UtcNow; lock (_pingSimulationList) { @@ -571,7 +572,6 @@ private void ProcessDelayedPackets() } } -#if DEBUG || SIMULATE_NETWORK lock (_outboundSimulationList) { for (int i = 0; i < _outboundSimulationList.Count; i++) @@ -765,7 +765,7 @@ private void HandleSimulateLatency(NetPacket packet, IPEndPoint remoteEndPoint) { return; } - +#if DEBUG || SIMULATE_NETWORK int roundTripLatency = _randomGenerator.Next(SimulationMinLatency, SimulationMaxLatency); int inboundLatency = roundTripLatency / 2; if (inboundLatency > MinLatencyThreshold) @@ -782,6 +782,7 @@ private void HandleSimulateLatency(NetPacket packet, IPEndPoint remoteEndPoint) // hold packet _dropPacket = true; } +#endif } [Conditional("DEBUG"), Conditional("SIMULATE_NETWORK")] @@ -828,11 +829,8 @@ private bool HandleSimulateOutboundLatency(byte[] data, int start, int length, I #endif #if DEBUG || SIMULATE_NETWORK - private bool HandleSimulateOutboundPacketLoss() - { - bool shouldDrop = SimulatePacketLoss && _randomGenerator.NextDouble() * 100 < SimulationPacketLossChance; - return shouldDrop; - } + private bool HandleSimulateOutboundPacketLoss() => //Should Drop? + SimulatePacketLoss && _randomGenerator.NextDouble() * 100 < SimulationPacketLossChance; #endif internal virtual bool CustomMessageHandle(NetPacket packet, IPEndPoint remoteEndPoint) => @@ -1482,8 +1480,14 @@ public void Stop(bool sendDisconnectMessages) { if (!_isRunning) return; + NetDebug.Write("[NM] Stop"); + //Little hack so shutdown message will not be queued by Outbound latency simulation + //In real world packet will be delayed by routers not by application(that closes) logic + var simLat = SimulateLatency; + SimulateLatency = false; + //Send last disconnect for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) netPeer.Shutdown(null, 0, 0, !sendDisconnectMessages); @@ -1491,6 +1495,9 @@ public void Stop(bool sendDisconnectMessages) //Stop CloseSocket(); + //Return setting + SimulateLatency = simLat; + #if UNITY_SOCKET_FIX if (_useSocketFix) { @@ -1519,14 +1526,14 @@ public void Stop(bool sendDisconnectMessages) _pendingEventTail = null; } - [Conditional("DEBUG"), Conditional("SIMULATE_NETWORK")] private void ClearPingSimulationList() { +#if DEBUG || SIMULATE_NETWORK lock (_pingSimulationList) _pingSimulationList.Clear(); +#endif } - [Conditional("DEBUG"), Conditional("SIMULATE_NETWORK")] private void ClearOutboundSimulationList() { #if DEBUG || SIMULATE_NETWORK From 7949480c3d7677813f49d6bf6ac22aa64e503a49 Mon Sep 17 00:00:00 2001 From: RevenantX Date: Tue, 19 May 2026 10:58:28 +0300 Subject: [PATCH 259/261] simplify code --- LiteNetLib/LiteNetManager.cs | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index d093accc..f9ee0012 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -1518,28 +1518,16 @@ public void Stop(bool sendDisconnectMessages) _peerIds = new ConcurrentQueue(); _lastPeerId = 0; - ClearPingSimulationList(); - ClearOutboundSimulationList(); - - _connectedPeersCount = 0; - _pendingEventHead = null; - _pendingEventTail = null; - } - - private void ClearPingSimulationList() - { #if DEBUG || SIMULATE_NETWORK lock (_pingSimulationList) _pingSimulationList.Clear(); -#endif - } - - private void ClearOutboundSimulationList() - { -#if DEBUG || SIMULATE_NETWORK lock (_outboundSimulationList) _outboundSimulationList.Clear(); #endif + + _connectedPeersCount = 0; + _pendingEventHead = null; + _pendingEventTail = null; } /// From 4d3de1e93abaead30199bf572f4a3363f854e14b Mon Sep 17 00:00:00 2001 From: RevenantX Date: Tue, 19 May 2026 11:04:43 +0300 Subject: [PATCH 260/261] version 2.1.4 --- LiteNetLib/LiteNetLib.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LiteNetLib/LiteNetLib.csproj b/LiteNetLib/LiteNetLib.csproj index fa18ce06..1b1249b1 100644 --- a/LiteNetLib/LiteNetLib.csproj +++ b/LiteNetLib/LiteNetLib.csproj @@ -10,11 +10,11 @@ true 1701;1702;1705;1591 - 2.1.3 + 2.1.4 Lite reliable UDP library for Mono and .NET true true - 2.1.3 + 2.1.4 @@ -33,7 +33,7 @@ true $(DefineConstants);LITENETLIB_UNSAFE udp reliable-udp network - https://github.com/RevenantX/LiteNetLib/releases/tag/2.1.3 + https://github.com/RevenantX/LiteNetLib/releases/tag/2.1.4 git https://github.com/RevenantX/LiteNetLib https://github.com/RevenantX/LiteNetLib From fedcaa013828b4c8057734aee02547b2a63d9ccd Mon Sep 17 00:00:00 2001 From: KingofBeast Date: Sun, 7 Jun 2026 00:01:53 -0500 Subject: [PATCH 261/261] Add ReadOnlySpan overloads to Reject/Disconnect methods --- LiteNetLib/ConnectionRequest.cs | 60 +++++++++++++++++++++++---------- LiteNetLib/LiteNetManager.cs | 53 ++++++++++++++++------------- LiteNetLib/LiteNetPeer.cs | 17 +++++----- 3 files changed, 82 insertions(+), 48 deletions(-) diff --git a/LiteNetLib/ConnectionRequest.cs b/LiteNetLib/ConnectionRequest.cs index 8fb15cf5..080009ab 100644 --- a/LiteNetLib/ConnectionRequest.cs +++ b/LiteNetLib/ConnectionRequest.cs @@ -1,4 +1,5 @@ -using System.Net; +using System; +using System.Net; using System.Threading; using LiteNetLib.Utils; @@ -76,10 +77,10 @@ public LiteNetPeer AcceptIfKey(string key) NetDebug.WriteError("[AC] Invalid incoming data"); } if (Result == ConnectionRequestResult.Accept) - return _listener.OnConnectionSolved(this, null, 0, 0); + return _listener.OnConnectionSolved(this, ReadOnlySpan.Empty); Result = ConnectionRequestResult.Reject; - _listener.OnConnectionSolved(this, null, 0, 0); + _listener.OnConnectionSolved(this, ReadOnlySpan.Empty); return null; } @@ -92,27 +93,38 @@ public LiteNetPeer Accept() if (!TryActivate()) return null; Result = ConnectionRequestResult.Accept; - return _listener.OnConnectionSolved(this, null, 0, 0); + return _listener.OnConnectionSolved(this, ReadOnlySpan.Empty); } /// /// Rejects the connection request. /// /// Optional user data to send along with the rejection packet. - /// Offset in the array. - /// Length of the data to be sent from the array. /// - /// If , immediately removes the request, if is not a reject packet is also sent.
    + /// If , immediately removes the request, if is not empty a reject packet is also sent.
    /// If , creates a temporary peer that sends rejection packets and lingers in memory until a timeout occurs to handle late-arriving packets. /// - public void Reject(byte[] rejectData, int start, int length, bool force) + public void Reject(ReadOnlySpan rejectData, bool force) { if (!TryActivate()) return; Result = force ? ConnectionRequestResult.RejectForce : ConnectionRequestResult.Reject; - _listener.OnConnectionSolved(this, rejectData, start, length); + _listener.OnConnectionSolved(this, rejectData); } + /// + /// Rejects the connection request. + /// + /// Optional user data to send along with the rejection packet. + /// Offset in the array. + /// Length of the data to be sent from the array. + /// + /// If , immediately removes the request, if is not a reject packet is also sent.
    + /// If , creates a temporary peer that sends rejection packets and lingers in memory until a timeout occurs to handle late-arriving packets. + /// + public void Reject(byte[] rejectData, int start, int length, bool force) => + Reject(new ReadOnlySpan(rejectData, start, length), force); + /// /// Rejects the connection reliably. Creates a temporary peer to handle packet loss. /// @@ -120,7 +132,7 @@ public void Reject(byte[] rejectData, int start, int length, bool force) /// Offset in the array. /// Length of the data to be sent. public void Reject(byte[] rejectData, int start, int length) => - Reject(rejectData, start, length, false); + Reject(new ReadOnlySpan(rejectData, start, length), false); /// /// Rejects the connection immediately without reliability. @@ -130,47 +142,61 @@ public void Reject(byte[] rejectData, int start, int length) => /// Offset in the array. /// Length of the data to be sent. public void RejectForce(byte[] rejectData, int start, int length) => - Reject(rejectData, start, length, true); + Reject(new ReadOnlySpan(rejectData, start, length), true); /// /// Rejects the connection immediately without sending any packet. /// public void RejectForce() => - Reject(null, 0, 0, true); + Reject(ReadOnlySpan.Empty, true); /// /// Rejects the connection immediately without reliability. /// /// Data to send with the rejection. public void RejectForce(byte[] rejectData) => - Reject(rejectData, 0, rejectData.Length, true); + Reject(new ReadOnlySpan(rejectData), true); /// /// Rejects the connection immediately without reliability using data from a . /// /// Writer containing the data to send. public void RejectForce(NetDataWriter rejectData) => - Reject(rejectData.Data, 0, rejectData.Length, true); + Reject(rejectData.AsReadOnlySpan(), true); + + /// + /// Rejects the connection immediately without reliability. + /// + /// Data to send with the rejection. + public void RejectForce(ReadOnlySpan rejectData) => + Reject(rejectData, true); /// /// Rejects the connection reliably without additional data. /// public void Reject() => - Reject(null, 0, 0, false); + Reject(ReadOnlySpan.Empty, false); /// /// Rejects the connection reliably. /// /// Data to send with the rejection. public void Reject(byte[] rejectData) => - Reject(rejectData, 0, rejectData.Length, false); + Reject(new ReadOnlySpan(rejectData), false); /// /// Rejects the connection reliably using data from a . /// /// Writer containing the data to send. public void Reject(NetDataWriter rejectData) => - Reject(rejectData.Data, 0, rejectData.Length, false); + Reject(rejectData.AsReadOnlySpan(), false); + + /// + /// Rejects the connection reliably. + /// + /// Data to send with the rejection. + public void Reject(ReadOnlySpan rejectData) => + Reject(rejectData, false); } public class ConnectionRequest : LiteConnectionRequest diff --git a/LiteNetLib/LiteNetManager.cs b/LiteNetLib/LiteNetManager.cs index f9ee0012..3d173ce7 100644 --- a/LiteNetLib/LiteNetManager.cs +++ b/LiteNetLib/LiteNetManager.cs @@ -313,7 +313,7 @@ internal void DisconnectPeerForce(LiteNetPeer peer, DisconnectReason reason, SocketError socketErrorCode, NetPacket eventData) => - DisconnectPeer(peer, reason, socketErrorCode, true, null, 0, 0, eventData); + DisconnectPeer(peer, reason, socketErrorCode, true, ReadOnlySpan.Empty, eventData); /// /// Disconnects a peer and handles internal state cleanup. @@ -327,20 +327,16 @@ internal void DisconnectPeerForce(LiteNetPeer peer, /// Peer will linger until to ignore late-arriving packets from the old session. /// /// Optional custom data to include in the disconnect packet. - /// Offset in the array. - /// Number of bytes to send from the array. /// Internal packet data associated with the disconnect event. private void DisconnectPeer( LiteNetPeer peer, DisconnectReason reason, SocketError socketErrorCode, bool force, - byte[] data, - int start, - int count, + ReadOnlySpan data, NetPacket eventData) { - var shutdownResult = peer.Shutdown(data, start, count, force); + var shutdownResult = peer.Shutdown(data, force); if (shutdownResult == ShutdownResult.None) return; if (shutdownResult == ShutdownResult.WasConnected) @@ -631,22 +627,22 @@ protected virtual LiteNetPeer CreateRejectPeer(IPEndPoint remoteEndPoint, int id protected virtual LiteConnectionRequest CreateConnectionRequest(IPEndPoint remoteEndPoint, NetConnectRequestPacket requestPacket) => new LiteConnectionRequest(remoteEndPoint, requestPacket, this); - internal LiteNetPeer OnConnectionSolved(LiteConnectionRequest request, byte[] rejectData, int start, int length) + internal LiteNetPeer OnConnectionSolved(LiteConnectionRequest request, ReadOnlySpan rejectData) { LiteNetPeer netPeer = null; if (request.Result == ConnectionRequestResult.RejectForce) { NetDebug.Write(NetLogLevel.Trace, "[NM] Peer connect reject force."); - if (rejectData != null && length > 0) + if (!rejectData.IsEmpty) { - var shutdownPacket = PoolGetWithProperty(PacketProperty.Disconnect, length); + var shutdownPacket = PoolGetWithProperty(PacketProperty.Disconnect, rejectData.Length); shutdownPacket.ConnectionNumber = request.InternalPacket.ConnectionNumber; FastBitConverter.GetBytes(shutdownPacket.RawData, 1, request.InternalPacket.ConnectionTime); if (shutdownPacket.Size >= NetConstants.PossibleMtu[0]) NetDebug.WriteError("[Peer] Disconnect additional data size more than MTU!"); else - Buffer.BlockCopy(rejectData, start, shutdownPacket.RawData, 9, length); + rejectData.CopyTo(shutdownPacket.RawData.AsSpan(9)); SendRawAndRecycle(shutdownPacket, request.RemoteEndPoint); } lock (_requestsDict) @@ -661,7 +657,7 @@ internal LiteNetPeer OnConnectionSolved(LiteConnectionRequest request, byte[] re else if (request.Result == ConnectionRequestResult.Reject) { netPeer = CreateRejectPeer(request.RemoteEndPoint, GetNextPeerId()); - netPeer.Reject(request.InternalPacket, rejectData, start, length); + netPeer.Reject(request.InternalPacket, rejectData); AddPeer(netPeer); NetDebug.Write(NetLogLevel.Trace, "[NM] Peer connect reject."); } @@ -1490,7 +1486,7 @@ public void Stop(bool sendDisconnectMessages) //Send last disconnect for (var netPeer = _headPeer; netPeer != null; netPeer = netPeer.NextPeer) - netPeer.Shutdown(null, 0, 0, !sendDisconnectMessages); + netPeer.Shutdown(ReadOnlySpan.Empty, !sendDisconnectMessages); //Stop CloseSocket(); @@ -1576,7 +1572,7 @@ public void GetConnectedPeers(List peers) => /// Disconnect all peers without any additional data /// public void DisconnectAll() => - DisconnectAll(null, 0, 0); + DisconnectAll(ReadOnlySpan.Empty); /// /// Disconnect all peers with shutdown message @@ -1584,7 +1580,14 @@ public void DisconnectAll() => /// Data to send (must be less or equal MTU) /// Data start /// Data count - public void DisconnectAll(byte[] data, int start, int count) + public void DisconnectAll(byte[] data, int start, int count) => + DisconnectAll(new ReadOnlySpan(data, start, count)); + + /// + /// Disconnect all peers with shutdown message + /// + /// Data to send (must be less or equal MTU) + public void DisconnectAll(ReadOnlySpan data) { //Send disconnect packets _peersLock.EnterReadLock(); @@ -1596,8 +1599,6 @@ public void DisconnectAll(byte[] data, int start, int count) 0, false, data, - start, - count, null); } _peersLock.ExitReadLock(); @@ -1615,7 +1616,7 @@ public void DisconnectPeerForce(LiteNetPeer peer) => /// /// peer to disconnect public void DisconnectPeer(LiteNetPeer peer) => - DisconnectPeer(peer, null, 0, 0); + DisconnectPeer(peer, ReadOnlySpan.Empty); /// /// Disconnect peer from server and send additional data (Size must be less or equal MTU - 8) @@ -1623,7 +1624,7 @@ public void DisconnectPeer(LiteNetPeer peer) => /// peer to disconnect /// additional data public void DisconnectPeer(LiteNetPeer peer, byte[] data) => - DisconnectPeer(peer, data, 0, data.Length); + DisconnectPeer(peer, new ReadOnlySpan(data)); /// /// Disconnect peer from server and send additional data (Size must be less or equal MTU - 8) @@ -1631,7 +1632,7 @@ public void DisconnectPeer(LiteNetPeer peer, byte[] data) => /// peer to disconnect /// additional data public void DisconnectPeer(LiteNetPeer peer, NetDataWriter writer) => - DisconnectPeer(peer, writer.Data, 0, writer.Length); + DisconnectPeer(peer, writer.AsReadOnlySpan()); /// /// Disconnect peer from server and send additional data (Size must be less or equal MTU - 8) @@ -1640,7 +1641,15 @@ public void DisconnectPeer(LiteNetPeer peer, NetDataWriter writer) => /// additional data /// data start /// data length - public void DisconnectPeer(LiteNetPeer peer, byte[] data, int start, int count) + public void DisconnectPeer(LiteNetPeer peer, byte[] data, int start, int count) => + DisconnectPeer(peer, new ReadOnlySpan(data, start, count)); + + /// + /// Disconnect peer from server and send additional data (Size must be less or equal MTU - 8) + /// + /// peer to disconnect + /// additional data + public void DisconnectPeer(LiteNetPeer peer, ReadOnlySpan data) { DisconnectPeer( peer, @@ -1648,8 +1657,6 @@ public void DisconnectPeer(LiteNetPeer peer, byte[] data, int start, int count) 0, false, data, - start, - count, null); } diff --git a/LiteNetLib/LiteNetPeer.cs b/LiteNetLib/LiteNetPeer.cs index 78ba2e9d..f36796c3 100644 --- a/LiteNetLib/LiteNetPeer.cs +++ b/LiteNetLib/LiteNetPeer.cs @@ -446,11 +446,11 @@ internal LiteNetPeer(LiteNetManager netManager, LiteConnectionRequest request, i } //Reject - internal void Reject(NetConnectRequestPacket requestData, byte[] data, int start, int length) + internal void Reject(NetConnectRequestPacket requestData, ReadOnlySpan data) { _connectTime = requestData.ConnectionTime; _connectNum = requestData.ConnectionNumber; - Shutdown(data, start, length, false); + Shutdown(data, false); } internal bool ProcessConnectAccept(NetConnectAcceptPacket packet) @@ -698,6 +698,9 @@ public void Disconnect(NetDataWriter writer) => public void Disconnect(byte[] data, int start, int count) => NetManager.DisconnectPeer(this, data, start, count); + public void Disconnect(ReadOnlySpan data) => + NetManager.DisconnectPeer(this, data); + public void Disconnect() => NetManager.DisconnectPeer(this); @@ -724,15 +727,13 @@ internal virtual void AddToReliableChannelSendQueue(BaseChannel channel) /// Internally handles the shutdown process for this peer. /// /// Optional data to include in the unreliable disconnect packet. - /// Offset in the array. - /// Length of the data to send. /// /// If , immediately sets state to without sending a notification.
    /// If , sends unreliable disconnect packets until a timeout occurs and sets state to /// Queued reliable packets are bypassed and dropped immediately. /// /// A indicating the state change transition. - internal ShutdownResult Shutdown(byte[] data, int start, int length, bool force) + internal ShutdownResult Shutdown(ReadOnlySpan data, bool force) { lock (_shutdownLock) { @@ -758,16 +759,16 @@ internal ShutdownResult Shutdown(byte[] data, int start, int length, bool force) Interlocked.Exchange(ref _timeSinceLastPacket, 0); //send shutdown packet - _shutdownPacket = new NetPacket(PacketProperty.Disconnect, length) {ConnectionNumber = _connectNum}; + _shutdownPacket = new NetPacket(PacketProperty.Disconnect, data.Length) {ConnectionNumber = _connectNum}; FastBitConverter.GetBytes(_shutdownPacket.RawData, 1, _connectTime); if (_shutdownPacket.Size >= _mtu) { //Drop additional data NetDebug.WriteError("[Peer] Disconnect additional data size more than MTU - 8!"); } - else if (data != null && length > 0) + else if (!data.IsEmpty) { - Buffer.BlockCopy(data, start, _shutdownPacket.RawData, 9, length); + data.CopyTo(_shutdownPacket.RawData.AsSpan(9)); } _connectionState = ConnectionState.ShutdownRequested; NetDebug.Write("[Peer] Send disconnect");