Merge pull request #2726 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2017-06-24 14:37:49 -04:00 committed by GitHub
commit 287178cbf5
34 changed files with 482 additions and 927 deletions

View File

@ -63,15 +63,15 @@ namespace Emby.Drawing.Skia
private void LogVersion()
{
// test an operation that requires the native library
SKPMColor.PreMultiply(SKColors.Black);
_logger.Info("SkiaSharp version: " + GetVersion());
}
public static string GetVersion()
{
using (var bitmap = new SKBitmap())
{
return typeof(SKBitmap).GetTypeInfo().Assembly.GetName().Version.ToString();
}
return typeof(SKBitmap).GetTypeInfo().Assembly.GetName().Version.ToString();
}
private static bool IsWhiteSpace(SKColor color)

View File

@ -410,6 +410,11 @@ namespace Emby.Drawing
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());
}
public ImageSize GetImageSize(ItemImageInfo info, bool allowSlowMethods)
{
return GetImageSize(info.Path, info.DateModified, allowSlowMethods);
}
public ImageSize GetImageSize(ItemImageInfo info)
{
return GetImageSize(info.Path, info.DateModified, false);

View File

@ -4297,12 +4297,9 @@ namespace Emby.Server.Implementations.Data
}
}
if (query.HasDeadParentId.HasValue)
if (query.HasDeadParentId.HasValue && query.HasDeadParentId.Value)
{
if (query.HasDeadParentId.Value)
{
whereClauses.Add("ParentId NOT NULL AND ParentId NOT IN (select guid from TypedBaseItems)");
}
whereClauses.Add("ParentId NOT NULL AND ParentId NOT IN (select guid from TypedBaseItems)");
}
if (query.Years.Length == 1)

View File

@ -49,8 +49,13 @@ namespace Emby.Server.Implementations.LiveTv.Listings
get { return "xmltv"; }
}
private string GetLanguage()
private string GetLanguage(ListingsProviderInfo info)
{
if (!string.IsNullOrWhiteSpace(info.PreferredLanguage))
{
return info.PreferredLanguage;
}
return _config.Configuration.PreferredMetadataLanguage;
}
@ -152,7 +157,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
_logger.Debug("Getting xmltv programs for channel {0}", channelId);
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
var reader = new XmlTvReader(path, GetLanguage());
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetProgrammes(channelId, startDateUtc, endDateUtc, cancellationToken);
return results.Select(p => GetProgramInfo(p, info));
@ -254,7 +259,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, CancellationToken.None).ConfigureAwait(false);
var reader = new XmlTvReader(path, GetLanguage());
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
// Should this method be async?
@ -265,7 +270,7 @@ namespace Emby.Server.Implementations.LiveTv.Listings
{
// In theory this should never be called because there is always only one lineup
var path = await GetXml(info.Path, cancellationToken).ConfigureAwait(false);
var reader = new XmlTvReader(path, GetLanguage());
var reader = new XmlTvReader(path, GetLanguage(info));
var results = reader.GetChannels();
// Should this method be async?

View File

@ -148,7 +148,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
},
RequiresOpening = true,
RequiresClosing = true,
RequiresLooping = true,
RequiresLooping = info.EnableStreamLooping,
ReadAtNativeFramerate = false,

View File

@ -265,7 +265,8 @@ namespace MediaBrowser.Api
Height = state.OutputHeight,
AudioChannels = state.OutputAudioChannels,
IsAudioDirect = string.Equals(state.OutputAudioCodec, "copy", StringComparison.OrdinalIgnoreCase),
IsVideoDirect = string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase)
IsVideoDirect = string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase),
TranscodeReasons = state.TranscodeReasons
});
}
}

View File

@ -326,7 +326,7 @@ namespace MediaBrowser.Api.Images
var fileInfo = _fileSystem.GetFileInfo(info.Path);
length = fileInfo.Length;
var size = _imageProcessor.GetImageSize(info);
var size = _imageProcessor.GetImageSize(info, true);
width = Convert.ToInt32(size.Width);
height = Convert.ToInt32(size.Height);

View File

@ -583,6 +583,10 @@ namespace MediaBrowser.Api.Playback
videoRequest.DeInterlace = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
}
}
else if (i == 33)
{
request.TranscodeReasons = val;
}
}
}

View File

@ -541,6 +541,11 @@ namespace MediaBrowser.Api.Playback.Hls
{
queryString += "&SegmentContainer=" + state.Request.SegmentContainer;
}
// from universal audio service
if (!string.IsNullOrWhiteSpace(state.Request.TranscodeReasons) && queryString.IndexOf("TranscodeReasons=", StringComparison.OrdinalIgnoreCase) == -1)
{
queryString += "&TranscodeReasons=" + state.Request.TranscodeReasons;
}
// Main stream
var playlistUrl = isLiveStream ? "live.m3u8" : "main.m3u8";

View File

@ -513,6 +513,8 @@ namespace MediaBrowser.Api.Playback
var profiles = info.GetSubtitleProfiles(false, "-", accessToken);
mediaSource.DefaultSubtitleStreamIndex = info.SubtitleStreamIndex;
mediaSource.TranscodeReasons = info.TranscodeReasons;
foreach (var profile in profiles)
{
foreach (var stream in mediaSource.MediaStreams)

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Api.Playback.Hls;
using MediaBrowser.Api.Playback.Progressive;
@ -265,7 +266,8 @@ namespace MediaBrowser.Api.Playback
Static = isStatic,
SegmentContainer = request.TranscodingContainer,
AudioSampleRate = request.MaxAudioSampleRate,
BreakOnNonKeyFrames = transcodingProfile.BreakOnNonKeyFrames
BreakOnNonKeyFrames = transcodingProfile.BreakOnNonKeyFrames,
TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray())
};
if (isHeadRequest)
@ -307,7 +309,8 @@ namespace MediaBrowser.Api.Playback
PlaySessionId = playbackInfoResult.PlaySessionId,
StartTimeTicks = request.StartTimeTicks,
Static = isStatic,
AudioSampleRate = request.MaxAudioSampleRate
AudioSampleRate = request.MaxAudioSampleRate,
TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(",", mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray())
};
if (isHeadRequest)

View File

@ -33,6 +33,8 @@ namespace MediaBrowser.Controller.Drawing
/// <returns>ImageSize.</returns>
ImageSize GetImageSize(ItemImageInfo info);
ImageSize GetImageSize(ItemImageInfo info, bool allowSlowMethods);
/// <summary>
/// Gets the size of the image.
/// </summary>

View File

