Merge pull request #1497 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-02-25 01:21:40 -05:00
commit f55d6ded74
17 changed files with 445 additions and 729 deletions

View file

@ -80,7 +80,6 @@
<Compile Include="FilterService.cs" />
<Compile Include="IHasDtoOptions.cs" />
<Compile Include="Library\ChapterService.cs" />
<Compile Include="PinLoginService.cs" />
<Compile Include="Playback\Dash\ManifestBuilder.cs" />
<Compile Include="Playback\Dash\MpegDashService.cs" />
<Compile Include="Playback\MediaInfoService.cs" />

View file

@ -1,243 +0,0 @@
using System;
using System.Collections.Concurrent;
using System.Globalization;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Connect;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Session;
using ServiceStack;
namespace MediaBrowser.Api
{
[Route("/Auth/Pin", "POST", Summary = "Creates a pin request")]
public class CreatePinRequest : IReturn<PinCreationResult>
{
[ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string DeviceId { get; set; }
[ApiMember(Name = "AppName", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string AppName { get; set; }
}
[Route("/Auth/Pin", "GET", Summary = "Gets pin status")]
public class GetPinStatusRequest : IReturn<PinStatusResult>
{
[ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string DeviceId { get; set; }
[ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string Pin { get; set; }
}
[Route("/Auth/Pin/Exchange", "POST", Summary = "Exchanges a pin")]
public class ExchangePinRequest : IReturn<PinExchangeResult>
{
[ApiMember(Name = "DeviceId", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string DeviceId { get; set; }
[ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string Pin { get; set; }
}
[Route("/Auth/Pin/Validate", "POST", Summary = "Validates a pin")]
[Authenticated]
public class ValidatePinRequest : IReturn<SessionInfoDto>
{
[ApiMember(Name = "Pin", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string Pin { get; set; }
}
public class PinLoginService : BaseApiService
{
private static readonly ConcurrentDictionary<string, MyPinStatus> _activeRequests = new ConcurrentDictionary<string, MyPinStatus>(StringComparer.OrdinalIgnoreCase);
private readonly ISessionManager _sessionManager;
private readonly IUserManager _userManager;
public PinLoginService(ISessionManager sessionManager, IUserManager userManager)
{
_sessionManager = sessionManager;
_userManager = userManager;
}
public object Post(CreatePinRequest request)
{
if (string.IsNullOrWhiteSpace(request.DeviceId))
{
throw new ArgumentNullException("DeviceId");
}
if (string.IsNullOrWhiteSpace(request.AppName))
{
throw new ArgumentNullException("AppName");
}
var pin = GetNewPin();
var value = new MyPinStatus
{
CreationTimeUtc = DateTime.UtcNow,
IsConfirmed = false,
IsExpired = false,
Pin = pin,
DeviceId = request.DeviceId,
AppName = request.AppName
};
_activeRequests.AddOrUpdate(pin, value, (k, v) => value);
return ToOptimizedResult(new PinCreationResult
{
DeviceId = request.DeviceId,
IsConfirmed = false,
IsExpired = false,
Pin = pin
});
}
public object Get(GetPinStatusRequest request)
{
MyPinStatus status;
if (!_activeRequests.TryGetValue(request.Pin, out status))
{
Logger.Debug("Pin {0} not found.", request.Pin);
throw new ResourceNotFoundException();
}
EnsureValid(request.DeviceId, status);
return ToOptimizedResult(new PinStatusResult
{
Pin = status.Pin,
IsConfirmed = status.IsConfirmed,
IsExpired = status.IsExpired
});
}
public async Task<object> Post(ExchangePinRequest request)
{
MyPinStatus status;
if (!_activeRequests.TryGetValue(request.Pin, out status))
{
Logger.Debug("Pin {0} not found.", request.Pin);
throw new ResourceNotFoundException();
}
EnsureValid(request.DeviceId, status);
if (!status.IsConfirmed)
{
throw new ResourceNotFoundException();
}
var auth = AuthorizationContext.GetAuthorizationInfo(Request);
var user = _userManager.GetUserById(status.UserId);
var result = await _sessionManager.CreateNewSession(new AuthenticationRequest
{
App = auth.Client,
AppVersion = auth.Version,
DeviceId = auth.DeviceId,
DeviceName = auth.Device,
RemoteEndPoint = Request.RemoteIp,
Username = user.Name
}).ConfigureAwait(false);
return ToOptimizedResult(result);
}
public object Post(ValidatePinRequest request)
{
MyPinStatus status;
if (!_activeRequests.TryGetValue(request.Pin, out status))
{
throw new ResourceNotFoundException();
}
EnsureValid(status);
status.IsConfirmed = true;
status.UserId = AuthorizationContext.GetAuthorizationInfo(Request).UserId;
return ToOptimizedResult(new ValidatePinResult
{
AppName = status.AppName
});
}
private void EnsureValid(string requestedDeviceId, MyPinStatus status)
{
if (!string.Equals(requestedDeviceId, status.DeviceId, StringComparison.OrdinalIgnoreCase))
{
Logger.Debug("Pin device Id's do not match. requestedDeviceId: {0}, status.DeviceId: {1}", requestedDeviceId, status.DeviceId);
throw new ResourceNotFoundException();
}
EnsureValid(status);
}
private void EnsureValid(MyPinStatus status)
{
if ((DateTime.UtcNow - status.CreationTimeUtc).TotalMinutes > 10)
{
status.IsExpired = true;
}
if (status.IsExpired)
{
Logger.Debug("Pin {0} is expired", status.Pin);
throw new ResourceNotFoundException();
}
}
private string GetNewPin()
{
var pin = GetNewPinInternal();
while (IsPinActive(pin))
{
pin = GetNewPinInternal();
}
return pin;
}
private string GetNewPinInternal()
{
return new Random().Next(10000, 99999).ToString(CultureInfo.InvariantCulture);
}
private bool IsPinActive(string pin)
{
MyPinStatus status;
if (!_activeRequests.TryGetValue(pin, out status))
{
return false;
}
if (status.IsExpired)
{
return false;
}
return true;
}
public class MyPinStatus : PinStatusResult
{
public DateTime CreationTimeUtc { get; set; }
public string DeviceId { get; set; }
public string UserId { get; set; }
public string AppName { get; set; }
}
}
public class ValidatePinResult
{
public string AppName { get; set; }
}
}

View file

@ -32,5 +32,12 @@ namespace MediaBrowser.Controller.Library
/// </summary>
/// <param name="path">The path.</param>
void ReportFileSystemChanged(string path);
/// <summary>
/// Determines whether [is path locked] [the specified path].
/// </summary>
/// <param name="path">The path.</param>
/// <returns><c>true</c> if [is path locked] [the specified path]; otherwise, <c>false</c>.</returns>
bool IsPathLocked(string path);
}
}

View file

@ -25,6 +25,12 @@ namespace MediaBrowser.Controller.LiveTv
/// <value>The id of the channel.</value>
public string Id { get; set; }
/// <summary>
/// Gets or sets the tuner host identifier.
/// </summary>
/// <value>The tuner host identifier.</value>
public string TunerHostId { get; set; }
/// <summary>
/// Gets or sets the type of the channel.
/// </summary>

View file

@ -7,7 +7,10 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using CommonIO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.MediaInfo;
@ -81,12 +84,29 @@ namespace MediaBrowser.MediaEncoding.Probing
}
FetchGenres(info, tags);
var overview = FFProbeHelpers.GetDictionaryValue(tags, "description");
var shortOverview = FFProbeHelpers.GetDictionaryValue(tags, "description");
var overview = FFProbeHelpers.GetDictionaryValue(tags, "synopsis");
if (string.IsNullOrWhiteSpace(overview))
{
overview = shortOverview;
shortOverview = null;
}
if (string.IsNullOrWhiteSpace(overview))
{
overview = FFProbeHelpers.GetDictionaryValue(tags, "desc");
}
if (!string.IsNullOrWhiteSpace(overview))
{
info.Overview = overview;
}
if (!string.IsNullOrWhiteSpace(shortOverview))
{
info.ShortOverview = shortOverview;
}
var title = FFProbeHelpers.GetDictionaryValue(tags, "title");
if (!string.IsNullOrWhiteSpace(title))
{
@ -105,13 +125,15 @@ namespace MediaBrowser.MediaEncoding.Probing
{
SetAudioRuntimeTicks(data, info);
// tags are normally located under data.format, but we've seen some cases with ogg where they're part of the audio stream
// tags are normally located under data.format, but we've seen some cases with ogg where they're part of the info stream
// so let's create a combined list of both
SetAudioInfoFromTags(info, tags);
}
else
{
FetchStudios(info, tags, "copyright");
var iTunEXTC = FFProbeHelpers.GetDictionaryValue(tags, "iTunEXTC");
if (!string.IsNullOrWhiteSpace(iTunEXTC))
{
@ -124,13 +146,13 @@ namespace MediaBrowser.MediaEncoding.Probing
info.OfficialRatingDescription = parts[3];
}
}
var itunesXml = FFProbeHelpers.GetDictionaryValue(tags, "iTunMOVI");
if (!string.IsNullOrWhiteSpace(itunesXml))
{
FetchFromItunesInfo(itunesXml, info);
}
if (data.format != null && !string.IsNullOrEmpty(data.format.duration))
{
info.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, _usCulture)).Ticks;
@ -151,13 +173,221 @@ namespace MediaBrowser.MediaEncoding.Probing
private void FetchFromItunesInfo(string xml, MediaInfo info)
{
// Make things simpler and strip out the dtd
xml = xml.Substring(xml.IndexOf("<plist", StringComparison.OrdinalIgnoreCase));
xml = "<?xml version=\"1.0\"?>" + xml;
// <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>cast</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Blender Foundation</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Janus Bager Kristensen</string>\n\t\t</dict>\n\t</array>\n\t<key>directors</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>name</key>\n\t\t\t<string>Sacha Goedegebure</string>\n\t\t</dict>\n\t</array>\n\t<key>studio</key>\n\t<string>Blender Foundation</string>\n</dict>\n</plist>\n
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
using (var streamReader = new StreamReader(stream))
{
// Use XmlReader for best performance
using (var reader = XmlReader.Create(streamReader))
{
reader.MoveToContent();
// Loop through each element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "dict":
using (var subtree = reader.ReadSubtree())
{
ReadFromDictNode(subtree, info);
}
break;
default:
reader.Skip();
break;
}
}
}
}
}
}
}
private void ReadFromDictNode(XmlReader reader, MediaInfo info)
{
reader.MoveToContent();
string currentKey = null;
List<NameValuePair> pairs = new List<NameValuePair>();
// Loop through each element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "key":
if (!string.IsNullOrWhiteSpace(currentKey))
{
ProcessPairs(currentKey, pairs, info);
}
currentKey = reader.ReadElementContentAsString();
pairs = new List<NameValuePair>();
break;
case "string":
var value = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(value))
{
pairs.Add(new NameValuePair
{
Name = value,
Value = value
});
}
break;
case "array":
if (!string.IsNullOrWhiteSpace(currentKey))
{
using (var subtree = reader.ReadSubtree())
{
pairs.AddRange(ReadValueArray(subtree));
}
}
break;
default:
reader.Skip();
break;
}
}
}
}
private List<NameValuePair> ReadValueArray(XmlReader reader)
{
reader.MoveToContent();
List<NameValuePair> pairs = new List<NameValuePair>();
// Loop through each element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "dict":
using (var subtree = reader.ReadSubtree())
{
var dict = GetNameValuePair(subtree);
if (dict != null)
{
pairs.Add(dict);
}
}
break;
default:
reader.Skip();
break;
}
}
}
return pairs;
}
private void ProcessPairs(string key, List<NameValuePair> pairs, MediaInfo info)
{
if (string.Equals(key, "studio", StringComparison.OrdinalIgnoreCase))
{
foreach (var pair in pairs)
{
info.Studios.Add(pair.Value);
}
info.Studios = info.Studios
.Where(i => !string.IsNullOrWhiteSpace(i))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();
}
else if (string.Equals(key, "screenwriters", StringComparison.OrdinalIgnoreCase))
{
foreach (var pair in pairs)
{
info.People.Add(new BaseItemPerson
{
Name = pair.Value,
Type = PersonType.Writer
});
}
}
else if (string.Equals(key, "producers", StringComparison.OrdinalIgnoreCase))
{
foreach (var pair in pairs)
{
info.People.Add(new BaseItemPerson
{
Name = pair.Value,
Type = PersonType.Producer
});
}
}
else if (string.Equals(key, "directors", StringComparison.OrdinalIgnoreCase))
{
foreach (var pair in pairs)
{
info.People.Add(new BaseItemPerson
{
Name = pair.Value,
Type = PersonType.Director
});
}
}
}
private NameValuePair GetNameValuePair(XmlReader reader)
{
reader.MoveToContent();
string name = null;
string value = null;
// Loop through each element
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
switch (reader.Name)
{
case "key":
name = reader.ReadElementContentAsString();
break;
case "string":
value = reader.ReadElementContentAsString();
break;
default:
reader.Skip();
break;
}
}
}
if (string.IsNullOrWhiteSpace(name) ||
string.IsNullOrWhiteSpace(value))
{
return null;
}
return new NameValuePair
{
Name = name,
Value = value
};
}
/// <summary>
/// Converts ffprobe stream info to our MediaStream class
/// </summary>
/// <param name="isAudio">if set to <c>true</c> [is audio].</param>
/// <param name="isAudio">if set to <c>true</c> [is info].</param>
/// <param name="streamInfo">The stream info.</param>
/// <param name="formatInfo">The format info.</param>
/// <returns>MediaStream.</returns>
@ -434,11 +664,11 @@ namespace MediaBrowser.MediaEncoding.Probing
return null;
}
private void SetAudioRuntimeTicks(InternalMediaInfoResult result, Model.MediaInfo.MediaInfo data)
private void SetAudioRuntimeTicks(InternalMediaInfoResult result, MediaInfo data)
{
if (result.streams != null)
{
// Get the first audio stream
// Get the first info stream
var stream = result.streams.FirstOrDefault(s => string.Equals(s.codec_type, "audio", StringComparison.OrdinalIgnoreCase));
if (stream != null)
@ -703,10 +933,10 @@ namespace MediaBrowser.MediaEncoding.Probing
/// <summary>
/// Gets the studios from the tags collection
/// </summary>
/// <param name="audio">The audio.</param>
/// <param name="info">The info.</param>
/// <param name="tags">The tags.</param>
/// <param name="tagName">Name of the tag.</param>
private void FetchStudios(Model.MediaInfo.MediaInfo audio, Dictionary<string, string> tags, string tagName)
private void FetchStudios(MediaInfo info, Dictionary<string, string> tags, string tagName)
{
var val = FFProbeHelpers.GetDictionaryValue(tags, tagName);
@ -717,19 +947,19 @@ namespace MediaBrowser.MediaEncoding.Probing
foreach (var studio in studios)
{
// Sometimes the artist name is listed here, account for that
if (audio.Artists.Contains(studio, StringComparer.OrdinalIgnoreCase))
if (info.Artists.Contains(studio, StringComparer.OrdinalIgnoreCase))
{
continue;
}
if (audio.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase))
if (info.AlbumArtists.Contains(studio, StringComparer.OrdinalIgnoreCase))
{
continue;
}
audio.Studios.Add(studio);
info.Studios.Add(studio);
}
audio.Studios = audio.Studios
info.Studios = info.Studios
.Where(i => !string.IsNullOrWhiteSpace(i))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToList();

View file

@ -15,7 +15,7 @@ namespace MediaBrowser.Model.LiveTv
public int PrePaddingSeconds { get; set; }
public int PostPaddingSeconds { get; set; }
public LiveTvOptions()
{
EnableMovieProviders = true;
@ -31,7 +31,6 @@ namespace MediaBrowser.Model.LiveTv
public string Type { get; set; }
public bool ImportFavoritesOnly { get; set; }
public bool IsEnabled { get; set; }
public string GuideGroup { get; set; }
public TunerHostInfo()
{
@ -49,6 +48,14 @@ namespace MediaBrowser.Model.LiveTv
public string ZipCode { get; set; }
public string Country { get; set; }
public string Path { get; set; }
public string GuideGroup { get; set; }
public string[] EnabledTuners { get; set; }
public bool EnableAllTuners { get; set; }
public ListingsProviderInfo()
{
EnabledTuners = new string[] { };
EnableAllTuners = true;
}
}
}

View file

@ -51,6 +51,11 @@ namespace MediaBrowser.Model.MediaInfo
/// </summary>
/// <value>The overview.</value>
public string Overview { get; set; }
/// <summary>
/// Gets or sets the short overview.
/// </summary>
/// <value>The short overview.</value>
public string ShortOverview { get; set; }
public MediaInfo()
{

View file

@ -463,6 +463,11 @@ namespace MediaBrowser.Providers.MediaInfo
video.Overview = data.Overview;
}
}
if (string.IsNullOrWhiteSpace(video.ShortOverview) || isFullRefresh)
{
video.ShortOverview = data.ShortOverview;
}
}
private async Task FetchPeople(Video video, Model.MediaInfo.MediaInfo data, MetadataRefreshOptions options)