@ -487,7 +487,7 @@ namespace MediaBrowser.Controller.Entities
var folder = this;
innerProgress.RegisterAction(p =>
{
double newPct = .70 * p + 10;
double newPct = .80 * p + 10;
progress.Report(newPct);
ProviderManager.OnRefreshProgress(folder, newPct);
});
@ -498,11 +498,11 @@ namespace MediaBrowser.Controller.Entities
if (refreshChildMetadata)
{
progress.Report(80);
progress.Report(90);
if (recursive)
{
ProviderManager.OnRefreshProgress(this, 80);
ProviderManager.OnRefreshProgress(this, 90);
}
var container = this as IMetadataContainer;
@ -512,7 +512,7 @@ namespace MediaBrowser.Controller.Entities
var folder = this;
innerProgress.RegisterAction(p =>
{
double newPct = .20 * p + 80;
double newPct = .10 * p + 90;
progress.Report(newPct);
if (recursive)
{

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
@ -9,6 +10,7 @@ using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Controller.MediaEncoding
{
@ -40,6 +42,24 @@ namespace MediaBrowser.Controller.MediaEncoding
public bool ReadInputAtNativeFramerate { get; set; }
private List<TranscodeReason> _transcodeReasons = null;
public List<TranscodeReason> TranscodeReasons
{
get
{
if (_transcodeReasons == null)
{
_transcodeReasons = (BaseRequest.TranscodeReasons ?? string.Empty)
.Split(',')
.Where(i => !string.IsNullOrWhiteSpace(i))
.Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true))
.ToList();
}
return _transcodeReasons;
}
}
public bool IgnoreInputDts
{
get
@ -251,7 +271,7 @@ namespace MediaBrowser.Controller.MediaEncoding
{
return AudioStream.SampleRate;
}
}
}
else if (BaseRequest.AudioSampleRate.HasValue)
{

View File

@ -204,6 +204,8 @@ namespace MediaBrowser.Controller.MediaEncoding
public string SubtitleCodec { get; set; }
public string TranscodeReasons { get; set; }
/// <summary>
/// Gets or sets the index of the audio stream.
/// </summary>

View File

@ -55,7 +55,6 @@ namespace MediaBrowser.Model.Configuration
HidePlayedInLatest = true;
PlayDefaultAudioTrack = true;
DisplayMissingEpisodes = true;
LatestItemsExcludes = new string[] { };
OrderedViews = new string[] { };

View File

@ -1,5 +1,4 @@
using System.Xml.Serialization;
using MediaBrowser.Model.Dlna;
namespace MediaBrowser.Model.Dlna
{

View File

@ -105,8 +105,99 @@ namespace MediaBrowser.Model.Dlna
return null;
}
private TranscodeReason? GetTranscodeReasonForFailedCondition(ProfileCondition condition)
{
switch (condition.Property)
{
case ProfileConditionValue.AudioBitrate:
if (condition.Condition == ProfileConditionType.LessThanEqual)
{
return TranscodeReason.AudioBitrateNotSupported;
}
return TranscodeReason.AudioBitrateNotSupported;
case ProfileConditionValue.AudioChannels:
if (condition.Condition == ProfileConditionType.LessThanEqual)
{
return TranscodeReason.AudioChannelsNotSupported;
}
return TranscodeReason.AudioChannelsNotSupported;
case ProfileConditionValue.AudioProfile:
return TranscodeReason.AudioProfileNotSupported;
case ProfileConditionValue.AudioSampleRate:
return TranscodeReason.AudioSampleRateNotSupported;
case ProfileConditionValue.Has64BitOffsets:
// TODO
return null;
case ProfileConditionValue.Height:
return TranscodeReason.VideoResolutionNotSupported;
case ProfileConditionValue.IsAnamorphic:
return TranscodeReason.AnamorphicVideoNotSupported;
case ProfileConditionValue.IsAvc:
// TODO
return null;
case ProfileConditionValue.IsInterlaced:
return TranscodeReason.InterlacedVideoNotSupported;
case ProfileConditionValue.IsSecondaryAudio:
return TranscodeReason.SecondaryAudioNotSupported;
case ProfileConditionValue.NumAudioStreams:
// TODO
return null;
case ProfileConditionValue.NumVideoStreams:
// TODO
return null;
case ProfileConditionValue.PacketLength:
// TODO
return null;
case ProfileConditionValue.RefFrames:
return TranscodeReason.RefFramesNotSupported;
case ProfileConditionValue.VideoBitDepth:
return TranscodeReason.VideoBitDepthNotSupported;
case ProfileConditionValue.VideoBitrate:
return TranscodeReason.VideoBitrateNotSupported;
case ProfileConditionValue.VideoCodecTag:
return TranscodeReason.VideoCodecNotSupported;
case ProfileConditionValue.VideoFramerate:
return TranscodeReason.VideoFramerateNotSupported;
case ProfileConditionValue.VideoLevel:
return TranscodeReason.VideoLevelNotSupported;
case ProfileConditionValue.VideoProfile:
return TranscodeReason.VideoProfileNotSupported;
case ProfileConditionValue.VideoTimestamp:
// TODO
return null;
case ProfileConditionValue.Width:
return TranscodeReason.VideoResolutionNotSupported;
default:
return null;
}
}
private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options)
{
List<TranscodeReason> transcodeReasons = new List<TranscodeReason>();
StreamInfo playlistItem = new StreamInfo
{
ItemId = options.ItemId,
@ -133,7 +224,10 @@ namespace MediaBrowser.Model.Dlna
MediaStream audioStream = item.GetDefaultAudioStream(null);
List<PlayMethod> directPlayMethods = GetAudioDirectPlayMethods(item, audioStream, options);
var directPlayInfo = GetAudioDirectPlayMethods(item, audioStream, options);
List<PlayMethod> directPlayMethods = directPlayInfo.Item1;
transcodeReasons.AddRange(directPlayInfo.Item2);
ConditionProcessor conditionProcessor = new ConditionProcessor();
@ -180,6 +274,11 @@ namespace MediaBrowser.Model.Dlna
if (!conditionProcessor.IsAudioConditionSatisfied(c, inputAudioChannels, inputAudioBitrate, inputAudioSampleRate))
{
LogConditionFailure(options.Profile, "AudioCodecProfile", c, item);
var transcodeReason = GetTranscodeReasonForFailedCondition(c);
if (transcodeReason.HasValue)
{
transcodeReasons.Add(transcodeReason.Value);
}
all = false;
break;
}
@ -292,9 +391,9 @@ namespace MediaBrowser.Model.Dlna
var longBitrate = Math.Min(transcodingBitrate, playlistItem.AudioBitrate ?? transcodingBitrate);
playlistItem.AudioBitrate = longBitrate > int.MaxValue ? int.MaxValue : Convert.ToInt32(longBitrate);
}
playlistItem.TranscodeReasons = transcodeReasons;
return playlistItem;
}
@ -308,8 +407,10 @@ namespace MediaBrowser.Model.Dlna
return options.GetMaxBitrate(isAudio);
}
private List<PlayMethod> GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options)
private Tuple<List<PlayMethod>, List<TranscodeReason>> GetAudioDirectPlayMethods(MediaSourceInfo item, MediaStream audioStream, AudioOptions options)
{
List<TranscodeReason> transcodeReasons = new List<TranscodeReason>();
DirectPlayProfile directPlayProfile = null;
foreach (DirectPlayProfile i in options.Profile.DirectPlayProfiles)
{
@ -325,27 +426,134 @@ namespace MediaBrowser.Model.Dlna
if (directPlayProfile != null)
{
// While options takes the network and other factors into account. Only applies to direct stream
if (item.SupportsDirectStream && IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true), PlayMethod.DirectStream) && options.EnableDirectStream)
if (item.SupportsDirectStream)
{
playMethods.Add(PlayMethod.DirectStream);
if (IsAudioEligibleForDirectPlay(item, options.GetMaxBitrate(true), PlayMethod.DirectStream))
{
if (options.EnableDirectStream)
{
playMethods.Add(PlayMethod.DirectStream);
}
}
else
{
transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit);
}
}
// The profile describes what the device supports
// If device requirements are satisfied then allow both direct stream and direct play
if (item.SupportsDirectPlay &&
IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), PlayMethod.DirectPlay) && options.EnableDirectPlay)
if (item.SupportsDirectPlay)
{
playMethods.Add(PlayMethod.DirectPlay);
if (IsAudioEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options, true), PlayMethod.DirectPlay))
{
if (options.EnableDirectPlay)
{
playMethods.Add(PlayMethod.DirectPlay);
}
}
else
{
transcodeReasons.Add(TranscodeReason.ContainerBitrateExceedsLimit);
}
}
}
else
{
transcodeReasons.InsertRange(0, GetTranscodeReasonsFromDirectPlayProfile(item, null, audioStream, options.Profile.DirectPlayProfiles));
_logger.Info("Profile: {0}, No direct play profiles found for Path: {1}",
options.Profile.Name ?? "Unknown Profile",
item.Path ?? "Unknown path");
}
return playMethods;
if (playMethods.Count > 0)
{
transcodeReasons.Clear();
}
else
{
transcodeReasons = transcodeReasons.Distinct().ToList();
}
return new Tuple<List<PlayMethod>, List<TranscodeReason>>(playMethods, transcodeReasons);
}
private List<TranscodeReason> GetTranscodeReasonsFromDirectPlayProfile(MediaSourceInfo item, MediaStream videoStream, MediaStream audioStream, IEnumerable<DirectPlayProfile> directPlayProfiles)
{
var list = new List<TranscodeReason>();
var containerSupported = false;
var audioSupported = false;
var videoSupported = false;
foreach (var profile in directPlayProfiles)
{
if (profile.Container.Length > 0)
{
// Check container type
string mediaContainer = item.Container ?? string.Empty;
foreach (string i in profile.GetContainers())
{
if (StringHelper.EqualsIgnoreCase(i, mediaContainer))
{
containerSupported = true;
if (videoStream != null)
{
// Check video codec
List<string> videoCodecs = profile.GetVideoCodecs();
if (videoCodecs.Count > 0)
{
string videoCodec = videoStream.Codec;
if (!string.IsNullOrEmpty(videoCodec) && ListHelper.ContainsIgnoreCase(videoCodecs, videoCodec))
{
videoSupported = true;
}
}
else
{
videoSupported = true;
}
}
if (audioStream != null)
{
// Check audio codec
List<string> audioCodecs = profile.GetAudioCodecs();
if (audioCodecs.Count > 0)
{
string audioCodec = audioStream.Codec;
if (!string.IsNullOrEmpty(audioCodec) && ListHelper.ContainsIgnoreCase(audioCodecs, audioCodec))
{
audioSupported = true;
}
}
else
{
audioSupported = true;
}
}
}
}
}
}
if (!containerSupported)
{
list.Add(TranscodeReason.ContainerNotSupported);
}
if (videoStream != null && !videoSupported)
{
list.Add(TranscodeReason.VideoCodecNotSupported);
}
if (audioStream != null && !audioSupported)
{
list.Add(TranscodeReason.VideoCodecNotSupported);
}
return list;
}
private int? GetDefaultSubtitleStreamIndex(MediaSourceInfo item, SubtitleProfile[] subtitleProfiles)
@ -393,6 +601,8 @@ namespace MediaBrowser.Model.Dlna
private StreamInfo BuildVideoItem(MediaSourceInfo item, VideoOptions options)
{
List<TranscodeReason> transcodeReasons = new List<TranscodeReason>();
StreamInfo playlistItem = new StreamInfo
{
ItemId = options.ItemId,
@ -428,7 +638,8 @@ namespace MediaBrowser.Model.Dlna
if (isEligibleForDirectPlay || isEligibleForDirectStream)
{
// See if it can be direct played
PlayMethod? directPlay = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
var directPlayInfo = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
var directPlay = directPlayInfo.Item1;
if (directPlay != null)
{
@ -445,6 +656,8 @@ namespace MediaBrowser.Model.Dlna
return playlistItem;
}
transcodeReasons.AddRange(directPlayInfo.Item2);
}
// Can't direct play, find the transcoding profile
@ -618,6 +831,8 @@ namespace MediaBrowser.Model.Dlna
}
}
playlistItem.TranscodeReasons = transcodeReasons;
return playlistItem;
}
@ -677,7 +892,7 @@ namespace MediaBrowser.Model.Dlna
return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
}
private PlayMethod? GetVideoDirectPlayProfile(VideoOptions options,
private Tuple<PlayMethod?, List<TranscodeReason>> GetVideoDirectPlayProfile(VideoOptions options,
MediaSourceInfo mediaSource,
MediaStream videoStream,
MediaStream audioStream,
@ -688,11 +903,11 @@ namespace MediaBrowser.Model.Dlna
if (options.ForceDirectPlay)
{
return PlayMethod.DirectPlay;
return new Tuple<PlayMethod?, List<TranscodeReason>>(PlayMethod.DirectPlay, new List<TranscodeReason>());
}
if (options.ForceDirectStream)
{
return PlayMethod.DirectStream;
return new Tuple<PlayMethod?, List<TranscodeReason>>(PlayMethod.DirectStream, new List<TranscodeReason>());
}
if (videoStream == null)
@ -701,7 +916,7 @@ namespace MediaBrowser.Model.Dlna
profile.Name ?? "Unknown Profile",
mediaSource.Path ?? "Unknown path");
return null;
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.UnknownVideoStreamInfo });
}
// See if it can be direct played
@ -721,7 +936,7 @@ namespace MediaBrowser.Model.Dlna
profile.Name ?? "Unknown Profile",
mediaSource.Path ?? "Unknown path");
return null;
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, GetTranscodeReasonsFromDirectPlayProfile(mediaSource, videoStream, audioStream, profile.DirectPlayProfiles));
}
string container = mediaSource.Container;
@ -784,7 +999,7 @@ namespace MediaBrowser.Model.Dlna
profile.Name ?? "Unknown Profile",
mediaSource.Path ?? "Unknown path");
return null;
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.UnknownVideoStreamInfo });
}
conditions = new List<ProfileCondition>();
@ -819,7 +1034,12 @@ namespace MediaBrowser.Model.Dlna
{
LogConditionFailure(profile, "VideoCodecProfile", i, mediaSource);
return null;
var transcodeReason = GetTranscodeReasonForFailedCondition(i);
var transcodeReasons = transcodeReason.HasValue
? new List<TranscodeReason> { transcodeReason.Value }
: new List<TranscodeReason> { };
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, transcodeReasons);
}
}
@ -833,7 +1053,7 @@ namespace MediaBrowser.Model.Dlna
profile.Name ?? "Unknown Profile",
mediaSource.Path ?? "Unknown path");
return null;
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.UnknownAudioStreamInfo });
}
conditions = new List<ProfileCondition>();
@ -870,17 +1090,22 @@ namespace MediaBrowser.Model.Dlna
{
LogConditionFailure(profile, "VideoAudioCodecProfile", i, mediaSource);
return null;
var transcodeReason = GetTranscodeReasonForFailedCondition(i);
var transcodeReasons = transcodeReason.HasValue
? new List<TranscodeReason> { transcodeReason.Value }
: new List<TranscodeReason> { };
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, transcodeReasons);
}
}
}
if (isEligibleForDirectStream && mediaSource.SupportsDirectStream)
{
return PlayMethod.DirectStream;
return new Tuple<PlayMethod?, List<TranscodeReason>>(PlayMethod.DirectStream, new List<TranscodeReason>());
}
return null;
return new Tuple<PlayMethod?, List<TranscodeReason>>(null, new List<TranscodeReason> { TranscodeReason.ContainerBitrateExceedsLimit });
}
private void LogConditionFailure(DeviceProfile profile, string type, ProfileCondition condition, MediaSourceInfo mediaSource)
@ -1047,12 +1272,12 @@ namespace MediaBrowser.Model.Dlna
// Don't restrict by bitrate if coming from an external domain
if (item.IsRemote)
{
return true;
return true;
}
if (!maxBitrate.HasValue)
{
_logger.Info("Cannot "+ playMethod + " due to unknown supported bitrate");
_logger.Info("Cannot " + playMethod + " due to unknown supported bitrate");
return false;
}