View file

@ -64,6 +64,13 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
FileSize = new FileInfo(path).Length
};
if (_libraryMonitor.IsPathLocked(path))
{
result.Status = FileSortingStatus.Failure;
result.StatusMessage = "Path is locked by other processes. Please try again later.";
return result;
}
var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
var resolver = new Naming.TV.EpisodeResolver(namingOptions, new PatternsLogger());

View file

@ -78,6 +78,12 @@ namespace MediaBrowser.Server.Implementations.IO
TemporarilyIgnore(path);
}
public bool IsPathLocked(string path)
{
var lockedPaths = _tempIgnoredPaths.Keys.ToList();
return lockedPaths.Any(i => string.Equals(i, path, StringComparison.OrdinalIgnoreCase) || _fileSystem.ContainsSubPath(i, path));
}
public async void ReportFileSystemChangeComplete(string path, bool refreshPath)
{
if (string.IsNullOrEmpty(path))

View file

@ -210,9 +210,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
if (list.Count > 0)
foreach (var provider in GetListingProviders())
{
foreach (var provider in GetListingProviders())
var enabledChannels = list
.Where(i => IsListingProviderEnabledForTuner(provider.Item2, i.TunerHostId))
.ToList();
if (enabledChannels.Count > 0)
{
try
{
@ -228,6 +232,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
}
_channelCache = list;
return list;
}
@ -489,6 +494,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
}
}
private bool IsListingProviderEnabledForTuner(ListingsProviderInfo info, string tunerHostId)
{
return info.EnableAllTuners || info.EnabledTuners.Contains(tunerHostId ?? string.Empty, StringComparer.OrdinalIgnoreCase);
}
private async Task<IEnumerable<ProgramInfo>> GetProgramsAsyncInternal(string channelId, DateTime startDateUtc, DateTime endDateUtc, CancellationToken cancellationToken)
{
var channels = await GetChannelsAsync(true, cancellationToken).ConfigureAwait(false);
@ -496,6 +506,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
foreach (var provider in GetListingProviders())
{
if (!IsListingProviderEnabledForTuner(provider.Item2, channel.TunerHostId))
{
continue;
}
var programs = await provider.Item1.GetProgramsAsync(provider.Item2, channel.Number, channel.Name, startDateUtc, endDateUtc, cancellationToken)
.ConfigureAwait(false);

View file

@ -14,6 +14,7 @@ using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Dlna;
@ -64,8 +65,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
Name = i.GuideName,
Number = i.GuideNumber.ToString(CultureInfo.InvariantCulture),
Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture),
IsFavorite = i.Favorite
Id = ChannelIdPrefix + i.GuideNumber.ToString(CultureInfo.InvariantCulture) + '_' + (i.GuideName ?? string.Empty).GetMD5().ToString("N"),
IsFavorite = i.Favorite,
TunerHostId = info.Id
});
@ -347,6 +349,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
return Config.GetConfiguration<EncodingOptions>("encoding");
}
private string GetHdHrIdFromChannelId(string channelId)
{
return channelId.Split('_')[1];
}
protected override async Task<List<MediaSourceInfo>> GetChannelStreamMediaSources(TunerHostInfo info, string channelId, CancellationToken cancellationToken)
{
var list = new List<MediaSourceInfo>();
@ -355,9 +362,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
return list;
}
channelId = channelId.Substring(ChannelIdPrefix.Length);
var hdhrId = GetHdHrIdFromChannelId(channelId);
list.Add(GetMediaSource(info, channelId, "native"));
list.Add(GetMediaSource(info, hdhrId, "native"));
try
{
@ -366,12 +373,12 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
if (model.IndexOf("hdtc", StringComparison.OrdinalIgnoreCase) != -1)
{
list.Insert(0, GetMediaSource(info, channelId, "heavy"));
list.Insert(0, GetMediaSource(info, hdhrId, "heavy"));
list.Add(GetMediaSource(info, channelId, "internet480"));
list.Add(GetMediaSource(info, channelId, "internet360"));
list.Add(GetMediaSource(info, channelId, "internet240"));
list.Add(GetMediaSource(info, channelId, "mobile"));
list.Add(GetMediaSource(info, hdhrId, "internet480"));
list.Add(GetMediaSource(info, hdhrId, "internet360"));
list.Add(GetMediaSource(info, hdhrId, "internet240"));
list.Add(GetMediaSource(info, hdhrId, "mobile"));
}
}
catch (Exception ex)
@ -400,9 +407,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
throw new ArgumentException("Channel not found");
}
channelId = channelId.Substring(ChannelIdPrefix.Length);
var hdhrId = GetHdHrIdFromChannelId(channelId);
return GetMediaSource(info, channelId, streamId);
return GetMediaSource(info, hdhrId, streamId);
}
public async Task Validate(TunerHostInfo info)

View file

@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
protected override async Task<IEnumerable<ChannelInfo>> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
{
return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, cancellationToken).ConfigureAwait(false);
return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false);
}
public Task<List<LiveTvTunerInfo>> GetTunerInfos(CancellationToken cancellationToken)

View file

@ -25,14 +25,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
_httpClient = httpClient;
}
public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, CancellationToken cancellationToken)
public async Task<List<M3UChannel>> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken)
{
var urlHash = url.GetMD5().ToString("N");
// Read the file and display it line by line.
using (var reader = new StreamReader(await GetListingsStream(url, cancellationToken).ConfigureAwait(false)))
{
return GetChannels(reader, urlHash, channelIdPrefix);
return GetChannels(reader, urlHash, channelIdPrefix, tunerHostId);
}
}
@ -45,7 +45,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
return Task.FromResult(_fileSystem.OpenRead(url));
}
private List<M3UChannel> GetChannels(StreamReader reader, string urlHash, string channelIdPrefix)
private List<M3UChannel> GetChannels(StreamReader reader, string urlHash, string channelIdPrefix, string tunerHostId)
{
var channels = new List<M3UChannel>();
string line;
@ -69,8 +69,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
_logger.Info("Found m3u channel: {0}", extInf);
}
else if (!string.IsNullOrWhiteSpace(extInf))
{
var channel = GetChannelnfo(extInf);
{
var channel = GetChannelnfo(extInf, tunerHostId);
channel.Id = channelIdPrefix + urlHash + line.GetMD5().ToString("N");
channel.Path = line;
channels.Add(channel);
@ -79,10 +79,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
}
return channels;
}
public M3UChannel GetChannelnfo(string extInf)
private M3UChannel GetChannelnfo(string extInf, string tunerHostId)
{
var titleIndex = extInf.LastIndexOf(',');
var channel = new M3UChannel();
channel.TunerHostId = tunerHostId;
channel.Number = extInf.Trim().Split(' ')[0] ?? "0";
channel.Name = extInf.Substring(titleIndex + 1);
@ -108,7 +109,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
return channel;
}
public string FindProperty(string property, string properties, string defaultResult = "")
private string FindProperty(string property, string properties, string defaultResult = "")
{
var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase);
var matches = reg.Matches(properties);