View File

@ -21,6 +21,7 @@ namespace MediaBrowser.Model.Dlna
AudioCodecs = new string[] { };
VideoCodecs = new string[] { };
SubtitleCodecs = new string[] { };
TranscodeReasons = new List<TranscodeReason>();
}
public string ItemId { get; set; }
@ -89,6 +90,7 @@ namespace MediaBrowser.Model.Dlna
public string PlaySessionId { get; set; }
public List<MediaSourceInfo> AllMediaSources { get; set; }
public List<TranscodeReason> TranscodeReasons { get; set; }
public string MediaSourceId
{
@ -231,22 +233,11 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("MaxWidth", item.MaxWidth.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxWidth.Value) : string.Empty));
list.Add(new NameValuePair("MaxHeight", item.MaxHeight.HasValue ? StringHelper.ToStringCultureInvariant(item.MaxHeight.Value) : string.Empty));
var forceStartPosition = false;
long startPositionTicks = item.StartPositionTicks;
//if (item.MediaSource.DateLiveStreamOpened.HasValue && startPositionTicks == 0)
//{
// var elapsed = DateTime.UtcNow - item.MediaSource.DateLiveStreamOpened.Value;
// elapsed -= TimeSpan.FromSeconds(20);
// if (elapsed.TotalSeconds >= 0)
// {
// startPositionTicks = elapsed.Ticks + startPositionTicks;
// forceStartPosition = true;
// }
//}
var isHls = StringHelper.EqualsIgnoreCase(item.SubProtocol, "hls");
if (isHls && !forceStartPosition)
if (isHls)
{
list.Add(new NameValuePair("StartTimeTicks", string.Empty));
}
@ -310,6 +301,11 @@ namespace MediaBrowser.Model.Dlna
list.Add(new NameValuePair("BreakOnNonKeyFrames", item.BreakOnNonKeyFrames.ToString()));
}
if (isDlna || !item.IsDirectStream)
{
list.Add(new NameValuePair("TranscodeReasons", string.Join(",", item.TranscodeReasons.Distinct().Select(i => i.ToString()).ToArray())));
}
return list;
}

View File

@ -4,6 +4,7 @@ using MediaBrowser.Model.MediaInfo;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Model.Session;
namespace MediaBrowser.Model.Dto
{
@ -110,6 +111,9 @@ namespace MediaBrowser.Model.Dto
}
}
[IgnoreDataMember]
public List<TranscodeReason> TranscodeReasons { get; set; }
public int? DefaultAudioStreamIndex { get; set; }
public int? DefaultSubtitleStreamIndex { get; set; }

View File

@ -122,16 +122,6 @@ namespace MediaBrowser.Model.Dto
/// <value>The primary image aspect ratio.</value>
public double? PrimaryImageAspectRatio { get; set; }
/// <summary>
/// Gets a value indicating whether this instance has primary image.
/// </summary>
/// <value><c>true</c> if this instance has primary image; otherwise, <c>false</c>.</value>
[IgnoreDataMember]
public bool HasPrimaryImage
{
get { return PrimaryImageTag != null; }
}
/// <summary>
/// Initializes a new instance of the <see cref="UserDto"/> class.
/// </summary>

View File

@ -47,6 +47,7 @@ namespace MediaBrowser.Model.LiveTv
public bool ImportFavoritesOnly { get; set; }
public bool AllowHWTranscoding { get; set; }
public bool EnableTvgId { get; set; }
public bool EnableStreamLooping { get; set; }
public TunerHostInfo()
{
@ -74,6 +75,7 @@ namespace MediaBrowser.Model.LiveTv
public NameValuePair[] ChannelMappings { get; set; }
public string MoviePrefix { get; set; }
public bool EnableNewProgramIds { get; set; }
public string PreferredLanguage { get; set; }
public ListingsProviderInfo()
{

View File

@ -72,6 +72,7 @@ namespace MediaBrowser.Model.Net
dict.Add(".tbn", "image/jpeg");
dict.Add(".png", "image/png");
dict.Add(".gif", "image/gif");
dict.Add(".tiff", "image/tiff");
dict.Add(".webp", "image/webp");
dict.Add(".ico", "image/vnd.microsoft.icon");
dict.Add(".mpg", "video/mpeg");

View File

@ -1,3 +1,5 @@
using System.Collections.Generic;
namespace MediaBrowser.Model.Session
{
public class TranscodingInfo
@ -15,5 +17,36 @@ namespace MediaBrowser.Model.Session
public int? Width { get; set; }
public int? Height { get; set; }
public int? AudioChannels { get; set; }
public List<TranscodeReason> TranscodeReasons { get; set; }
public TranscodingInfo()
{
TranscodeReasons = new List<TranscodeReason>();
}
}
public enum TranscodeReason
{
ContainerNotSupported = 0,
VideoCodecNotSupported = 1,
AudioCodecNotSupported = 2,
ContainerBitrateExceedsLimit = 3,
AudioBitrateNotSupported = 4,
AudioChannelsNotSupported = 5,
VideoResolutionNotSupported = 6,
UnknownVideoStreamInfo = 7,
UnknownAudioStreamInfo = 8,
AudioProfileNotSupported = 9,
AudioSampleRateNotSupported = 10,
AnamorphicVideoNotSupported = 11,
InterlacedVideoNotSupported = 12,
SecondaryAudioNotSupported = 13,
RefFramesNotSupported = 14,
VideoBitDepthNotSupported = 15,
VideoBitrateNotSupported = 16,
VideoFramerateNotSupported = 17,
VideoLevelNotSupported = 18,
VideoProfileNotSupported = 19
}
}

View File

@ -31,7 +31,7 @@ namespace MediaBrowser.Server.Startup.Common
}
catch (Exception ex)
{
logger.Info("Error loading Skia: {0}. Will revert to ImageMagick.", ex.Message);
logger.Error("Skia not available. Will try next image processor. {0}", ex.Message);
}
try
@ -40,7 +40,7 @@ namespace MediaBrowser.Server.Startup.Common
}
catch
{
logger.Error("Error loading ImageMagick. Will revert to GDI.");
logger.Error("ImageMagick not available. Will try next image processor.");
}
}

View File

@ -14,10 +14,10 @@ namespace MediaBrowser.Server.Startup.Common
{
public class ImageEncoderHelper
{
public static IImageEncoder GetImageEncoder(ILogger logger,
ILogManager logManager,
IFileSystem fileSystem,
StartupOptions startupOptions,
public static IImageEncoder GetImageEncoder(ILogger logger,
ILogManager logManager,
IFileSystem fileSystem,
StartupOptions startupOptions,
Func<IHttpClient> httpClient,
IApplicationPaths appPaths)
{
@ -27,7 +27,7 @@ namespace MediaBrowser.Server.Startup.Common
}
catch
{
logger.Error("Error loading Skia. Will revert to ImageMagick.");
logger.Error("Skia not available. Will try next image processor.");
}
return new NullImageEncoder();

View File

@ -1,136 +0,0 @@
namespace MediaBrowser.ServerApplication
{
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.cmdBrowse = new System.Windows.Forms.ToolStripMenuItem();
this.cmdConfigure = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.cmdRestart = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.cmdCommunity = new System.Windows.Forms.ToolStripMenuItem();
this.cmdExit = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuStrip1.SuspendLayout();
this.SuspendLayout();
//
// notifyIcon1
//
this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));
this.notifyIcon1.Text = "Emby";
this.notifyIcon1.Visible = true;
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.cmdBrowse,
this.cmdConfigure,
this.toolStripSeparator2,
this.cmdRestart,
this.toolStripSeparator1,
this.cmdCommunity,
this.cmdExit});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.ShowCheckMargin = true;
this.contextMenuStrip1.ShowImageMargin = false;
this.contextMenuStrip1.Size = new System.Drawing.Size(209, 192);
//
// cmdBrowse
//
this.cmdBrowse.Name = "cmdBrowse";
this.cmdBrowse.Size = new System.Drawing.Size(208, 22);
this.cmdBrowse.Text = "Browse Library";
//
// cmdConfigure
//
this.cmdConfigure.Name = "cmdConfigure";
this.cmdConfigure.Size = new System.Drawing.Size(208, 22);
this.cmdConfigure.Text = "Configure Media Browser";
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(205, 6);
//
// cmdRestart
//
this.cmdRestart.Name = "cmdRestart";
this.cmdRestart.Size = new System.Drawing.Size(208, 22);
this.cmdRestart.Text = "Restart Server";
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(205, 6);
//
// cmdCommunity
//
this.cmdCommunity.Name = "cmdCommunity";
this.cmdCommunity.Size = new System.Drawing.Size(208, 22);
this.cmdCommunity.Text = "Visit Community";
//
// cmdExit
//
this.cmdExit.Name = "cmdExit";
this.cmdExit.Size = new System.Drawing.Size(208, 22);
this.cmdExit.Text = "Exit";
//
// MainForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "MainForm";
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "MainForm";
this.contextMenuStrip1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.NotifyIcon notifyIcon1;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem cmdExit;
private System.Windows.Forms.ToolStripMenuItem cmdBrowse;
private System.Windows.Forms.ToolStripMenuItem cmdConfigure;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem cmdRestart;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripMenuItem cmdCommunity;
}
}