View file

@ -37,7 +37,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
var satInfo = (SatIpTunerHostInfo) tuner;
return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(satInfo.M3UUrl, ChannelIdPrefix, cancellationToken).ConfigureAwait(false);
return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(satInfo.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false);
}
public static string DeviceType

View file

@ -476,6 +476,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\photos.html">
<Link>Resources\dashboard-ui\photos.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\pin.html">
<Link>Resources\dashboard-ui\pin.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\playbackconfiguration.html">
<Link>Resources\dashboard-ui\playbackconfiguration.html</Link>
</BundleResource>
@ -1316,6 +1319,18 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\visibleinviewport.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.css">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.css</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\actionsheet\actionsheet.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\confirm\confirm.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\confirm\confirm.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\confirm\nativeconfirm.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\confirm\nativeconfirm.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\emby-webcomponents\images\basicimagefetcher.js">
<Link>Resources\dashboard-ui\bower_components\emby-webcomponents\images\basicimagefetcher.js</Link>
</BundleResource>
@ -1877,6 +1892,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-demo-helpers\.gitignore">
<Link>Resources\dashboard-ui\bower_components\iron-demo-helpers\.gitignore</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-demo-helpers\.travis.yml">
<Link>Resources\dashboard-ui\bower_components\iron-demo-helpers\.travis.yml</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-demo-helpers\CONTRIBUTING.md">
<Link>Resources\dashboard-ui\bower_components\iron-demo-helpers\CONTRIBUTING.md</Link>
</BundleResource>
@ -2012,6 +2030,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\index.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\index.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout-classes.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout-classes.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\iron-flex-layout.html</Link>
</BundleResource>
@ -2021,12 +2042,18 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\classes\iron-shadow-flex-layout.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\classes\iron-shadow-flex-layout.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\demo\demo-snippet.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\demo\demo-snippet.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\demo\index.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\demo\index.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\test\index.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\test\index.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout-classes.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout-classes.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout.html">
<Link>Resources\dashboard-ui\bower_components\iron-flex-layout\test\iron-flex-layout.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-form-element-behavior\.bower.json">
<Link>Resources\dashboard-ui\bower_components\iron-form-element-behavior\.bower.json</Link>
</BundleResource>
@ -2495,6 +2522,12 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-resizable-behavior\.gitignore">
<Link>Resources\dashboard-ui\bower_components\iron-resizable-behavior\.gitignore</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-resizable-behavior\.travis.yml">
<Link>Resources\dashboard-ui\bower_components\iron-resizable-behavior\.travis.yml</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-resizable-behavior\CONTRIBUTING.md">
<Link>Resources\dashboard-ui\bower_components\iron-resizable-behavior\CONTRIBUTING.md</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\iron-resizable-behavior\README.md">
<Link>Resources\dashboard-ui\bower_components\iron-resizable-behavior\README.md</Link>
</BundleResource>
@ -2651,50 +2684,17 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.bower.json">
<Link>Resources\dashboard-ui\bower_components\jquery\.bower.json</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.editorconfig">
<Link>Resources\dashboard-ui\bower_components\jquery\.editorconfig</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.gitattributes">
<Link>Resources\dashboard-ui\bower_components\jquery\.gitattributes</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.gitignore">
<Link>Resources\dashboard-ui\bower_components\jquery\.gitignore</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.jscsrc">
<Link>Resources\dashboard-ui\bower_components\jquery\.jscsrc</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.jshintignore">
<Link>Resources\dashboard-ui\bower_components\jquery\.jshintignore</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.jshintrc">
<Link>Resources\dashboard-ui\bower_components\jquery\.jshintrc</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.mailmap">
<Link>Resources\dashboard-ui\bower_components\jquery\.mailmap</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.npmignore">
<Link>Resources\dashboard-ui\bower_components\jquery\.npmignore</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\.travis.yml">
<Link>Resources\dashboard-ui\bower_components\jquery\.travis.yml</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\AUTHORS.txt">
<Link>Resources\dashboard-ui\bower_components\jquery\AUTHORS.txt</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\CONTRIBUTING.md">
<Link>Resources\dashboard-ui\bower_components\jquery\CONTRIBUTING.md</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\Gruntfile.js">
<Link>Resources\dashboard-ui\bower_components\jquery\Gruntfile.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\LICENSE.txt">
<Link>Resources\dashboard-ui\bower_components\jquery\LICENSE.txt</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\README.md">
<Link>Resources\dashboard-ui\bower_components\jquery\README.md</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\package.json">
<Link>Resources\dashboard-ui\bower_components\jquery\package.json</Link>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\bower.json">
<Link>Resources\dashboard-ui\bower_components\jquery\bower.json</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.js">
<Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.js</Link>
@ -2705,44 +2705,14 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.min.map">
<Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.min.map</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\npo\npo.js">
<Link>Resources\dashboard-ui\bower_components\jquery\external\npo\npo.js</Link>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.slim.js">
<Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit\LICENSE.txt">
<Link>Resources\dashboard-ui\bower_components\jquery\external\qunit\LICENSE.txt</Link>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.js">
<Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit\MIT-LICENSE.txt">
<Link>Resources\dashboard-ui\bower_components\jquery\external\qunit\MIT-LICENSE.txt</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit\qunit.css">
<Link>Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.css</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit\qunit.js">
<Link>Resources\dashboard-ui\bower_components\jquery\external\qunit\qunit.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit-assert-step\MIT-LICENSE.txt">
<Link>Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\MIT-LICENSE.txt</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\qunit-assert-step\qunit-assert-step.js">
<Link>Resources\dashboard-ui\bower_components\jquery\external\qunit-assert-step\qunit-assert-step.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\requirejs\require.js">
<Link>Resources\dashboard-ui\bower_components\jquery\external\requirejs\require.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sinon\sinon-1.14.1.js">
<Link>Resources\dashboard-ui\bower_components\jquery\external\sinon\sinon-1.14.1.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sizzle\LICENSE.txt">
<Link>Resources\dashboard-ui\bower_components\jquery\external\sizzle\LICENSE.txt</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.js">
<Link>Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.js">
<Link>Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.map">
<Link>Resources\dashboard-ui\bower_components\jquery\external\sizzle\dist\sizzle.min.map</Link>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.map">
<Link>Resources\dashboard-ui\bower_components\jquery\dist\jquery.slim.min.map</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\.jshintrc">
<Link>Resources\dashboard-ui\bower_components\jquery\src\.jshintrc</Link>
@ -2810,6 +2780,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\serialize.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\serialize.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\support.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\support.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\traversing.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\traversing.js</Link>
</BundleResource>
@ -2849,6 +2822,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\attributes\val.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\attributes\val.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\core\DOMEval.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\core\DOMEval.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\core\access.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\core\access.js</Link>
</BundleResource>
@ -2888,12 +2864,24 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\data\Data.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\data\Data.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\data\accepts.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\data\accepts.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\data\support.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\data\support.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\deferred\exceptionHook.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\deferred\exceptionHook.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\effects\Tween.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\effects\Tween.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\effects\animatedSelector.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\effects\animatedSelector.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\effects\support.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\effects\support.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\event\ajax.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\event\ajax.js</Link>
</BundleResource>
@ -2921,6 +2909,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\manipulation\buildFragment.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\manipulation\buildFragment.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\manipulation\createSafeFragment.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\manipulation\createSafeFragment.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\manipulation\getAll.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\manipulation\getAll.js</Link>
</BundleResource>
@ -2939,366 +2930,6 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\src\traversing\findFilter.js">
<Link>Resources\dashboard-ui\bower_components\jquery\src\traversing\findFilter.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\.jshintrc">
<Link>Resources\dashboard-ui\bower_components\jquery\test\.jshintrc</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\delegatetest.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\delegatetest.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\hovertest.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\hovertest.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\index.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\index.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\jquery.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\jquery.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\localfile.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\localfile.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\networkerror.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\networkerror.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\promises_aplus_adapter.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\promises_aplus_adapter.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\readywait.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\readywait.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\xhtml.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\xhtml.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\1x1.jpg">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\1x1.jpg</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\atom+xml.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\atom+xml.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\badcall.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\badcall.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\badjson.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\badjson.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\cleanScript.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\cleanScript.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\dashboard.xml">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\dashboard.xml</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\echoData.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\echoData.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\echoQuery.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\echoQuery.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\errorWithJSON.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\errorWithJSON.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\errorWithText.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\errorWithText.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\etag.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\etag.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\headers.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\headers.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\if_modified_since.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\if_modified_since.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\iframe.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\iframe.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\jquery-1.9.1.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\jquery-1.9.1.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\json.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\json.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\json_obj.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\json_obj.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\jsonp.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\jsonp.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\name.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\name.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\name.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\name.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\nocontent.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\nocontent.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\params_html.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\params_html.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\readywaitasset.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\readywaitasset.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\readywaitloader.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\readywaitloader.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\script.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\script.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\statusText.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\statusText.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\test.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\test.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\test.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\test.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\test2.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\test2.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\test3.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\test3.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\testbar.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\testbar.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\testinit.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\testinit.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\testrunner.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\testrunner.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\testsuite.css">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\testsuite.css</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\text.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\text.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\with_fries.xml">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\with_fries.xml</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\with_fries_over_jsonp.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\with_fries_over_jsonp.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\content-type.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\content-type.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\evalScript.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\evalScript.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\method.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\method.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\onunload.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\onunload.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\ajax\unreleasedXHR.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\ajax\unreleasedXHR.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\aliased.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\aliased.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\cc_on.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\cc_on.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\dont_return.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\dont_return.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\dynamic_ready.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\dynamic_ready.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\core\onready.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\core\onready.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\css\cssWidthBeforeDocReady.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\css\cssWidthBeforeDocReady.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\data\dataAttrs.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\data\dataAttrs.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\dimensions\documentLarge.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\dimensions\documentLarge.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\focusElem.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\focusElem.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\focusinCrossFrame.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\focusinCrossFrame.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\interactiveReady.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\interactiveReady.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\longLoadScript.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\longLoadScript.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\onbeforeunload.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\onbeforeunload.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\promiseReady.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\promiseReady.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\syncReady.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\syncReady.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\event\triggerunload.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\event\triggerunload.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\manipulation\iframe-denied.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\manipulation\iframe-denied.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\absolute.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\absolute.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\body.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\body.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\fixed.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\fixed.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\relative.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\relative.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\scroll.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\scroll.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\static.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\static.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\offset\table.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\offset\table.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\selector\html5_selector.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\selector\html5_selector.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\selector\sizzle_cache.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\selector\sizzle_cache.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\bodyBackground.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\bodyBackground.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\csp-clean.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-clean.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\csp-log.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\csp-log.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\csp.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\csp.php">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\csp.php</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\data\support\getComputedSupport.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\data\support\getComputedSupport.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\gh-1764-fullscreen.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\integration\gh-1764-fullscreen.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\gh-2343-ie-radio-click.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\integration\gh-2343-ie-radio-click.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.css">
<Link>Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.css</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.html">
<Link>Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen-iframe.html</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\integration\data\gh-1764-fullscreen.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\.jshintrc">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\.jshintrc</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_missing.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_missing.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_passed.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_passed.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_present_originally.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\document_present_originally.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_native_symbol.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_native_symbol.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_symbol_polyfill.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\iterable_with_symbol_polyfill.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_global_not_created.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_global_not_created.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_iterability_es6.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_iterability_es6.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_jquery.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\node_smoke_tests\lib\ensure_jquery.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\ajax.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\ajax.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\attributes.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\attributes.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\basic.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\basic.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\callbacks.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\callbacks.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\core.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\core.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\css.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\css.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\data.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\data.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\deferred.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\deferred.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\deprecated.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\deprecated.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\dimensions.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\dimensions.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\effects.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\effects.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\event.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\event.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\exports.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\exports.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\manipulation.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\manipulation.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\offset.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\offset.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\queue.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\queue.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\ready.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\ready.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\selector.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\selector.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\serialize.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\serialize.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\support.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\support.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\traversing.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\traversing.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jquery\test\unit\wrap.js">
<Link>Resources\dashboard-ui\bower_components\jquery\test\unit\wrap.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\bower_components\jstree\.bower.json">
<Link>Resources\dashboard-ui\bower_components\jstree\.bower.json</Link>
</BundleResource>
@ -8774,21 +8405,21 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\devices\ios\ios.css">
<Link>Resources\dashboard-ui\devices\ios\ios.css</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\devices\windowsphone\wp.css">
<Link>Resources\dashboard-ui\devices\windowsphone\wp.css</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\files\dummy.mp4">
<Link>Resources\dashboard-ui\files\dummy.mp4</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\legacy\buttonenabled.js">
<Link>Resources\dashboard-ui\legacy\buttonenabled.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\legacy\deferred.js">
<Link>Resources\dashboard-ui\legacy\deferred.js</Link>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\legacy\dashboard.js">
<Link>Resources\dashboard-ui\legacy\dashboard.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\aboutpage.js">
<Link>Resources\dashboard-ui\scripts\aboutpage.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\actionsheet.js">
<Link>Resources\dashboard-ui\scripts\actionsheet.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\addpluginpage.js">
<Link>Resources\dashboard-ui\scripts\addpluginpage.js</Link>
</BundleResource>
@ -9116,6 +8747,9 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\photos.js">
<Link>Resources\dashboard-ui\scripts\photos.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\pin.js">
<Link>Resources\dashboard-ui\scripts\pin.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\scripts\playbackconfiguration.js">
<Link>Resources\dashboard-ui\scripts\playbackconfiguration.js</Link>
</BundleResource>
@ -9929,8 +9563,11 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\thirdparty\social-share-kit-1.0.4\dist\js\social-share-kit.min.js">
<Link>Resources\dashboard-ui\thirdparty\social-share-kit-1.0.4\dist\js\social-share-kit.min.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\textprocessor-en-us.js">
<Link>Resources\dashboard-ui\voice\textprocessor-en-us.js</Link>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\Readme.md">
<Link>Resources\dashboard-ui\voice\Readme.md</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\grammarprocessor.js">
<Link>Resources\dashboard-ui\voice\grammarprocessor.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\voice.css">
<Link>Resources\dashboard-ui\voice\voice.css</Link>
@ -9938,5 +9575,38 @@
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\voice.js">
<Link>Resources\dashboard-ui\voice\voice.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\voicecommands.js">
<Link>Resources\dashboard-ui\voice\voicecommands.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\voicedialog.js">
<Link>Resources\dashboard-ui\voice\voicedialog.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\controlcommands.js">
<Link>Resources\dashboard-ui\voice\commands\controlcommands.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\disablecommands.js">
<Link>Resources\dashboard-ui\voice\commands\disablecommands.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\enablecommands.js">
<Link>Resources\dashboard-ui\voice\commands\enablecommands.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\playcommands.js">
<Link>Resources\dashboard-ui\voice\commands\playcommands.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\searchcommands.js">
<Link>Resources\dashboard-ui\voice\commands\searchcommands.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\showcommands.js">
<Link>Resources\dashboard-ui\voice\commands\showcommands.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\commands\togglecommands.js">
<Link>Resources\dashboard-ui\voice\commands\togglecommands.js</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\grammar\en-US.json">
<Link>Resources\dashboard-ui\voice\grammar\en-US.json</Link>
</BundleResource>
<BundleResource Include="..\MediaBrowser.WebDashboard\dashboard-ui\voice\grammar\grammar.json">
<Link>Resources\dashboard-ui\voice\grammar\grammar.json</Link>
</BundleResource>
</ItemGroup>
</Project>

View file

@ -278,9 +278,6 @@
<Content Include="dashboard-ui\mysyncsettings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\pin.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\robots.txt">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -320,9 +317,6 @@
<Content Include="dashboard-ui\scripts\autoorganizesmart.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\pin.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\searchmenu.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>