View File

@ -1,12 +0,0 @@
using System.Windows.Forms;
namespace MediaBrowser.ServerApplication
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
}
}

View File

@ -1,576 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="notifyIcon1.TrayLocation" type="System.Drawing.Point, System.Drawing">
<value>17, 17</value>
</data>
<data name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing">
<value>130, 17</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAgAMDAAAAEAIACoJQAAhgAAADAwAAABAAgAqA4AAC4mAAAgIAAAAQAgAKgQAADWNAAAICAAAAEA
CACoCAAAfkUAABgYAAABACAAiAkAACZOAAAYGAAAAQAIAMgGAACuVwAAEBAAAAEAIABoBAAAdl4AABAQ
AAABAAgAaAUAAN5iAAAoAAAAMAAAAGAAAAABACAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu2UkpItlMxAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7RQM0u1Uv9LtVL/S7NSJQAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABKtFIfS7VS/0u1
Uv9LtVL/S7VS/0i2SAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEuz
Uz1LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9ItkgHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAS7NRTku1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7NSJQAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABLs1FOS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0i2
UzEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEuzUz1LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv/OtgAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASrRSH0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/xsYACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtFAzS7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqqAAMAAAAAAAAAAEu2UkpLtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv/atgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv/MuwAPTLVSUEu1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/0rwAFwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/9K8ABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/atgAOAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/8Dkwf9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////bsBk/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS//////////////////////9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////
/////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////
///////////////////////////////////d6sP/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/////////////////////////////////////////////////0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////////////////////////////
////////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////////////
//////////////////////////////////9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////
////////////////////////////////////////////////////////0uOr/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAA/wABS7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////
////////////////////////////////////////////////////////////////////////V7lZ/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/////////////////////////////////////////////////////////////////7Dd
rP9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////////////////////////////
////////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9ItlMxAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////////////
/////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0uzUiUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////
//////////////////9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/SLZIBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAD/AAFLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////
////////////////////////+fff/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9ItkgHAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS//////////////////////9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/9S4ABIAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/1L8AGAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/1q6Xf9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv/OtgAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/8bGAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/atgAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/9K8ABcAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtFHOAAAAAEu1Uv9LtVL/0rwAFwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0q0UdQAAAAAAAAAAAAAAADatgAOAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/SrVS7AAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0q0
UuIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/SrVS0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9KtVLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0q0UuIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9KtVLsAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEq0UdQAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////AAD///+f//8AAP///w///wAA///+B///
AAD///wD//8AAP//+AH//wAA///wAP//AAD//+AAf/8AAP//wAA//wAA//+AAB//AAD/8wAAD/8AAP/g
AAAH/wAA/8AAAAP/AAD/gAAAA/8AAP8AAAAH/wAA/gAAAAP/AAD8AAAAAf8AAPgAAAAA/wAA8AAAAAB/
AADgAAAAAD8AAMAAAAAAHwAAgAAAAAAPAACAAAAAAAcAAMAAAAAAAwAA4AAAAAABAADwAAAAAAAAAPgA
AAAAAQAA/AAAAAADAAD+AAAAAAcAAP8AAAAADwAA/4AAAAAfAAD/wAAAAD8AAP/gAAAAfwAA/+AAAAD/
AAD/wAAAAf8AAP/AAAAD/wAA/+AAAAf/AAD/8AAAT/8AAP/4AAD//wAA//wAAf//AAD//gAD//8AAP//
AAf//wAA//+AD///AAD//8Af//8AAP//4D///wAA///wf///AAD///j///8AAP///f///wAAKAAAADAA
AABgAAAAAQAIAAAAAAAAEgAAAAAAAAAAAAAAAAAAAAAAAAAAAP9vtzz/cLc8/1+2Rv9RtU//S7VS/0y1
Uf9NtVH/TrVQ/0+1UP9NtlP/TbZU/062VP9Rt1f/VLla/1W5W/9WuVz/Y7ZD/2C2Rf9htkX/YrZE/2O2
RP9otkD/Yb5m/2S/aP9mv2j/aMBq/3jHef95x3z/e8h8/3zIfP9+yX//f8qD/4PMiP+R0ZL/ktGS/5TS
lP+V0pX/mdSY/6jaqP+s3Kv/r92t/7Ddrv/G5sL/xufF/8jnxv/L6cj/3fDb/9/x3f/g8d3/4/Pg/+/4
7f/x+e//8vnv//r8+P/7/fn//v/+/////v8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAABQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQUFAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUFBQUFBQAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFBQUFBQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAUFBQUFBQUFBQUFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUF
BQUFBQUFBQUFBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQUFBQUFBQUFBQUFBQMA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFBQUFBQUFBQUFBQUFBQYDAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAUFBQUFBQUFBQUFBQUFBQUGAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAUEgAABQUFBQUFBQUFBQUFBQUFBQUFBgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUHBhIFBQUFBQUF
BQUFBQUFBQUFBQUFBQYDAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQcFBQYFBQUFBQUFBQUFBQUFBQUFBQUF
BQUGAwAAAAAAAAAAAAAAAAAAAAAAAAAVBwUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBhIAAAAAAAAA
AAAAAAAAAAAAABUHBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCBUAAAAAAAAAAAAAAAAAAAAAFQcF
BQUFBQUFBQUGBQUFBQUFBQUFBQUFBQUFBQUFEwAAAAAAAAAAAAAAAAAAAAAVBwUFBQUFBQUFBQUgKg8F
BQUFBQUFBQUFBQUFBQUFBQUAAAAAAAAAAAAAAAAAABUHBQUFBQUFBQUFBQUhOTUkDAUFBQUFBQUFBQUF
BQUFBQUFAAAAAAAAAAAAAAAAFQcFBQUFBQUFBQUFBQUhOTk5MR4FBQUFBQUFBQUFBQUFBQUFBQAAAAAA
AAAAAAASBwUFBQUFBQUFBQUFBQUhOTk5OTgsGAUFBQUFBQUFBQUFBQUFBQUAAAAAAAAAAAUFBQUFBQUF
BQUFBQUFBQUhOTk5OTk5NygOBQUFBQUFBQUFBQUFBQUFAAAAAAAABQUFBQUFBQUFBQUFBQUFBQUhOTk5
OTk5OTkzIwsFBQUFBQUFBQUFBQUFBQAAAAAFBQUFBQUFBQUFBQUFBQUFBQUhOTk5OTk5OTk5OS8bBQUF
BQUFBQUFBQUFBQUAAAAFBQUFBQUFBQUFBQUFBQUFBQUhOTk5OTk5OTk5OTk4KxcFBQUFBQUFBQUFBQUF
AAAABQUFBQUFBQUFBQUFBQUFBQUhOTk5OTk5OTk5OTk5OTYnDQUFBQUFBQUFBQUFBQAAAAUFBQUFBQUF
BQUFBQUFBQUhOTk5OTk5OTk5OTk5OTMiCwUFBQUFBQUFBQUFBQUAAAAFBQUFBQUFBQUFBQUFBQUhOTk5
OTk5OTk5OTk2KQ4FBQUFBQUFBQUFBQUFBQUAAAAABQUFBQUFBQUFBQUFBQUhOTk5OTk5OTk5OS0ZBQUF
BQUFBQUFBQUFBQUFBQUAAAAAAAUFBQUFBQUFBQUFBQUhOTk5OTk5OTkwHQUFBQUFBQUFBQUFBQUFBQUF
BQAAAAAAAAAFBQUFBQUFBQUFBQUhOTk5OTk5NCUKBQUFBQUFBQUFBQUFBQUFBQUFAAAAAAAAAAAABQUF
BQUFBQUFBQUhOTk5OTcpEAUFBQUFBQUFBQUFBQUFBQUFBQUAAAAAAAAAAAAAAAUFBQUFBQUFBQUhOTk5
LhoFBQUFBQUFBQUFBQUFBQUFBQUGAwAAAAAAAAAAAAAAAAAFBQUFBQUFBQUhOTIfBQUFBQUFBQUFBQUF
BQUFBQUFBQYDAAAAAAAAAAAAAAAAAAAABQUFBQUFBQUcJgsFBQUFBQUFBQUFBQUFBQUFBQUFBgMAAAAA
AAAAAAAAAAAAAAAAFgcFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUGAwAAAAAAAAAAAAAAAAAAAAAW
CQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQYDAAAAAAAAAAAAAAAAAAAAAAARBwUFBQUFBQUFBQUF
BQUFBQUFBQUFBQUFBQUFBgMAAAAAAAAAAAAAAAAAAAAAAAAAFQcFBQUFBQUFBQUFBQUFBQUFBQUFBQUH
BQUGAwAAAAAAAAAAAAAAAAAAAAAAAAAAABUHBQUFBQUFBQUFBQUFBQUFBQUFBQUBBAYDAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAUBwUFBQUFBQUFBQUFBQUFBQUFBQUAAhQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAFAcFBQUFBQUFBQUFBQUFBQUFBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQHBQUFBQUF
BQUFBQUFBQUFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVBwUFBQUFBQUFBQUFBQUAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQcFBQUFBQUFBQUFBQAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAABQHBQUFBQUFBQUFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAVBwUFBQUFBQUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFQcF
BQUFBQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUHBQUFAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVBwUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAD///////8AAP///5///wAA////D///AAD///4H//8AAP///AP//wAA///4Af//AAD///AA//8AAP//
4AB//wAA///AAD//AAD//4AAH/8AAP/zAAAP/wAA/+AAAAf/AAD/wAAAA/8AAP+AAAAD/wAA/wAAAAf/
AAD+AAAAA/8AAPwAAAAB/wAA+AAAAAD/AADwAAAAAH8AAOAAAAAAPwAAwAAAAAAfAACAAAAAAA8AAIAA
AAAABwAAwAAAAAADAADgAAAAAAEAAPAAAAAAAAAA+AAAAAABAAD8AAAAAAMAAP4AAAAABwAA/wAAAAAP
AAD/gAAAAB8AAP/AAAAAPwAA/+AAAAB/AAD/4AAAAP8AAP/AAAAB/wAA/8AAAAP/AAD/4AAAB/8AAP/w
AABP/wAA//gAAP//AAD//AAB//8AAP/+AAP//wAA//8AB///AAD//4AP//8AAP//wB///wAA///gP///
AAD///B///8AAP//+P///wAA///9////AAAoAAAAIAAAAEAAAAABACAAAAAAAAAgAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABLtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/AAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtFH+S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv/8/fz/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS//z9/P///////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVH/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL//P38//////////////////////9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/8/fz/////////////////////////
///q8dP/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS//z9/P//////////////
////////////////////////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL//P38////
/////////////////////////////////////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv/8/fz/////////////////////////////////////////////////S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS//z9/P//////////////////////////////////////S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL//P38////////////////////////////mspu/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/8/fz//////////////////v7+/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS//z9/P///////////0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL//P38/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAEu1
Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAEu0Uf5LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uf9LtVL/S7VS/0u1
Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//v////x////4P///8B///+AP///AB//9gAP/+AAB//AAAP/gA
AH/wAAB/4AAAP8AAAB+AAAAPAAAAB4AAAAPAAAAB4AAAAPAAAAH4AAAD/AAAB/4AAA/+AAAf/AAAP/4A
AH//AAb//4AP///AH///4D////B////4/////f//KAAAACAAAABAAAAAAQAIAAAAAAAACAAAAAAAAAAA
AAAAAAAAAAAAAAAAAP95tzb/erc2/3u3Nf9wtzz/VrZL/1C1T/9RtU7/UrVO/1O1Tf9VtUz/VbZM/0u1
Uv9NtVH/TrVQ/0+1UP9NtlT/ULdW/1a5W/9gtkb/Y7ZE/2i2QP9bu2D/Zb9p/2vCb/9vw3L/d8d6/33J
fv+NuCr/jrgq/4+4Kf+SuSf/k7kn/5C5Kf+SuSj/hcyG/4fNif+U0pX/l9OY/5bUmf+e15//n9eh/63d
rv+s3bD/uOG5/8jox//Q68//0+zS/97x3f/h8t//5vTl//D47//1+/T/+/36//3+/f//////AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAADAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAADAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAYCAAAAAAAAAAAAAAAAAAAA
AAAAAAAMDAwMDAwMDAwMDAcBAAAAAAAAAAAAAAAAAAAAIAsTDAwMDAwMDAwMDAwMDAcDAAAAAAAAAAAA
AAAAACAJDA4MDAwMDAwMDAwMDAwMDAcDAAAAAAAAAAAAAAAdCQwMDAwMDAwMDAwMDAwMDAwMDAoAAAAA
AAAAAAAAHgkMDAwMDAwMDAwMDAwMDAwMDAwNFAAAAAAAAAAAACAJDAwMDAwMDCkmEAwMDAwMDAwMDAwM
AAAAAAAAAAAhCQwMDAwMDAwMKzcxGwwMDAwMDAwMDAwMAAAAAAAADAcMDAwMDAwMDAwrNzc3LRcMDAwM
DAwMDAwMAAAAAAwMDAwMDAwMDAwMDCs3Nzc3NSoSDAwMDAwMDAwMAAAADAwMDAwMDAwMDAwMKzc3Nzc3
NzMlEAwMDAwMDAwMAAAMDAwMDAwMDAwMDAwrNzc3Nzc3NzcwGgwMDAwMDAwMAAAMDAwMDAwMDAwMDCs3
Nzc3Nzc3Ny4YDAwMDAwMDAwMAAAMDAwMDAwMDAwMKzc3Nzc3NzIjDAwMDAwMDAwMDAwAAAAMDAwMDAwM
DAwrNzc3NzQoEQwMDAwMDAwMDAwMDAAAAAAMDAwMDAwMDCs3NzYsFgwMDAwMDAwMDAwMDAwAAAAAAAAM
DAwMDAwMKzcvGQwMDAwMDAwMDAwMDAcCAAAAAAAAAAAMDAwMDAwnJAwMDAwMDAwMDAwMDAwHAwAAAAAA
AAAAABUPDAwMDAwMDAwMDAwMDAwMDAwMBwIAAAAAAAAAAAAABQwMDAwMDAwMDAwMDAwMDAwMDAcBAAAA
AAAAAAAAAAAfCQwMDAwMDAwMDAwMDAwMDwwHAgAAAAAAAAAAAAAAAAAfCQwMDAwMDAwMDAwMDAwEBQIA
AAAAAAAAAAAAAAAAAAAcCQwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAeCQwMDAwMDAwMDAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAgCQwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeCQwMDAwM
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdCQwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAi
CAwAAAAAAAAAAAAAAAAAAAAA//+/////H////g////wH///4A///8AH//2AA//4AAH/8AAA/+AAAf/AA
AH/gAAA/wAAAH4AAAA8AAAAHgAAAA8AAAAHgAAAA8AAAAfgAAAP8AAAH/gAAD/4AAB/8AAA//gAAf/8A
Bv//gA///8Af///gP///8H////j////9//8oAAAAGAAAADAAAAABACAAAAAAAAASAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASrRSQUm1
Ty0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABJtU8tS7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEuz
UVFLtVL/S7VS/0u1Uv9LtVL/SbVPLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASbVPLUu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/8+/
ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABKtFJBS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv/UqgAGAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/2S1QV5LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/1L8AGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL///////////9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL//////////////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/////////////////////////
///29+b/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL//////////////////////////////////////0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/////////
/////////////////////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL///////////////////////////+l1ZP/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9JtU8tAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
Uv9LtVL//////////////////////0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/wAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL///////////9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/0LkAFgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv/PvwAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/9SqAAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u0
UtJLtVL/1L8AGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/SrVR3gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9KtVLyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u0Uc4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1
Uv9LtVL/SrVS8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABKtVHeAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////AP/z/wD/4f8A/8D/AP+AfwD9AD8A+AAfAPAA
HwDgAA8AwAAHAIAAAwCAAAEAwAAAAOAAAQDwAAMA+AAHAPwADwD4AB8A/AA/AP4A/wD/Af8A/4P/AP/H
/wD/7/8AKAAAABgAAAAwAAAAAQAIAAAAAACABAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9UtUz/VbZM/0u1
Uv9MtVH/TbVR/061UP9PtVD/TLZT/062VP9SuFj/Vrlc/2W2Qv9htkX/Xr1j/2XAav9qwW7/ccR1/3LF
dv99yYD/iM6L/5PSlv+j2aX/r92w/73kvv/B5sP/yejJ/9ju1//h8uD/6vbp//H58P/3/Pb/+/36//7+
/v//////AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAA
AAADAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAAAAAAAA
AAAAAAAAAAAAAAADAwMDAwMDAQAAAAAAAAAAAAAAAAANAAMDAwMDAwMDAwEAAAAAAAAAAAAAAAIEBgMD
AwMDAwMDAwMBAAAAAAAAAAAAAgQDAwMDAwMDAwMDAwMEDQAAAAAAAAACBAMDAwMRCQMDAwMDAwMFAwAA
AAAAAAIEAwMDAwMZHBMDAwMDAwMDAwMAAAAABwQDAwMDAwMZIiIaDwMDAwMDAwMDAAADAwMDAwMDAwMZ
IiIiIBcLAwMDAwMDAwADAwMDAwMDAwMZIiIiIiIeFQgDAwMDAwMAAwMDAwMDAwMZIiIiIiIdFAMDAwMD
AwMAAAMDAwMDAwMZIiIiHxYKAwMDAwMDAwMAAAADAwMDAwMZIiEYDgMDAwMDAwMDAwAAAAAAAwMDAwMZ
GxIDAwMDAwMDAwMBAAAAAAAAAAYDAwMQBAMDAwMDAwMDAwEAAAAAAAAADAUDAwMDAwMDAwMDAwMDAQAA
AAAAAAAAAAIEAwMDAwMDAwMDBQUBAAAAAAAAAAAAAAACBAMDAwMDAwMDAwwAAAAAAAAAAAAAAAAAAgQD
AwMDAwMDAAAAAAAAAAAAAAAAAAAAAAIEAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAACBAMDAwAAAAAAAAAA
AAAAAAAAAAAAAAAAAgQDAAAAAAAAAAAAAAD///8A//P/AP/h/wD/wP8A/4B/AP0APwD4AB8A8AAfAOAA
DwDAAAcAgAADAIAAAQDAAAAA4AABAPAAAwD4AAcA/AAPAPgAHwD8AD8A/gD/AP8B/wD/g/8A/8f/AP/v
/wAoAAAAEAAAACAAAAABACAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABLtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv//////S7VS/0u1Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAA
AAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/////////////////S7VS/0u1Uv9LtVL/S7VS/0u1
Uv8AAAAAAAAAAEu1Uv9LtVL/S7VS/0u1Uv9LtVL/S7VS////////////////////////////S7VS/0u1
Uv9LtVL/S7VS/wAAAAAAAAAAS7VS/0u1Uv9LtVL/S7VS/0u1Uv//////////////////////sN2s/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/////////////////S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS//////9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAABLtVL/S7VS/0u1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEu1Uv9LtVL/S7VS/0u1
Uv9LtVL/S7VS/0u1Uv9LtVL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS7VS/0u1
Uv9LtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AABLtVL/S7VS/0u1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAEu1Uv8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9/AAD+PwAA/B8AAPAP
AADgBwAAwAcAAIADAAAAAQAAgAAAAMABAADgAwAA4AcAAPAPAAD4PwAA/H8AAP7/AAAoAAAAEAAAACAA
AAABAAgAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAA/0+1T/9QtU//VLVM/1W2TP9LtVL/TLVR/021
Uf9PtVD/U7hZ/1a5XP9hvmb/ZsBr/3bGev99yYH/qNuq/6/esf+y37T/uOK6/8Lmw//K6cr/1u7X//n8
+f/7/fv////+/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAFBQUAAAAAAAAAAAAAAAAFBQUF
BQAAAAAAAAAAAAAFBQUFBQYDAAAAAAAAAAQBBQUFBQUFBgMAAAAAAAQGBQUFBQUFBQUIAAAAAAQGBQUF
Eg4FBQUFBQUAAAUGBQUFBRUYFAwFBQUFBQAFBQUFBQUVGBgXEAoFBQUFBQUFBQUFFRgYFg8JBQUFBQAF
BQUFBRUYEwsFBQUFBQUAAAUFBQURDQUFBQUFBgMAAAAAAgUFBQUFBQUFBgMAAAAAAAQGBQUFBQUFAQMA
AAAAAAAABAYFBQUFBQAAAAAAAAAAAAAEBgUFBQAAAAAAAAAAAAAAAAQHBQAAAAAAAAD/fwAA/j8AAPwf
AADwDwAA4AcAAMAHAACAAwAAAAEAAIAAAADAAQAA4AMAAOAHAADwDwAA+D8AAPx/AAD+/wAA
</value>
</data>
</root>

View File

@ -53,31 +53,10 @@ namespace MediaBrowser.ServerApplication
private static IFileSystem FileSystem;
public static bool TryGetLocalFromUncDirectory(string local, out string unc)
{
if ((local == null) || (local == ""))
{
unc = "";
throw new ArgumentNullException("local");
}
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT Name FROM Win32_share WHERE path ='" + local.Replace("\\", "\\\\") + "'");
ManagementObjectCollection coll = searcher.Get();
if (coll.Count == 1)
{
foreach (ManagementObject share in searcher.Get())
{
unc = share["Name"] as String;
unc = "\\\\" + SystemInformation.ComputerName + "\\" + unc;
return true;
}
}
unc = "";
return false;
}
/// <summary>
/// Defines the entry point of the application.
/// </summary>
[STAThread]
public static void Main()
{
var options = new StartupOptions(Environment.GetCommandLineArgs());
@ -321,8 +300,6 @@ namespace MediaBrowser.ServerApplication
}
}
private static readonly TaskCompletionSource<bool> ApplicationTaskCompletionSource = new TaskCompletionSource<bool>();
/// <summary>
/// Runs the application.
/// </summary>
@ -394,9 +371,6 @@ namespace MediaBrowser.ServerApplication
HideSplashScreen();
ShowTrayIcon();
task = ApplicationTaskCompletionSource.Task;
Task.WaitAll(task);
}
}
@ -487,7 +461,6 @@ namespace MediaBrowser.ServerApplication
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
static void service_Disposed(object sender, EventArgs e)
{
ApplicationTaskCompletionSource.SetResult(true);
OnServiceShutdown();
}
@ -706,14 +679,10 @@ namespace MediaBrowser.ServerApplication
_serverNotifyIcon = null;
}
//_logger.Info("Calling Application.Exit");
_logger.Info("Calling Application.Exit");
//Application.Exit();
_logger.Info("Calling Environment.Exit");
Environment.Exit(0);
_logger.Info("Calling ApplicationTaskCompletionSource.SetResult");
ApplicationTaskCompletionSource.SetResult(true);
}
private static void ShutdownWindowsService()

View File

@ -130,12 +130,6 @@
<SubType>Component</SubType>
</Compile>
<Compile Include="ImageEncoderHelper.cs" />
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="MainForm.Designer.cs">
<DependentUpon>MainForm.cs</DependentUpon>
</Compile>
<Compile Include="MainStartup.cs" />
<Compile Include="Native\LoopUtil.cs" />
<Compile Include="Native\PowerManagement.cs" />
@ -167,9 +161,6 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
@ -197,7 +188,7 @@
<Content Include="x64\sqlite3.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Icon.ico" />
<EmbeddedResource Include="Icon.ico" />
<Content Include="Resources\Images\mb3logo800.png" />
<Content Include="x86\libSkiaSharp.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

View File

@ -45,7 +45,6 @@ namespace MediaBrowser.ServerApplication
components = new System.ComponentModel.Container();
var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
contextMenuStrip1 = new ContextMenuStrip(components);
notifyIcon1 = new NotifyIcon(components);
@ -62,7 +61,7 @@ namespace MediaBrowser.ServerApplication
// notifyIcon1
//
notifyIcon1.ContextMenuStrip = contextMenuStrip1;
notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
notifyIcon1.Icon = new System.Drawing.Icon(GetType().Assembly.GetManifestResourceStream(GetType().Namespace + ".Icon.ico"));
notifyIcon1.Text = "Emby";
notifyIcon1.Visible = true;
//

View File

@ -41,26 +41,25 @@ using MediaBrowser.Model.Logging;
namespace Mono.Nat
{
public static class NatUtility
{
private static ManualResetEvent searching;
public static event EventHandler<DeviceEventArgs> DeviceFound;
public static event EventHandler<DeviceEventArgs> DeviceLost;
private static List<ISearcher> controllers;
private static bool verbose;
public static class NatUtility
{
public static event EventHandler<DeviceEventArgs> DeviceFound;
public static event EventHandler<DeviceEventArgs> DeviceLost;
private static List<ISearcher> controllers;
private static bool verbose;
public static List<NatProtocol> EnabledProtocols { get; set; }
public static ILogger Logger { get; set; }
public static ILogger Logger { get; set; }
public static IHttpClient HttpClient { get; set; }
public static bool Verbose
{
get { return verbose; }
set { verbose = value; }
}
{
get { return verbose; }
set { verbose = value; }
}
static NatUtility()
{
EnabledProtocols = new List<NatProtocol>
@ -68,8 +67,6 @@ namespace Mono.Nat
NatProtocol.Pmp
};
searching = new ManualResetEvent(false);
controllers = new List<ISearcher>();
controllers.Add(PmpSearcher.Instance);
@ -86,23 +83,19 @@ namespace Mono.Nat
DeviceLost(sender, args);
};
});
Task.Factory.StartNew(SearchAndListen, TaskCreationOptions.LongRunning);
}
internal static void Log(string format, params object[] args)
{
var logger = Logger;
if (logger != null)
logger.Debug(format, args);
}
private static async Task SearchAndListen()
internal static void Log(string format, params object[] args)
{
while (true)
{
searching.WaitOne();
var logger = Logger;
if (logger != null)
logger.Debug(format, args);
}
private static async Task SearchAndListen(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
try
{
var enabledProtocols = EnabledProtocols.ToList();
@ -123,67 +116,99 @@ namespace Mono.Nat
}
catch (Exception e)
{
}
await Task.Delay(100).ConfigureAwait(false);
}
}
}
static async Task Receive (ISearcher searcher, List<UdpClient> clients)
{
foreach (UdpClient client in clients)
{
if (client.Available > 0)
{
IPAddress localAddress = ((IPEndPoint)client.Client.LocalEndPoint).Address;
var result = await client.ReceiveAsync().ConfigureAwait(false);
var data = result.Buffer;
var received = result.RemoteEndPoint;
searcher.Handle(localAddress, data, received);
}
static async Task Receive(ISearcher searcher, List<UdpClient> clients)
{
foreach (UdpClient client in clients)
{
if (client.Available > 0)
{
IPAddress localAddress = ((IPEndPoint)client.Client.LocalEndPoint).Address;
var result = await client.ReceiveAsync().ConfigureAwait(false);
var data = result.Buffer;
var received = result.RemoteEndPoint;
searcher.Handle(localAddress, data, received);
}
}
}
public static void StartDiscovery ()
{
searching.Set();
}
public static void StopDiscovery ()
{
searching.Reset();
}
//checks if an IP address is a private address space as defined by RFC 1918
public static bool IsPrivateAddressSpace (IPAddress address)
{
byte[] ba = address.GetAddressBytes ();
private static CancellationTokenSource _currentCancellationTokenSource;
private static object _runSyncLock = new object();
public static void StartDiscovery()
{
lock (_runSyncLock)
{
if (_currentCancellationTokenSource == null)
{
return;
}
switch ((int)ba[0]) {
case 10:
return true; //10.x.x.x
case 172:
return ((int)ba[1] & 16) != 0; //172.16-31.x.x
case 192:
return (int)ba[1] == 168; //192.168.x.x
default:
return false;
}
}
var tokenSource = new CancellationTokenSource();
public static void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint, NatProtocol protocol)
{
switch (protocol)
{
_currentCancellationTokenSource = tokenSource;
//Task.Factory.StartNew(() => SearchAndListen(tokenSource.Token), tokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}
}
public static void StopDiscovery()
{
lock (_runSyncLock)
{
var tokenSource = _currentCancellationTokenSource;
if (tokenSource != null)
{
try
{
tokenSource.Cancel();
tokenSource.Dispose();
}
catch
{
}
_currentCancellationTokenSource = null;
}
}
}
//checks if an IP address is a private address space as defined by RFC 1918
public static bool IsPrivateAddressSpace(IPAddress address)
{
byte[] ba = address.GetAddressBytes();
switch ((int)ba[0])
{
case 10:
return true; //10.x.x.x
case 172:
return ((int)ba[1] & 16) != 0; //172.16-31.x.x
case 192:
return (int)ba[1] == 168; //192.168.x.x
default:
return false;
}
}
public static void Handle(IPAddress localAddress, byte[] response, IPEndPoint endpoint, NatProtocol protocol)
{
switch (protocol)
{
case NatProtocol.Upnp:
//UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
break;
//UpnpSearcher.Instance.Handle(localAddress, response, endpoint);
break;
case NatProtocol.Pmp:
PmpSearcher.Instance.Handle(localAddress, response, endpoint);
break;
default:
throw new ArgumentException("Unexpected protocol: " + protocol);
}
PmpSearcher.Instance.Handle(localAddress, response, endpoint);
break;
default:
throw new ArgumentException("Unexpected protocol: " + protocol);
}
}
public static void Handle(IPAddress localAddress, UpnpDeviceInfo deviceInfo, IPEndPoint endpoint, NatProtocol protocol)

View File

@ -1,3 +1,3 @@
using System.Reflection;
[assembly: AssemblyVersion("3.2.20.11")]
[assembly: AssemblyVersion("3.2.20.12")]